예제 #1
0
        // 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();
        }
예제 #2
0
        // 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);
        }
예제 #3
0
 public void SetParent(Bone parent)
 {
     Parent = parent;
 }
예제 #4
0
 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);
            }
        }
예제 #6
0
 public Skeleton()
 {
     Bones = new Bone[0];
 }
예제 #7
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);
            }
        }