示例#1
0
        public static Assimp.Matrix4x4 AssimpCalculateInverseMatrix(STBone bone)
        {
            Assimp.Matrix4x4 transf;

            //Get parent transform for a smooth matrix
            if (bone.Parent != null && bone.Parent is STBone)
            {
                transf = AssimpCalculateInverseMatrix((STBone)bone.Parent);
            }
            else
            {
                transf = Assimp.Matrix4x4.Identity;
            }

            //Now calculate the matrix with TK matrices
            var trans = Assimp.Matrix4x4.FromTranslation(new Vector3D(bone.position[0], bone.position[1], bone.position[2]));
            var scale = Assimp.Matrix4x4.FromScaling(new Vector3D(bone.scale[0], bone.scale[1], bone.scale[2]));
            var rotX  = Assimp.Matrix4x4.FromRotationX(bone.rotation[0]);
            var rotY  = Assimp.Matrix4x4.FromRotationY(bone.rotation[1]);
            var rotZ  = Assimp.Matrix4x4.FromRotationZ(bone.rotation[2]);

            var result = scale * (rotX * rotY * rotZ) * trans;

            result.Inverse();

            return(transf);
        }
示例#2
0
        public static Matrix4x4 GetBoneMatrix(STBone bone)
        {
            var pos  = Matrix4x4.FromTranslation(new Vector3D(bone.position[0], bone.position[1], bone.position[2]));
            var rotx = Matrix4x4.FromRotationX(bone.rotation[0]);
            var roty = Matrix4x4.FromRotationY(bone.rotation[1]);
            var rotz = Matrix4x4.FromRotationZ(bone.rotation[2]);
            var sca  = Matrix4x4.FromScaling(new Vector3D(bone.scale[0], bone.scale[1], bone.scale[2]));

            return(sca * (rotx * roty * rotz) * pos);
        }
示例#3
0
        private void SaveBones(Node parentBone, STBone bone, STSkeleton skeleton)
        {
            Node boneNode = new Node(bone.Text);

            parentBone.Children.Add(boneNode);

            boneNode.Transform = AssimpHelper.GetBoneMatrix(bone);

            foreach (STBone child in bone.GetChildren())
            {
                SaveBones(boneNode, child, skeleton);
            }
        }
示例#4
0
 public Matrix4 GetBoneTransform(STBone Bone)
 {
     if (Bone == null)
     {
         return(Matrix4.Identity);
     }
     if (Bone.parentIndex == -1)
     {
         return(Bone.GetTransform());
     }
     else
     {
         return(Bone.GetTransform() * GetBoneTransform(bones[Bone.parentIndex]));
     }
 }
示例#5
0
        public STBone CreateGenericBone(SELib.SEModel seModel, SELib.SEModelBone seBone)
        {
            STBone bone = new STBone(skeleton);

            bone.Text         = seBone.BoneName;
            bone.parentIndex  = seBone.BoneParent;
            bone.RotationType = STBone.BoneRotationType.Euler;

            Vector3 rotEular = ToEular(seBone.LocalRotation);

            bone.position = new float[] { (float)seBone.LocalPosition.X, (float)seBone.LocalPosition.Y, (float)seBone.LocalPosition.Z };
            bone.scale    = new float[] { (float)seBone.Scale.X, (float)seBone.Scale.Y, (float)seBone.Scale.Z };
            bone.rotation = new float[] { rotEular.X, rotEular.Y, rotEular.Z, 0 };

            return(bone);
        }
示例#6
0
        public List <STBone> getBoneTreeOrder()
        {
            List <STBone>  bone = new List <STBone>();
            Queue <STBone> q    = new Queue <STBone>();

            q.Enqueue(bones[0]);

            while (q.Count > 0)
            {
                STBone b = q.Dequeue();
                foreach (STBone bo in b.GetChildren())
                {
                    q.Enqueue(bo);
                }
                bone.Add(b);
            }
            return(bone);
        }
示例#7
0
        public STBone CreateGenericBone(SELib.SEModel seModel, SELib.SEModelBone seBone)
        {
            STBone bone = new STBone(skeleton);

            bone.Text         = seBone.BoneName;
            bone.parentIndex  = seBone.BoneParent;
            bone.RotationType = STBone.BoneRotationType.Euler;

            bone.Position = new Vector3(
                (float)seBone.LocalPosition.X,
                (float)seBone.LocalPosition.Y,
                (float)seBone.LocalPosition.Z);
            bone.Scale = new Vector3(
                (float)seBone.Scale.X,
                (float)seBone.Scale.Y,
                (float)seBone.Scale.Z);
            bone.Rotation = new Quaternion(
                (float)seBone.LocalRotation.X,
                (float)seBone.LocalRotation.Y,
                (float)seBone.LocalRotation.Z,
                (float)seBone.LocalRotation.W);

            return(bone);
        }
示例#8
0
        private Mesh SaveMesh(STGenericObject genericObj, Scene scene, int index, STSkeleton skeleton, List <int> NodeArray)
        {
            //Assimp is weird so use mesh_# for the name. We'll change it back after save
            Mesh mesh = new Mesh($"mesh_{ index }", PrimitiveType.Triangle);

            if (genericObj.MaterialIndex < scene.MaterialCount && genericObj.MaterialIndex > 0)
            {
                mesh.MaterialIndex = genericObj.MaterialIndex;
            }
            else
            {
                mesh.MaterialIndex = 0;
            }

            List <Vector3D> textureCoords0 = new List <Vector3D>();
            List <Vector3D> textureCoords1 = new List <Vector3D>();
            List <Vector3D> textureCoords2 = new List <Vector3D>();
            List <Color4D>  vertexColors   = new List <Color4D>();

            int vertexID = 0;

            foreach (Vertex v in genericObj.vertices)
            {
                mesh.Vertices.Add(new Vector3D(v.pos.X, v.pos.Y, v.pos.Z));
                mesh.Normals.Add(new Vector3D(v.nrm.X, v.nrm.Y, v.nrm.Z));
                textureCoords0.Add(new Vector3D(v.uv0.X, v.uv0.Y, 0));
                textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0));
                textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0));
                vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W));

                if (skeleton != null)
                {
                    for (int j = 0; j < v.boneIds.Count; j++)
                    {
                        if (j < genericObj.VertexSkinCount)
                        {
                            STBone STbone = null;
                            if (NodeArray != null)
                            {
                                //Get the bone via the node array and bone index from the vertex
                                STbone = skeleton.bones[NodeArray[v.boneIds[j]]];
                            }
                            else
                            {
                                STbone = skeleton.bones[v.boneIds[j]];
                            }

                            //Find the index of a bone. If it doesn't exist then we add it
                            int boneInd = mesh.Bones.FindIndex(x => x.Name == STbone.Text);

                            if (boneInd == -1)
                            {
                                var matrices = Toolbox.Library.IO.MatrixExenstion.CalculateInverseMatrix(STbone);

                                //Set the inverse matrix
                                Matrix4x4 transform = matrices.inverse.FromNumerics();

                                //Create a new assimp bone
                                Bone bone = new Bone();
                                bone.Name         = STbone.Text;
                                bone.OffsetMatrix = STbone.invert.ToMatrix4x4();
                                mesh.Bones.Add(bone);
                                BoneNames.Add(bone.Name);

                                boneInd = mesh.Bones.IndexOf(bone); //Set the index of the bone for the vertex weight
                            }

                            int MinWeightAmount = 0;

                            //Check if the max amount of weights is higher than the current bone id
                            if (v.boneWeights.Count > j && v.boneWeights[j] > MinWeightAmount)
                            {
                                if (v.boneWeights[j] <= 1)
                                {
                                    mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, v.boneWeights[j]));
                                }
                                else
                                {
                                    mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, 1));
                                }
                            }
                            else if (v.boneWeights.Count == 0 || v.boneWeights[j] > MinWeightAmount)
                            {
                                mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, 1));
                            }
                        }
                    }
                }


                vertexID++;
            }

            if (genericObj.lodMeshes.Count != 0)
            {
                List <int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces;
                for (int f = 0; f < faces.Count; f++)
                {
                    mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] }));
                }
            }
            if (genericObj.PolygonGroups.Count != 0)
            {
                for (int p = 0; p < genericObj.PolygonGroups.Count; p++)
                {
                    var polygonGroup = genericObj.PolygonGroups[p];
                    for (int f = 0; f < polygonGroup.faces.Count; f++)
                    {
                        if (f < polygonGroup.faces.Count - 2)
                        {
                            mesh.Faces.Add(new Face(new int[] { polygonGroup.faces[f++], polygonGroup.faces[f++], polygonGroup.faces[f] }));
                        }
                    }
                }
            }

            mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0);
            mesh.TextureCoordinateChannels.SetValue(textureCoords1, 1);
            mesh.TextureCoordinateChannels.SetValue(textureCoords2, 2);
            mesh.VertexColorChannels.SetValue(vertexColors, 0);

            return(mesh);
        }
示例#9
0
        private void CreateByNode(Node node, STSkeleton skeleton, string ParentArmatureName,
                                  short SmoothIndex, short RigidIndex, bool IsRoot, ref Assimp.Matrix4x4 rootTransform)
        {
            Matrix4x4 trafo        = node.Transform;
            Matrix4x4 world        = trafo * rootTransform;
            var       transformMat = AssimpHelper.TKMatrix(world);

            int matchedBoneIndex = skeleton.bones.FindIndex(item => item.Name == node.Name);

            if (matchedBoneIndex < 0)
            {
                tempBoneNodes.Add(node);

                STBone bone = new STBone();
                bone.skeletonParent = skeleton;
                bone.RotationType   = STBone.BoneRotationType.Euler;
                skeleton.bones.Add(bone);

                if (DaeHelper.IDMapToName.ContainsKey(node.Name))
                {
                    bone.Text = DaeHelper.IDMapToName[node.Name];
                }
                else
                {
                    bone.Text = node.Name;
                }

                bone.SmoothMatrixIndex = (short)skeleton.bones.IndexOf(bone);
                bone.RigidMatrixIndex  = -1; //Todo calculate these

                if (IsRoot)
                {
                    bone.parentIndex = -1;

                    if (RotateSkeleton)
                    {
                        transformMat = AssimpHelper.TKMatrix(world * Matrix4x4.FromRotationX(MathHelper.DegreesToRadians(RotateSkeletonAmount)));
                    }
                    else
                    {
                        transformMat = AssimpHelper.TKMatrix(world);
                    }
                }
                else
                {
                    if (tempBoneNodes.Contains(node.Parent))
                    {
                        bone.parentIndex = tempBoneNodes.IndexOf(node.Parent);
                    }
                }


                var scale    = transformMat.ExtractScale();
                var rotation = transformMat.ExtractRotation();
                var position = transformMat.ExtractTranslation();

                STConsole.WriteLine($"-".Repeat(30));
                STConsole.WriteLine($"Processing Bone {bone.Text}");
                STConsole.WriteLine($"scale {scale}");
                STConsole.WriteLine($"rotation {rotation}");
                STConsole.WriteLine($"position {position}");
                STConsole.WriteLine($"-".Repeat(30));

                bone.FromTransform(transformMat);
            }
            else
            {
                STConsole.WriteLine($"Duplicate node name found for bone {node.Name}!", Color.Red);
            }

            var identity = Matrix4x4.Identity;

            foreach (Node child in node.Children)
            {
                CreateByNode(child, skeleton, ParentArmatureName, SmoothIndex, RigidIndex, false, ref identity);
            }
        }
示例#10
0
        public void update(bool reset = false)
        {
            Updated = true;
            List <STBone> nodesToProcess = new List <STBone>();

            // Add all root nodes from the VBN
            foreach (STBone b in bones)
            {
                if (b.parentIndex == -1)
                {
                    nodesToProcess.Add(b);
                }
            }

            // some special processing for the root bones before we start
            foreach (STBone b in nodesToProcess)
            {
                b.Transform = Matrix4.CreateScale(b.sca) * Matrix4.CreateFromQuaternion(b.rot) * Matrix4.CreateTranslation(b.pos);

                // scale down the model in its entirety only when mid-animation (i.e. reset == false)
                if (!reset)
                {
                    b.Transform *= Matrix4.CreateScale(1);
                }
            }

            // Process as a tree from the root node's children and beyond. These
            // all use the same processing, unlike the root nodes.
            int numRootNodes = nodesToProcess.Count;

            for (int i = 0; i < numRootNodes; i++)
            {
                nodesToProcess.AddRange(nodesToProcess[0].GetChildren());
                nodesToProcess.RemoveAt(0);
            }
            while (nodesToProcess.Count > 0)
            {
                // DFS
                STBone Bone = nodesToProcess[0];
                nodesToProcess.RemoveAt(0);
                nodesToProcess.AddRange(Bone.GetChildren());

                // Process this node
                Bone.Transform = Matrix4.CreateScale(Bone.sca) * Matrix4.CreateFromQuaternion(Bone.rot) * Matrix4.CreateTranslation(Bone.pos);
                if (Bone.parentIndex != -1)
                {
                    if (Bone.UseSegmentScaleCompensate && Bone.Parent != null &&
                        Bone.Parent is STBone)
                    {
                        Bone.Transform *= Matrix4.CreateScale(
                            1f / ((STBone)Bone.Parent).GetScale().X,
                            1f / ((STBone)Bone.Parent).GetScale().Y,
                            1f / ((STBone)Bone.Parent).GetScale().Z);

                        Bone.Transform *= ((STBone)Bone.Parent).Transform;
                    }
                    else
                    {
                        Bone.Transform = Bone.Transform * ((STBone)Bone.Parent).Transform;
                    }
                }
            }
        }
示例#11
0
 public static Syroot.Maths.Matrix3x4 CalculateInverseMatrix(STBone bone)
 {
     return(FromAssimpMatrix(AssimpCalculateInverseMatrix(bone)));
 }
示例#12
0
 public static Matrix4x4 GetBoneMatrix(STBone bone)
 {
     return(AssimpFromTKMatrix(bone.Transform));
 }
示例#13
0
        private static SELib.SEModelBone SaveBone(STBone bone)
        {
            var seBone = new SELib.SEModelBone();

            return(seBone);
        }