From 481d9d3032d7e65847977730d08cb3b6424d5306 Mon Sep 17 00:00:00 2001 From: 4sval Date: Sat, 14 Jan 2023 00:37:51 +0100 Subject: [PATCH] more world lights --- CUE4Parse | 2 +- FModel/Resources/default.vert | 13 +++--- FModel/Views/Snooper/Lights/Light.cs | 16 +++++++ FModel/Views/Snooper/Lights/PointLight.cs | 12 ++++- FModel/Views/Snooper/Lights/SpotLight.cs | 12 ++++- .../Snooper/Models/Animations/Animation.cs | 45 +++++++++---------- .../Snooper/Models/Animations/Skeleton.cs | 14 +++--- FModel/Views/Snooper/Models/Model.cs | 1 + FModel/Views/Snooper/Renderer.cs | 22 ++++++--- FModel/Views/Snooper/SnimGui.cs | 16 ++++--- FModel/Views/Snooper/Transform.cs | 2 + 11 files changed, 106 insertions(+), 49 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index d5a1610b..b02fb8c6 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit d5a1610bbd3ec0a43579fe6151539bc11f673505 +Subproject commit b02fb8c67e3ab7b1c256297a4363dedc6aca951a diff --git a/FModel/Resources/default.vert b/FModel/Resources/default.vert index c120b5a9..6148892c 100644 --- a/FModel/Resources/default.vert +++ b/FModel/Resources/default.vert @@ -1,4 +1,4 @@ -#version 460 core +#version 460 core layout (location = 1) in vec3 vPos; layout (location = 2) in vec3 vNormal; @@ -12,8 +12,8 @@ layout (location = 9) in mat4 vInstanceMatrix; layout (location = 13) in vec3 vMorphTargetPos; layout (location = 14) in vec3 vMorphTargetTangent; -//const int MAX_BONES = 0; -//const int MAX_BONE_INFLUENCE = 0; +//const int MAX_BONES = 140; +//const int MAX_BONE_INFLUENCE = 4; uniform mat4 uView; uniform mat4 uProjection; @@ -33,13 +33,14 @@ void main() vec3 tangent = mix(vTangent, vMorphTargetTangent, uMorphTime); // for(int i = 0 ; i < MAX_BONE_INFLUENCE; i++) // { -// if(vBoneIds[i] == -1) continue; -// if(vBoneIds[i] >= MAX_BONES) +// int boneIndex = int(vBoneIds[i]); +// if(boneIndex == -1) continue; +// if(boneIndex >= MAX_BONES) // { // break; // } // -// vec4 localPos = uFinalBonesMatrix[int(vBoneIds[i])] * pos; +// vec4 localPos = uFinalBonesMatrix[boneIndex] * pos; // pos += localPos * vBoneWeights[i]; // } diff --git a/FModel/Views/Snooper/Lights/Light.cs b/FModel/Views/Snooper/Lights/Light.cs index b87f59ea..49e23b49 100644 --- a/FModel/Views/Snooper/Lights/Light.cs +++ b/FModel/Views/Snooper/Lights/Light.cs @@ -36,6 +36,22 @@ public abstract class Light : IDisposable public float Intensity; public bool IsSetup; + public Light(Texture icon, UObject light) + { + Transform = new Transform + { + Position = light.GetOrDefault("RelativeLocation", FVector.ZeroVector) * Constants.SCALE_DOWN_RATIO, + Rotation = light.GetOrDefault("RelativeRotation", FRotator.ZeroRotator).Quaternion(), + Scale = light.GetOrDefault("RelativeScale3D", FVector.OneVector) + }; + + Model = Guid.NewGuid(); + Icon = icon; + + Color = light.GetOrDefault("LightColor", new FColor(0xFF, 0xFF, 0xFF, 0xFF)); + Intensity = light.GetOrDefault("Intensity", 1.0f); + } + public Light(FGuid model, Texture icon, UObject parent, UObject light, Transform transform) { Transform = new Transform diff --git a/FModel/Views/Snooper/Lights/PointLight.cs b/FModel/Views/Snooper/Lights/PointLight.cs index 14019b24..ef916834 100644 --- a/FModel/Views/Snooper/Lights/PointLight.cs +++ b/FModel/Views/Snooper/Lights/PointLight.cs @@ -12,9 +12,19 @@ public class PointLight : Light public float Linear; public float Quadratic; + public PointLight(Texture icon, UObject point) : base(icon, point) + { + if (!point.TryGetValue(out float radius, "SourceRadius", "AttenuationRadius")) + radius = 1.0f; + + radius *= Constants.SCALE_DOWN_RATIO; + Linear = 4.5f / radius; + Quadratic = 75.0f / MathF.Pow(radius, 2.0f); + } + public PointLight(FGuid model, Texture icon, UObject parent, UObject point, Transform transform) : base(model, icon, parent, point, transform) { - if (!point.TryGetValue(out float radius, "AttenuationRadius", "SourceRadius")) + if (!point.TryGetValue(out float radius, "SourceRadius", "AttenuationRadius")) radius = 1.0f; radius *= Constants.SCALE_DOWN_RATIO; diff --git a/FModel/Views/Snooper/Lights/SpotLight.cs b/FModel/Views/Snooper/Lights/SpotLight.cs index 6c867922..1f7e9468 100644 --- a/FModel/Views/Snooper/Lights/SpotLight.cs +++ b/FModel/Views/Snooper/Lights/SpotLight.cs @@ -12,9 +12,19 @@ public class SpotLight : Light public float InnerConeAngle; public float OuterConeAngle; + public SpotLight(Texture icon, UObject spot) : base(icon, spot) + { + if (!spot.TryGetValue(out Attenuation, "SourceRadius", "AttenuationRadius")) + Attenuation = 1.0f; + + Attenuation *= Constants.SCALE_DOWN_RATIO; + InnerConeAngle = spot.GetOrDefault("InnerConeAngle", 50.0f); + OuterConeAngle = spot.GetOrDefault("OuterConeAngle", 60.0f); + } + public SpotLight(FGuid model, Texture icon, UObject parent, UObject spot, Transform transform) : base(model, icon, parent, spot, transform) { - if (!spot.TryGetValue(out Attenuation, "AttenuationRadius", "SourceRadius")) + if (!spot.TryGetValue(out Attenuation, "SourceRadius", "AttenuationRadius")) Attenuation = 1.0f; Attenuation *= Constants.SCALE_DOWN_RATIO; diff --git a/FModel/Views/Snooper/Models/Animations/Animation.cs b/FModel/Views/Snooper/Models/Animations/Animation.cs index 69391705..51893414 100644 --- a/FModel/Views/Snooper/Models/Animations/Animation.cs +++ b/FModel/Views/Snooper/Models/Animations/Animation.cs @@ -2,57 +2,54 @@ using System.Collections.Generic; using System.Numerics; using CUE4Parse_Conversion.Animations; +using CUE4Parse.UE4.Assets.Exports.Animation; using CUE4Parse.UE4.Objects.Core.Math; namespace FModel.Views.Snooper.Models.Animations; public class Animation : IDisposable { - public float CurrentTime; + public int CurrentTime; public float DeltaTime; public CAnimSet CurrentAnimation; - public Transform[] FinalBonesMatrix; - public Animation(CAnimSet anim, Dictionary nameToIndex, Dictionary indexToTransform) + public Animation(CAnimSet anim) { - CurrentTime = 0f; + CurrentTime = 0; CurrentAnimation = anim; - - FinalBonesMatrix = new Transform[anim.TrackBoneNames.Length]; - for (int i = 0; i < FinalBonesMatrix.Length; i++) - { - if (!nameToIndex.TryGetValue(anim.TrackBoneNames[i].Text, out var boneIndex) || - !indexToTransform.TryGetValue(boneIndex, out var boneTransform)) - { - boneTransform = Transform.Identity; - } - - FinalBonesMatrix[i] = Transform.Identity; - FinalBonesMatrix[i].Relation = boneTransform.Matrix; - } } - public void UpdateAnimation(float deltaTime) + public void UpdateAnimation(FMeshBoneInfo[] boneInfos, ref Dictionary bonesTransformByIndex) { - DeltaTime = deltaTime; if (CurrentAnimation != null) { // CurrentTime = deltaTime; - CalculateBoneTransform(); + CalculateBoneTransform(boneInfos, ref bonesTransformByIndex); } } - public void CalculateBoneTransform() + public void CalculateBoneTransform(FMeshBoneInfo[] boneInfos, ref Dictionary bonesTransformByIndex) { var sequence = CurrentAnimation.Sequences[0]; - for (int boneIndex = 0; boneIndex < FinalBonesMatrix.Length; boneIndex++) + for (int boneIndex = 0; boneIndex < boneInfos.Length; boneIndex++) { var boneOrientation = FQuat.Identity; var bonePosition = FVector.ZeroVector; + var boneScale = FVector.OneVector; sequence.Tracks[boneIndex].GetBonePosition(CurrentTime, sequence.NumFrames, false, ref bonePosition, ref boneOrientation); + if (CurrentTime < sequence.Tracks[boneIndex].KeyScale.Length) + boneScale = sequence.Tracks[boneIndex].KeyScale[CurrentTime]; - FinalBonesMatrix[boneIndex].Rotation = boneOrientation; - FinalBonesMatrix[boneIndex].Position = bonePosition * Constants.SCALE_DOWN_RATIO; + if (!bonesTransformByIndex.TryGetValue(boneInfos[boneIndex].ParentIndex, out var parentTransform)) + parentTransform = new Transform { Relation = Matrix4x4.Identity }; + + bonesTransformByIndex[boneIndex] = new Transform + { + Relation = parentTransform.Matrix, + Rotation = boneOrientation, + Position = bonePosition * Constants.SCALE_DOWN_RATIO, + Scale = boneScale + }; } } diff --git a/FModel/Views/Snooper/Models/Animations/Skeleton.cs b/FModel/Views/Snooper/Models/Animations/Skeleton.cs index f37601c7..d7ecd0da 100644 --- a/FModel/Views/Snooper/Models/Animations/Skeleton.cs +++ b/FModel/Views/Snooper/Models/Animations/Skeleton.cs @@ -13,7 +13,7 @@ public class Skeleton : IDisposable public readonly USkeleton UnrealSkeleton; public readonly FReferenceSkeleton ReferenceSkeleton; public readonly Dictionary BonesIndexByName; - public readonly Dictionary BonesTransformByIndex; + public Dictionary BonesTransformByIndex; public readonly bool IsLoaded; public Animation Anim; @@ -27,22 +27,23 @@ public class Skeleton : IDisposable public Skeleton(FPackageIndex package, FReferenceSkeleton referenceSkeleton, Transform transform) : this() { UnrealSkeleton = package.Load(); - if (UnrealSkeleton == null) return; + IsLoaded = UnrealSkeleton != null; + if (!IsLoaded) return; ReferenceSkeleton = referenceSkeleton ?? UnrealSkeleton.ReferenceSkeleton; BonesIndexByName = ReferenceSkeleton.FinalNameToIndexMap; BonesTransformByIndex = new Dictionary(); UpdateBoneMatrices(transform.Matrix); - IsLoaded = true; } public void SetAnimation(CAnimSet anim) { - Anim = new Animation(anim, BonesIndexByName, BonesTransformByIndex); + Anim = new Animation(anim); } public void UpdateBoneMatrices(Matrix4x4 matrix) { + if (!IsLoaded) return; foreach (var boneIndex in BonesIndexByName.Values) { var bone = ReferenceSkeleton.FinalRefBonePose[boneIndex]; @@ -69,9 +70,10 @@ public class Skeleton : IDisposable public void SetUniform(Shader shader) { if (!IsLoaded) return; - for (var i = 0; i < Anim?.FinalBonesMatrix.Length; i++) + Anim?.UpdateAnimation(ReferenceSkeleton.FinalRefBoneInfo, ref BonesTransformByIndex); + foreach ((int boneIndex, Transform boneTransform) in BonesTransformByIndex) { - shader.SetUniform($"uFinalBonesMatrix[{i}]", Anim.FinalBonesMatrix[i].Matrix); + shader.SetUniform($"uFinalBonesMatrix[{boneIndex}]", boneTransform.Matrix); } } diff --git a/FModel/Views/Snooper/Models/Model.cs b/FModel/Views/Snooper/Models/Model.cs index 88ce1137..827aac75 100644 --- a/FModel/Views/Snooper/Models/Model.cs +++ b/FModel/Views/Snooper/Models/Model.cs @@ -362,6 +362,7 @@ public class Model : IDisposable shader.SetUniform("uMorphTime", MorphTime); if (!outline) { + // if (HasSkeleton) Skeleton.SetUniform(shader); shader.SetUniform("uUvCount", UvCount); shader.SetUniform("uHasVertexColors", HasVertexColors); } diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs index 7f2276bc..f1019c59 100644 --- a/FModel/Views/Snooper/Renderer.cs +++ b/FModel/Views/Snooper/Renderer.cs @@ -231,7 +231,7 @@ public class Renderer : IDisposable Services.ApplicationService.ApplicationView.Status.UpdateStatusLabel($"{original.Name} ... {i}/{length}"); WorldCamera(actor); - // WorldLight(actor); + WorldLight(actor); WorldMesh(actor, transform); AdditionalWorlds(actor, transform.Matrix, cancellationToken); } @@ -250,10 +250,22 @@ public class Renderer : IDisposable private void WorldLight(UObject actor) { - // if (!actor.TryGetValue(out FPackageIndex lightComponent, "LightComponent") || - // lightComponent.Load() is not { } lightObject) return; - // - // Cache.Lights.Add(new PointLight(Cache.Icons["pointlight"], lightObject, FVector.ZeroVector)); + if (!actor.TryGetValue(out FPackageIndex lightComponent, "LightComponent") || + lightComponent.Load() is not { } lightObject) return; + + switch (actor.ExportType) + { + case "PointLight": + Options.Lights.Add(new PointLight(Options.Icons["pointlight"], lightObject)); + break; + case "SpotLight": + Options.Lights.Add(new SpotLight(Options.Icons["spotlight"], lightObject)); + break; + case "RectLight": + case "SkyLight": + case "DirectionalLight": + break; + } } private void WorldMesh(UObject actor, Transform transform) diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index 89f77321..bd5378a0 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -158,11 +158,14 @@ public class SnimGui { for (int i = 0; i < s.Renderer.Options.Lights.Count; i++) { - var id = $"[{i}] {s.Renderer.Options.Models[s.Renderer.Options.Lights[i].Model].Name}"; + var light = s.Renderer.Options.Lights[i]; + var id = s.Renderer.Options.TryGetModel(light.Model, out var lightModel) ? lightModel.Name : "None"; + + id += $"##{i}"; if (ImGui.TreeNode(id) && ImGui.BeginTable(id, 2)) { - s.Renderer.Options.SelectModel(s.Renderer.Options.Lights[i].Model); - s.Renderer.Options.Lights[i].ImGuiLight(); + s.Renderer.Options.SelectModel(light.Model); + light.ImGuiLight(); ImGui.EndTable(); ImGui.TreePop(); } @@ -341,8 +344,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio _saver.Value = model.TrySave(out _saver.Label, out _saver.Path); s.WindowShouldFreeze(false); } - ImGui.BeginDisabled(true); - // ImGui.BeginDisabled(!model.HasSkeleton); + ImGui.BeginDisabled(!model.HasSkeleton); if (ImGui.Selectable("Animate")) { s.Renderer.Options.AnimateMesh(true); @@ -444,6 +446,10 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio Layout("Guid");ImGui.Text($" : {s.Renderer.Options.SelectedModel.ToString(EGuidFormats.UniqueObjectGuid)}"); if (model.HasSkeleton) { + if (model.Skeleton.Anim != null) + { + ImGui.DragInt("Time", ref model.Skeleton.Anim.CurrentTime, 1, 0, 110); + } Layout("Skeleton");ImGui.Text($" : {model.Skeleton.UnrealSkeleton.Name}"); Layout("Bones");ImGui.Text($" : x{model.Skeleton.UnrealSkeleton.BoneTree.Length}"); } diff --git a/FModel/Views/Snooper/Transform.cs b/FModel/Views/Snooper/Transform.cs index 8a623853..ea63f2f2 100644 --- a/FModel/Views/Snooper/Transform.cs +++ b/FModel/Views/Snooper/Transform.cs @@ -74,4 +74,6 @@ public class Transform ImGui.TreePop(); } } + + public override string ToString() => Matrix.Translation.ToString(); }