diff --git a/CUE4Parse b/CUE4Parse index 3a7ddc13..c6fcae36 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 3a7ddc13bb370e5988bc122a7cf67ad8036ccaf1 +Subproject commit c6fcae365d91d7d9501e2be79e78dfba136b4670 diff --git a/FModel/Resources/default.vert b/FModel/Resources/default.vert index 03da234c..49331454 100644 --- a/FModel/Resources/default.vert +++ b/FModel/Resources/default.vert @@ -33,17 +33,26 @@ void main() vec4 finalPos = vec4(0.0); vec4 finalNormal = vec4(0.0); vec4 finalTangent = vec4(0.0); - for(int i = 0 ; i < 4; i++) + if (vBoneIds != vBoneWeights) { - int boneIndex = int(vBoneIds[i]); - if(boneIndex < 0) break; + for(int i = 0 ; i < 4; i++) + { + int boneIndex = int(vBoneIds[i]); + if(boneIndex < 0) break; - mat4 boneMatrix = uFinalBonesMatrix[boneIndex]; - float weight = vBoneWeights[i]; + mat4 boneMatrix = uFinalBonesMatrix[boneIndex]; + float weight = vBoneWeights[i]; - finalPos += boneMatrix * bindPos * weight; - finalNormal += boneMatrix * bindNormal * weight; - finalTangent += boneMatrix * bindTangent * weight; + finalPos += boneMatrix * bindPos * weight; + finalNormal += boneMatrix * bindNormal * weight; + finalTangent += boneMatrix * bindTangent * weight; + } + } + else + { + finalPos = bindPos; + finalNormal = bindNormal; + finalTangent = bindTangent; } gl_Position = uProjection * uView * vInstanceMatrix * finalPos; diff --git a/FModel/Resources/outline.vert b/FModel/Resources/outline.vert index ec0811cb..1784f75e 100644 --- a/FModel/Resources/outline.vert +++ b/FModel/Resources/outline.vert @@ -20,16 +20,24 @@ void main() vec4 finalPos = vec4(0.0); vec4 finalNormal = vec4(0.0); - for(int i = 0 ; i < 4; i++) + if (vBoneIds != vBoneWeights) { - int boneIndex = int(vBoneIds[i]); - if(boneIndex < 0) break; + for(int i = 0 ; i < 4; i++) + { + int boneIndex = int(vBoneIds[i]); + if(boneIndex < 0) break; - mat4 boneMatrix = uFinalBonesMatrix[boneIndex]; - float weight = vBoneWeights[i]; + mat4 boneMatrix = uFinalBonesMatrix[boneIndex]; + float weight = vBoneWeights[i]; - finalPos += boneMatrix * bindPos * weight; - finalNormal += boneMatrix * bindNormal * weight; + finalPos += boneMatrix * bindPos * weight; + finalNormal += boneMatrix * bindNormal * weight; + } + } + else + { + finalPos = bindPos; + finalNormal = bindNormal; } float scaleFactor = distance(vec3(finalPos), uViewPos) * 0.0025; diff --git a/FModel/Resources/picking.vert b/FModel/Resources/picking.vert index b5f91692..a1d21292 100644 --- a/FModel/Resources/picking.vert +++ b/FModel/Resources/picking.vert @@ -1,15 +1,38 @@ #version 460 core layout (location = 1) in vec3 vPos; +layout (location = 7) in vec4 vBoneIds; +layout (location = 8) in vec4 vBoneWeights; layout (location = 9) in mat4 vInstanceMatrix; -layout (location = 13) in vec3 vMorphTarget; +layout (location = 13) in vec3 vMorphTargetPos; uniform mat4 uView; uniform mat4 uProjection; uniform float uMorphTime; +uniform mat4 uFinalBonesMatrix[250]; void main() { - vec3 pos = mix(vPos, vMorphTarget, uMorphTime); - gl_Position = uProjection * uView * vInstanceMatrix * vec4(pos, 1.0); + vec4 bindPos = vec4(mix(vPos, vMorphTargetPos, uMorphTime), 1.0); + + vec4 finalPos = vec4(0.0); + if (vBoneIds != vBoneWeights) + { + for(int i = 0 ; i < 4; i++) + { + int boneIndex = int(vBoneIds[i]); + if(boneIndex < 0) break; + + mat4 boneMatrix = uFinalBonesMatrix[boneIndex]; + float weight = vBoneWeights[i]; + + finalPos += boneMatrix * bindPos * weight; + } + } + else + { + finalPos = bindPos; + } + + gl_Position = uProjection * uView * vInstanceMatrix * finalPos; } diff --git a/FModel/Views/Snooper/Models/Animations/Animation.cs b/FModel/Views/Snooper/Models/Animations/Animation.cs index 9efc953a..67227251 100644 --- a/FModel/Views/Snooper/Models/Animations/Animation.cs +++ b/FModel/Views/Snooper/Models/Animations/Animation.cs @@ -54,6 +54,18 @@ public class Animation : IDisposable bonePosition *= Constants.SCALE_DOWN_RATIO; + switch (anim.BoneModes[trackIndex]) + { + case EBoneRetargetingMode.Animation: + case EBoneRetargetingMode.Mesh: + case EBoneRetargetingMode.AnimationScaled: + case EBoneRetargetingMode.AnimationRelative: + case EBoneRetargetingMode.OrientAndScale: + case EBoneRetargetingMode.Count: + default: + break; + } + BoneTransforms[trackIndex][frame] = new Transform { Relation = bone.ParentIndex >= 0 ? BoneTransforms[bone.ParentIndex][frame].Matrix : originalTransform.Relation, diff --git a/FModel/Views/Snooper/Models/Animations/Skeleton.cs b/FModel/Views/Snooper/Models/Animations/Skeleton.cs index e37df2cf..95f12317 100644 --- a/FModel/Views/Snooper/Models/Animations/Skeleton.cs +++ b/FModel/Views/Snooper/Models/Animations/Skeleton.cs @@ -77,22 +77,21 @@ public class Skeleton : IDisposable shader.SetUniform($"uFinalBonesMatrix[{boneIndex}]", Matrix4x4.Identity); } } - - public void SetUniform(float deltaSeconds, bool outline, Shader shader) + public void SetUniform(Shader shader, float deltaSeconds = 0f, bool updateElapsedTime = false) { if (!IsLoaded) return; if (Anim == null) SetPoseUniform(shader); else { - if (!outline) Anim.ElapsedTime += deltaSeconds / Anim.TimePerFrame; - foreach ((var boneName, var trackIndex) in UnrealSkeleton.ReferenceSkeleton.FinalNameToIndexMap) + if (!updateElapsedTime) Anim.ElapsedTime += deltaSeconds / Anim.TimePerFrame; + foreach (var boneIndex in BonesTransformByIndex.Keys) { - if (!BonesIndexByLoweredName.TryGetValue(boneName.ToLower(), out var boneIndex)) - continue; - if (!InvertedBonesMatrixByIndex.TryGetValue(boneIndex, out var invertMatrix)) - throw new ArgumentNullException($"no inverse matrix for bone '{boneIndex}'"); if (boneIndex >= Constants.MAX_BONE_UNIFORM) break; + if (!InvertedBonesMatrixByIndex.TryGetValue(boneIndex, out var invertMatrix)) + throw new ArgumentNullException($"no inverse matrix for bone '{boneIndex}'"); + if (!Anim.TrackIndexByBoneIndex.TryGetValue(boneIndex, out var trackIndex)) + throw new ArgumentNullException($"no track index for bone '{boneIndex}'"); shader.SetUniform($"uFinalBonesMatrix[{boneIndex}]", invertMatrix * Anim.InterpolateBoneTransform(trackIndex)); } diff --git a/FModel/Views/Snooper/Models/Model.cs b/FModel/Views/Snooper/Models/Model.cs index 50e3fd3e..14b71559 100644 --- a/FModel/Views/Snooper/Models/Model.cs +++ b/FModel/Views/Snooper/Models/Model.cs @@ -266,7 +266,7 @@ public class Model : IDisposable if (!options.TryGetModel(attached, out var attachedModel)) continue; - attachedModel.Transforms[attachedModel.SelectedInstance].Relation = socket.Transform.Matrix * socketRelation; + attachedModel.Transforms[attachedModel.SelectedInstance].Relation = socket.Transform.LocalMatrix * socketRelation; attachedModel.UpdateMatrices(options); } } @@ -382,7 +382,7 @@ public class Model : IDisposable _vao.Bind(); shader.SetUniform("uMorphTime", MorphTime); - if (HasSkeleton) Skeleton.SetUniform(deltaSeconds, outline, shader); + if (HasSkeleton) Skeleton.SetUniform(shader, deltaSeconds, outline); if (!outline) { shader.SetUniform("uUvCount", UvCount); @@ -413,6 +413,8 @@ public class Model : IDisposable _vao.Bind(); shader.SetUniform("uMorphTime", MorphTime); + if (HasSkeleton) Skeleton.SetUniform(shader); + foreach (var section in Sections) { if (!section.Show) continue;