public NewAnimSkeleton(Model mdl, List <FLVER.Bone> flverBones) { MODEL = mdl; int[] childCounts = new int[flverBones.Count]; FlverSkeleton = new List <FlverBoneInfo>(); for (int i = 0; i < flverBones.Count; i++) { var newBone = new FlverBoneInfo(flverBones[i], flverBones); if (flverBones[i].ParentIndex >= 0) { childCounts[flverBones[i].ParentIndex]++; } FlverSkeleton.Add(newBone); } for (int i = 0; i < FlverSkeleton.Count; i++) { FlverSkeleton[i].Length = Math.Max(0.1f, (flverBones[i].BoundingBoxMax.Z - flverBones[i].BoundingBoxMin.Z) * 0.8f); if (childCounts[i] == 1 && flverBones[i].ChildIndex >= 0) { var parentChildDifference = Vector3.Transform(Vector3.Zero, FlverSkeleton[flverBones[i].ChildIndex].ReferenceMatrix) - Vector3.Transform(Vector3.Zero, FlverSkeleton[i].ReferenceMatrix); var parentChildDirection = Vector3.Normalize(parentChildDifference); var parentDir = Vector3.TransformNormal(Vector3.Backward, Matrix.CreateRotationX(flverBones[i].Rotation.X) * Matrix.CreateRotationZ(flverBones[i].Rotation.Z) * Matrix.CreateRotationY(flverBones[i].Rotation.Y)); var dot = Vector3.Dot(parentDir, parentChildDirection); FlverSkeleton[i].Length = parentChildDifference.Length() * (float)Math.Cos(dot); } else { FlverSkeleton[i].Length = Math.Max(0.1f, (flverBones[i].BoundingBoxMax.Z - flverBones[i].BoundingBoxMin.Z) * 0.8f); } } for (int i = 0; i < GFXShaders.FlverShader.MaxBonePerMatrixArray; i++) { ShaderMatrices0[i] = Matrix.Identity; ShaderMatrices1[i] = Matrix.Identity; ShaderMatrices2[i] = Matrix.Identity; ShaderMatrices3[i] = Matrix.Identity; ShaderMatrices4[i] = Matrix.Identity; ShaderMatrices5[i] = Matrix.Identity; } }
public NewAnimSkeleton_FLVER(Model mdl, List <FLVER.Bone> flverBones) { MODEL = mdl; int[] childCounts = new int[flverBones.Count]; FlverSkeleton.Clear(); TopLevelFlverBoneIndices.Clear(); for (int i = 0; i < flverBones.Count; i++) { if (flverBones[i].ParentIndex < 0) { TopLevelFlverBoneIndices.Add(i); } var newBone = new FlverBoneInfo(flverBones[i], flverBones); if (flverBones[i].ParentIndex >= 0) { childCounts[flverBones[i].ParentIndex]++; } FlverSkeleton.Add(newBone); } for (int i = 0; i < FlverSkeleton.Count; i++) { //FlverSkeleton[i].Length = Math.Max(0.1f, // (flverBones[i].BoundingBoxMax.Z - flverBones[i].BoundingBoxMin.Z) * 0.8f); //if (childCounts[i] == 1 && flverBones[i].ChildIndex >= 0) //{ // var parentChildDifference = Vector3.Transform(Vector3.Zero, // FlverSkeleton[flverBones[i].ChildIndex].ReferenceMatrix) - // Vector3.Transform(Vector3.Zero, FlverSkeleton[i].ReferenceMatrix); // var parentChildDirection = Vector3.Normalize(parentChildDifference); // var parentDir = Vector3.TransformNormal(Vector3.Backward, // Matrix.CreateRotationX(flverBones[i].Rotation.X) * // Matrix.CreateRotationZ(flverBones[i].Rotation.Z) * // Matrix.CreateRotationY(flverBones[i].Rotation.Y)); // var dot = Vector3.Dot(parentDir, parentChildDirection); // FlverSkeleton[i].Length = parentChildDifference.Length() * (float)Math.Cos(dot); //} //else //{ // FlverSkeleton[i].Length = Math.Max(0.1f, // (flverBones[i].BoundingBoxMax.Z - flverBones[i].BoundingBoxMin.Z) * 0.8f); //} if (flverBones[i].ParentIndex >= 0 && flverBones[i].ParentIndex < flverBones.Count) { FlverSkeleton[flverBones[i].ParentIndex].ChildBones.Add(FlverSkeleton[i]); } } for (int i = 0; i < GFXShaders.FlverShader.MaxBonePerMatrixArray; i++) { ShaderMatrices0[i] = Matrix.Identity; ShaderMatrices1[i] = Matrix.Identity; ShaderMatrices2[i] = Matrix.Identity; ShaderMatrices3[i] = Matrix.Identity; ShaderMatrices4[i] = Matrix.Identity; ShaderMatrices5[i] = Matrix.Identity; ShaderMatrices0_RefPose[i] = Matrix.Identity; ShaderMatrices1_RefPose[i] = Matrix.Identity; ShaderMatrices2_RefPose[i] = Matrix.Identity; ShaderMatrices3_RefPose[i] = Matrix.Identity; ShaderMatrices4_RefPose[i] = Matrix.Identity; ShaderMatrices5_RefPose[i] = Matrix.Identity; } }
public void LoadHKXSkeleton(HKX.HKASkeleton skeleton) { OriginalHavokSkeleton = skeleton; HkxSkeleton.Clear(); for (int i = 0; i < skeleton.Bones.Size; i++) { var newHkxBone = new HkxBoneInfo(); newHkxBone.Name = skeleton.Bones[i].Name.GetString(); newHkxBone.ParentIndex = skeleton.ParentIndices[i].data; newHkxBone.RelativeReferenceMatrix = Matrix.CreateScale(new Vector3( skeleton.Transforms[i].Scale.Vector.X, skeleton.Transforms[i].Scale.Vector.Y, skeleton.Transforms[i].Scale.Vector.Z)) * Matrix.CreateFromQuaternion(new Quaternion( skeleton.Transforms[i].Rotation.Vector.X, skeleton.Transforms[i].Rotation.Vector.Y, skeleton.Transforms[i].Rotation.Vector.Z, skeleton.Transforms[i].Rotation.Vector.W)) * Matrix.CreateTranslation(new Vector3( skeleton.Transforms[i].Position.Vector.X, skeleton.Transforms[i].Position.Vector.Y, skeleton.Transforms[i].Position.Vector.Z)); for (int j = 0; j < FlverSkeleton.Count; j++) { if (FlverSkeleton[j].Name == newHkxBone.Name) { FlverSkeleton[j].HkxBoneIndex = i; newHkxBone.FlverBoneIndex = j; break; } } HkxSkeleton.Add(newHkxBone); } Matrix GetAbsoluteReferenceMatrix(int i) { Matrix result = Matrix.Identity; do { result *= HkxSkeleton[i].RelativeReferenceMatrix; i = HkxSkeleton[i].ParentIndex; }while (i >= 0); return(result); } var flverDeadBonesToApplyHkxChildrenTo = new Dictionary <int, int>(); for (int i = 0; i < HkxSkeleton.Count; i++) { HkxSkeleton[i].ReferenceMatrix = GetAbsoluteReferenceMatrix(i); for (int j = 0; j < HkxSkeleton.Count; j++) { if (HkxSkeleton[j].ParentIndex == i) { HkxSkeleton[i].ChildIndices.Add(j); } } if (HkxSkeleton[i].ParentIndex < 0) { RootBoneIndices.Add(i); } if (HkxSkeleton[i].FlverBoneIndex == -1) { HkxSkeleton[i].FlverBoneIndex = FlverSkeleton.Count; var newFlverBone = new FlverBoneInfo(HkxSkeleton[i], HkxSkeleton, FlverSkeleton); FlverSkeleton.Add(newFlverBone); if (!flverDeadBonesToApplyHkxChildrenTo.ContainsKey(HkxSkeleton[i].FlverBoneIndex)) { flverDeadBonesToApplyHkxChildrenTo.Add(HkxSkeleton[i].FlverBoneIndex, i); } } else if (FlverSkeleton[HkxSkeleton[i].FlverBoneIndex].IsNub) { FlverSkeleton[HkxSkeleton[i].FlverBoneIndex].ApplyHkxBoneProperties(HkxSkeleton[i], HkxSkeleton, FlverSkeleton); if (!flverDeadBonesToApplyHkxChildrenTo.ContainsKey(HkxSkeleton[i].FlverBoneIndex)) { flverDeadBonesToApplyHkxChildrenTo.Add(HkxSkeleton[i].FlverBoneIndex, i); } } foreach (var kvp in flverDeadBonesToApplyHkxChildrenTo) { FlverSkeleton[kvp.Key].ChildBones.Clear(); var copyFromHkx = HkxSkeleton[kvp.Value]; foreach (var ci in copyFromHkx.ChildIndices) { if (ci >= 0 && ci < HkxSkeleton.Count) { var matchingFlverChildBone = FlverSkeleton.FirstOrDefault(b => b.Name == HkxSkeleton[ci].Name); if (matchingFlverChildBone != null && !FlverSkeleton[kvp.Key].ChildBones.Contains(matchingFlverChildBone)) { FlverSkeleton[kvp.Key].ChildBones.Add(matchingFlverChildBone); } } } if (HkxSkeleton[kvp.Value].ParentIndex >= 0 && HkxSkeleton[kvp.Value].ParentIndex < HkxSkeleton.Count) { var matchingFlverParentBone = FlverSkeleton.FirstOrDefault(b => b.Name == HkxSkeleton[HkxSkeleton[kvp.Value].ParentIndex].Name); if (matchingFlverParentBone != null && !matchingFlverParentBone.ChildBones.Contains(FlverSkeleton[kvp.Key])) { matchingFlverParentBone.ChildBones.Add(FlverSkeleton[kvp.Key]); } } } } }