// Construct the Armature object from mesh skeleton KV data. public void ConstructFromNTRO(NTROStruct skeletonData, Dictionary<int, int> remapTable) { var boneNames = skeletonData.Get<NTROArray>("m_boneName").ToArray<string>(); var boneParents = skeletonData.Get<NTROArray>("m_nParent").ToArray<short>(); var bonePositions = skeletonData.Get<NTROArray>("m_bonePosParent").ToArray<Vector3>(); var boneRotations = skeletonData.Get<NTROArray>("m_boneRotParent").ToArray<Vector4>(); // Initialise bone array Bones = new Bone[boneNames.Length]; //Add all bones to the list for (var i = 0; i < boneNames.Length; i++) { var name = boneNames[i]; var position = new OpenTK.Vector3(bonePositions[i].X, bonePositions[i].Y, bonePositions[i].Z); var rotation = new Quaternion(boneRotations[i].X, boneRotations[i].Y, boneRotations[i].Z, boneRotations[i].W); // Create bone var index = remapTable.ContainsKey(i) ? remapTable[i] : -1; var bone = new Bone(name, index, position, rotation); if (boneParents[i] != -1) { bone.SetParent(Bones[boneParents[i]]); Bones[boneParents[i]].AddChild(bone); } Bones[i] = bone; } FindRoots(); }
// Armature constructor public Skeleton(Resource model) { Bones = new Bone[0]; Roots = new List<Bone>(); var modelData = (NTRO)model.Blocks[BlockType.DATA]; // Check if there is any skeleton data present at all if (!modelData.Output.Contains("m_modelSkeleton")) { Console.WriteLine("No skeleton data found."); } // Get the remap table and invert it for our construction method var remapTable = ((NTROArray)modelData.Output["m_remappingTable"]).ToArray<short>(); var invMapTable = new Dictionary<int, int>(); for (var i = 0; i < remapTable.Length; i++) { if (!invMapTable.ContainsKey(remapTable[i])) { invMapTable.Add(remapTable[i], i); } } // Construct the armature from the skeleton KV ConstructFromNTRO(((NTROValue<NTROStruct>)modelData.Output["m_modelSkeleton"]).Value, invMapTable); }
public void SetParent(Bone parent) { Parent = parent; }
public void AddChild(Bone child) { Children.Add(child); }
private void GetAnimationMatrixRecursive(Bone bone, Matrix4 parentBindPose, Matrix4 parentInvBindPose, Frame transforms, ref Matrix4[] matrices) { // Calculate world space bind and inverse bind pose var bindPose = parentBindPose; var invBindPose = parentInvBindPose * bone.InverseBindPose; // Calculate transformation matrix var transformMatrix = Matrix4.Identity; if (transforms.Bones.ContainsKey(bone.Name)) { var transform = transforms.Bones[bone.Name]; transformMatrix = Matrix4.CreateFromQuaternion(transform.Angle) * Matrix4.CreateTranslation(transform.Position); } // Apply tranformation var transformed = transformMatrix * bindPose; // Store result if (bone.Index != -1) { matrices[bone.Index] = invBindPose * transformed; } // Propagate to childen foreach (var child in bone.Children) { GetAnimationMatrixRecursive(child, transformed, invBindPose, transforms, ref matrices); } }
public Skeleton() { Bones = new Bone[0]; }
private void DebugDrawRecursive(DebugUtil debug, Bone bone, Matrix4 matrix) { var transform = bone.BindPose * matrix; debug.AddCube(transform); foreach (var child in bone.Children) { DebugDrawRecursive(debug, child, transform); } }