Пример #1
0
        public static OpenTK.Matrix4 TKMatrix2(Assimp.Matrix4x4 matOut)
        {
            var matIn = new OpenTK.Matrix4();

            matOut.A1 = matIn.M11;
            matOut.B1 = matIn.M12;
            matOut.C1 = matIn.M13;
            matOut.D1 = matIn.M14;

            //Y
            matOut.A2 = matIn.M21;
            matOut.B2 = matIn.M22;
            matOut.C2 = matIn.M23;
            matOut.D2 = matIn.M24;

            //Z
            matOut.A3 = matIn.M31;
            matOut.B3 = matIn.M32;
            matOut.C3 = matIn.M33;
            matOut.D3 = matIn.M34;

            //Translation
            matOut.A4 = matIn.M41;
            matOut.B4 = matIn.M42;
            matOut.C4 = matIn.M43;
            matOut.D4 = matIn.M44;

            return(matIn);
        }
Пример #2
0
        public static void FromNumerics(this SN.Matrix4x4 matIn, out Assimp.Matrix4x4 matOut)
        {
            //Numerics matrix are row vector, so X,Y,Z axes are rows 1-3 and 4th row is translation.
            //Rows => Columns to make it compatible with assimp

            //X
            matOut.A1 = matIn.M11;
            matOut.B1 = matIn.M12;
            matOut.C1 = matIn.M13;
            matOut.D1 = matIn.M14;

            //Y
            matOut.A2 = matIn.M21;
            matOut.B2 = matIn.M22;
            matOut.C2 = matIn.M23;
            matOut.D2 = matIn.M24;

            //Z
            matOut.A3 = matIn.M31;
            matOut.B3 = matIn.M32;
            matOut.C3 = matIn.M33;
            matOut.D3 = matIn.M34;

            //Translation
            matOut.A4 = matIn.M41;
            matOut.B4 = matIn.M42;
            matOut.C4 = matIn.M43;
            matOut.D4 = matIn.M44;
        }
Пример #3
0
 public static Matrix4x4 ToNumericsTransposed(this Ai.Matrix4x4 value)
 {
     return(new Matrix4x4(value.A1, value.B1, value.C1, value.D1,
                          value.A2, value.B2, value.C2, value.D2,
                          value.A3, value.B3, value.C3, value.D3,
                          value.A4, value.B4, value.C4, value.D4));
 }
        private void UpdateChannel(double time, Node node, aiMatrix4x4 parentTransform)
        {
            aiMatrix4x4 nodeTransformation = node.Transform;

            if (GetChannel(node, out NodeAnimationChannel channel))
            {
                aiMatrix4x4 scale       = InterpolateScale(time, channel);
                aiMatrix4x4 rotation    = InterpolateRotation(time, channel);
                aiMatrix4x4 translation = InterpolateTranslation(time, channel);

                nodeTransformation = scale * rotation * translation;
            }

            if (_boneIDsByName.TryGetValue(node.Name, out uint boneID))
            {
                aiMatrix4x4 m = _firstMesh.Bones[(int)boneID].OffsetMatrix
                                * nodeTransformation
                                * parentTransform
                                * _rootNodeInverseTransform;
                _boneTransformations[boneID] = m;
            }

            foreach (Node childNode in node.Children)
            {
                UpdateChannel(time, childNode, nodeTransformation * parentTransform);
            }
        }
Пример #5
0
        private void TransformNode(double time, Node aiNode, mat4 parentTransform)
        {
            var name          = aiNode.Name;
            var nodeTransform = aiNode.Transform.ToMat4();

            var animationChannel = animation.NodeAnimationChannels.SingleOrDefault(m => m.NodeName == name);

            if (animationChannel != null)
            {
                var scaling  = InterpolatedHelper.CalcInterpolatedScaling((float)time, animationChannel);
                var scalingM = mat4.Scale(scaling.X, scaling.Y, scaling.Z);

                var rotation  = InterpolatedHelper.CalcInterpolatedRotation((float)time, animationChannel).GetMatrix();
                var rotationM = new Assimp.Matrix4x4(rotation).ToMat4();

                var translation  = InterpolatedHelper.CalcInterpolatedPosition((float)time, animationChannel);
                var translationM = mat4.Translate(translation.X, translation.Y, translation.Z);

                nodeTransform = translationM * rotationM * scalingM;
            }

            var globalTransform = parentTransform * nodeTransform;

            if (allBones.ContainsKey(name))
            {
                allBones[name].finalTransformation = globalTransform * allBones[name].Bone.OffsetMatrix.ToMat4();
            }

            for (int i = 0; i < aiNode.ChildCount; i++)
            {
                TransformNode(time, aiNode.Children[i], globalTransform);
            }
        }
Пример #6
0
 private static bool NearlyEquals(Ai.Matrix4x4 left, Ai.Matrix4x4 right)
 {
     return(NearlyEquals(left.A1, right.A1) && NearlyEquals(left.A2, right.A2) && NearlyEquals(left.A3, right.A3) && NearlyEquals(left.A4, right.A4) &&
            NearlyEquals(left.B1, right.B1) && NearlyEquals(left.B2, right.B2) && NearlyEquals(left.B3, right.B3) && NearlyEquals(left.B4, right.B4) &&
            NearlyEquals(left.C1, right.C1) && NearlyEquals(left.C2, right.C2) && NearlyEquals(left.C3, right.C3) && NearlyEquals(left.C4, right.C4) &&
            NearlyEquals(left.D1, right.D1) && NearlyEquals(left.D2, right.D2) && NearlyEquals(left.D3, right.D3) && NearlyEquals(left.D4, right.D4));
 }
Пример #7
0
        public static OpenTK.Matrix4 TKMatrix(Assimp.Matrix4x4 input)
        {
            return(new OpenTK.Matrix4(input.A1, input.B1, input.C1, input.D1,
                                      input.A2, input.B2, input.C2, input.D2,
                                      input.A3, input.B3, input.C3, input.D3,
                                      input.A4, input.B4, input.C4, input.D4));

            /*     return new OpenTK.Matrix4()
             *   {
             *       M11 = input.A1,
             *       M12 = input.A2,
             *       M13 = input.A3,
             *       M14 = input.A4,
             *       M21 = input.B1,
             *       M22 = input.B2,
             *       M23 = input.B3,
             *       M24 = input.B4,
             *       M31 = input.C1,
             *       M32 = input.C2,
             *       M33 = input.C3,
             *       M34 = input.C4,
             *       M41 = input.D1,
             *       M42 = input.D2,
             *       M43 = input.D3,
             *       M44 = input.D4
             *   };*/
        }
Пример #8
0
        // QSRT INFO TO STRING
        private static string QsrtInfoToString(this Assimp.Matrix4x4 m, string tabspaces, bool showQuaternions)
        {
            var    checkdeterminatevalid = Math.Abs(m.Determinant()) < 1e-5;
            string str = "";

            // this can fail if the determinante is invalid.
            if (checkdeterminatevalid == false)
            {
                Vector3D          scale;
                Assimp.Quaternion rot;
                Vector3D          rotAngles;
                Vector3D          trans;
                m.Decompose(out scale, out rot, out trans);
                QuatToEulerXyz(ref rot, out rotAngles);
                var rotDeg = rotAngles * (float)(180d / Math.PI);
                int padamt = 20;
                if (showQuaternions)
                {
                    str += "\n" + tabspaces + "    " + "As Quaternion     ".PadRight(padamt) + rot.ToStringTrimed();
                }
                str += "\n" + tabspaces + "    " + "Translation          ".PadRight(padamt) + trans.ToStringTrimed();
                if (scale.X != scale.Y || scale.Y != scale.Z || scale.Z != scale.X)
                {
                    str += "\n" + tabspaces + "    " + "Scale                  ".PadRight(padamt) + scale.ToStringTrimed();
                }
                else
                {
                    str += "\n" + tabspaces + "    " + "Scale                  ".PadRight(padamt) + scale.X.ToString(); //scale.X.ToStringTrimed();
                }
                str += "\n" + tabspaces + "    " + "Rotation degrees  ".PadRight(padamt) + rotDeg.ToStringTrimed();     // + "   radians: " + rotAngles.ToStringTrimed();
                str += "\n";
            }
            return(str);
        }
Пример #9
0
 public static System.Numerics.Matrix4x4 ToNumerics(this Matrix4x4 matrix)
 {
     return(new System.Numerics.Matrix4x4(matrix.A1, matrix.B1, matrix.C1, matrix.D1,
                                          matrix.A2, matrix.B2, matrix.C2, matrix.D2,
                                          matrix.A3, matrix.B3, matrix.C3, matrix.D3,
                                          matrix.A4, matrix.B4, matrix.C4, matrix.D4));
 }
Пример #10
0
 public static OpenTK.Matrix4d TKMatrixd(Assimp.Matrix4x4 input)
 {
     return(new OpenTK.Matrix4d(input.A1, input.B1, input.C1, input.D1,
                                input.A2, input.B2, input.C2, input.D2,
                                input.A3, input.B3, input.C3, input.D3,
                                input.A4, input.B4, input.C4, input.D4));
 }
Пример #11
0
 public static void ToNumerics(this Assimp.Matrix4x4 matIn, out SN.Matrix4x4 matOut)
 {
     //Assimp matrices are column vector, so X,Y,Z axes are columns 1-3 and 4th column is translation.
     //Columns => Rows to make it compatible with numerics
     matOut = new System.Numerics.Matrix4x4(matIn.A1, matIn.B1, matIn.C1, matIn.D1,  //X
                                            matIn.A2, matIn.B2, matIn.C2, matIn.D2,  //Y
                                            matIn.A3, matIn.B3, matIn.C3, matIn.D3,  //Z
                                            matIn.A4, matIn.B4, matIn.C4, matIn.D4); //Translation
 }
Пример #12
0
 public static Matrix ToMatrix(this Assimp.Matrix4x4 v)
 {
     return(Matrix.Transpose(new Matrix(
                                 v.A1, v.A2, v.A3, v.A4,
                                 v.B1, v.B2, v.B3, v.B4,
                                 v.C1, v.C2, v.C3, v.C4,
                                 v.D1, v.D2, v.D3, v.D4
                                 )));
 }
        private Matrix4 ConvertToMatrix4(Assimp.Matrix4x4 m)
        {
            var row1 = new Vector4(m.A1, m.A2, m.A3, m.A4);
            var row2 = new Vector4(m.B1, m.B2, m.B3, m.B4);
            var row3 = new Vector4(m.C1, m.C2, m.C3, m.C4);
            var row4 = new Vector4(m.D1, m.D2, m.D3, m.D4);
            var m4   = new Matrix4(row1, row2, row3, row4);

            return(m4);
        }
Пример #14
0
        // T O   M G  (convert for use with MonoGame) - MATRIX
        public static Matrix ToMg(this Assimp.Matrix4x4 ma)
        {
            Matrix m = Matrix.Identity;

            m.M11 = TestVal(ma.A1); m.M12 = TestVal(ma.A2); m.M13 = TestVal(ma.A3); m.M14 = TestVal(ma.A4);
            m.M21 = TestVal(ma.B1); m.M22 = TestVal(ma.B2); m.M23 = TestVal(ma.B3); m.M24 = TestVal(ma.B4);
            m.M31 = TestVal(ma.C1); m.M32 = TestVal(ma.C2); m.M33 = TestVal(ma.C3); m.M34 = TestVal(ma.C4);
            m.M41 = TestVal(ma.D1); m.M42 = TestVal(ma.D2); m.M43 = TestVal(ma.D3); m.M44 = TestVal(ma.D4);
            return(m);
        }
Пример #15
0
        static NumMatrix4x4 ConvertMatrix(AssMatrix4x4 Mat)
        {
            return(NumMatrix4x4.Transpose(*(NumMatrix4x4 *)&Mat));

            /*Mat.Decompose(out Vector3D Scaling, out AssQuaternion Rotation, out Vector3D Translation);
             *
             * NumMatrix4x4 Rot = NumMatrix4x4.CreateFromQuaternion(ConvertQuat(Rotation));
             * NumMatrix4x4 Pos = NumMatrix4x4.CreateTranslation(ConvertVec(Translation));
             * NumMatrix4x4 Scl = NumMatrix4x4.CreateScale(ConvertVec(Scaling));
             * return Scl * Rot * Pos;
             * //*/
        }
Пример #16
0
        private static Matrix4x4 GetMatrix4x4FromAiMatrix4x4(Ai.Matrix4x4 matrix, bool transpose = true)
        {
            if (transpose)
            {
                return(new Matrix4x4(matrix.A1, matrix.B1, matrix.C1, matrix.D1,
                                     matrix.A2, matrix.B2, matrix.C2, matrix.D2,
                                     matrix.A3, matrix.B3, matrix.C3, matrix.D3,
                                     matrix.A4, matrix.B4, matrix.C4, matrix.D4));
            }

            else
            {
                return(new Matrix4x4(matrix.A1, matrix.A2, matrix.A3, matrix.A4,
                                     matrix.B1, matrix.B2, matrix.B3, matrix.B4,
                                     matrix.C1, matrix.C2, matrix.C3, matrix.C4,
                                     matrix.D1, matrix.D2, matrix.D3, matrix.D4));
            }
        }
Пример #17
0
 /// <summary>
 /// Transform a direction vector by the given Matrix. Note: this is for assimp
 /// matrix which is row major.
 /// </summary>
 /// <param name="vec">The vector to transform</param>
 /// <param name="mat">The desired transformation</param>
 /// <param name="result">The transformed vector</param>
 public static ai.Vector3D eTransformVector(this ai.Matrix4x4 mat, ai.Vector3D vec)
 {
     return(new ai.Vector3D
     {
         X = vec.X * mat.A1
             + vec.Y * mat.B1
             + vec.Z * mat.C1
             + mat.A4,
         Y = vec.X * mat.A2
             + vec.Y * mat.B2
             + vec.Z * mat.C2
             + mat.B4,
         Z = vec.X * mat.A3
             + vec.Y * mat.B3
             + vec.Z * mat.C3
             + mat.C4
     });
 }
 /// <summary>
 /// Converts an Assimp <see cref="AssimpMatrix4x4"/> to a numerics <see cref="NumericsMatrix4x4"/>.
 /// </summary>
 /// <param name="input">The input <see cref="AssimpMatrix4x4"/>.</param>
 /// <returns>The output <see cref="NumericsMatrix4x4"/>.</returns>
 private NumericsMatrix4x4 GetNumericsMatrix4x4(AssimpMatrix4x4 input)
 {
     return(new NumericsMatrix4x4(input[1, 1],
                                  input[1, 2],
                                  input[1, 3],
                                  input[1, 4],
                                  input[2, 1],
                                  input[2, 2],
                                  input[2, 3],
                                  input[2, 4],
                                  input[3, 1],
                                  input[3, 2],
                                  input[3, 3],
                                  input[3, 4],
                                  input[4, 1],
                                  input[4, 2],
                                  input[4, 3],
                                  input[4, 4]));
 }
Пример #19
0
 static public Matrix MatrixAssimpToXna(Assimp.Matrix4x4 matrix)
 {
     return(new Matrix(
                matrix.A1,
                matrix.A2,
                matrix.A3,
                matrix.A4,
                matrix.B1,
                matrix.B2,
                matrix.B3,
                matrix.B4,
                matrix.C1,
                matrix.C2,
                matrix.C3,
                matrix.C4,
                matrix.D1,
                matrix.D2,
                matrix.D3,
                matrix.D4
                ));
 }
Пример #20
0
        public static Assimp.Matrix4x4 convertMatrix(Matrix4 localMat)
        {
            Assimp.Matrix4x4 mat = new Assimp.Matrix4x4();
            mat.A1 = localMat.Column0.X;
            mat.A2 = localMat.Column0.Y;
            mat.A3 = localMat.Column0.Z;
            mat.A4 = localMat.Column0.W;
            mat.B1 = localMat.Column1.X;
            mat.B2 = localMat.Column1.Y;
            mat.B3 = localMat.Column1.Z;
            mat.B4 = localMat.Column1.W;
            mat.C1 = localMat.Column2.X;
            mat.C2 = localMat.Column2.Y;
            mat.C3 = localMat.Column2.Z;
            mat.C4 = localMat.Column2.W;
            mat.D1 = localMat.Column3.X;
            mat.D2 = localMat.Column3.Y;
            mat.D3 = localMat.Column3.Z;
            mat.D4 = localMat.Column3.W;

            return(mat);
        }
Пример #21
0
        /// <summary>
        /// internal.
        /// </summary>
        internal static Matrix ConvertTransform(Assimp.Matrix4x4 mat)
        {
            Matrix Result = new Matrix();

            Result.a00 = mat.A1;
            Result.a01 = mat.A2;
            Result.a02 = mat.A3;
            Result.a03 = mat.A4;
            Result.a10 = mat.B1;
            Result.a11 = mat.B2;
            Result.a12 = mat.B3;
            Result.a13 = mat.B4;
            Result.a20 = mat.C1;
            Result.a21 = mat.C2;
            Result.a22 = mat.C3;
            Result.a23 = mat.C4;
            Result.a30 = mat.D1;
            Result.a31 = mat.D2;
            Result.a32 = mat.D3;
            Result.a33 = mat.D4;
            return(Result);
        }
Пример #22
0
 /// <summary>
 /// Convert 4x4 Assimp matrix to OpenTK matrix.
 /// Will be a very useful function becasue Assimp
 /// matrices are very limited.
 /// </summary>
 /// <param name="m"></param>
 /// <returns></returns>
 public static tk.Matrix4 eToOpenTK(this ai.Matrix4x4 m)
 {
     return(new tk.Matrix4
     {
         M11 = m.A1,
         M12 = m.B1,
         M13 = m.C1,
         M14 = m.D1,
         M21 = m.A2,
         M22 = m.B2,
         M23 = m.C2,
         M24 = m.D2,
         M31 = m.A3,
         M32 = m.B3,
         M33 = m.C3,
         M34 = m.D3,
         M41 = m.A4,
         M42 = m.B4,
         M43 = m.C4,
         M44 = m.D4
     });
 }
Пример #23
0
        public static Syroot.Maths.Matrix3x4 FromAssimpMatrix(Assimp.Matrix4x4 mat)
        {
            var mat4 = new Syroot.Maths.Matrix3x4();

            mat4.M11 = mat.A1;
            mat4.M12 = mat.A2;
            mat4.M13 = mat.A3;
            mat4.M14 = mat.A4;
            mat4.M21 = mat.B1;
            mat4.M22 = mat.B2;
            mat4.M23 = mat.B3;
            mat4.M24 = mat.B4;
            mat4.M31 = mat.C1;
            mat4.M32 = mat.C2;
            mat4.M33 = mat.C3;
            mat4.M34 = mat.C4;

            /*  mat4.M41 = mat.D1;
             * mat4.M42 = mat.D2;
             * mat4.M43 = mat.D3;
             * mat4.M44 = mat.D4;*/

            return(mat4);
        }
Пример #24
0
        private void CreateByNode(Node node, STSkeleton skeleton, 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;
                skeleton.bones.Add(bone);

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

                STConsole.WriteLine($"-".Repeat(30));
                STConsole.WriteLine($"Processing Bone {bone.Text}");
                STConsole.WriteLine($"SmoothMatrixIndex {bone.SmoothMatrixIndex}");
                STConsole.WriteLine($"RigidMatrixIndex {bone.RigidMatrixIndex}");
                STConsole.WriteLine($"Transform Matrix {transformMat}");
                STConsole.WriteLine($"-".Repeat(30));

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


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

                var rotEular = AssimpHelper.ToEular(rotation);

                bone.position = new float[] { position.X, position.Y, position.Z };
                bone.scale    = new float[] { scale.X, scale.Y, scale.Z };
                bone.rotation = new float[] { rotEular.X, rotEular.Y, rotEular.Z, 0 };
            }
            else
            {
                STConsole.WriteLine($"Duplicate node name found for bone {node.Name}!", Color.Red);
            }

            foreach (Node child in node.Children)
            {
                CreateByNode(child, skeleton, SmoothIndex, RigidIndex, false, ref rootTransform);
            }
        }
Пример #25
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);
            }
        }
Пример #26
0
 public static Matrix4x4 ToNumerics(this Ai.Matrix4x4 value) =>
 new Matrix4x4(value.A1, value.A2, value.A3, value.A4,
               value.B1, value.B2, value.B3, value.B4,
               value.C1, value.C2, value.C3, value.C4,
               value.D1, value.D2, value.D3, value.D4);
Пример #27
0
        public unsafe override ProcessedModel ProcessT(Stream stream, string extension)
        {
            AssimpContext ac    = new AssimpContext();
            Scene         scene = ac.ImportFileFromStream(
                stream,
                PostProcessSteps.FlipWindingOrder | PostProcessSteps.GenerateNormals | PostProcessSteps.FlipUVs,
                extension);
            aiMatrix4x4 rootNodeInverseTransform = scene.RootNode.Transform;

            rootNodeInverseTransform.Inverse();

            List <ProcessedMeshPart>  parts      = new List <ProcessedMeshPart>();
            List <ProcessedAnimation> animations = new List <ProcessedAnimation>();

            HashSet <string> encounteredNames = new HashSet <string>();

            for (int meshIndex = 0; meshIndex < scene.MeshCount; meshIndex++)
            {
                Mesh   mesh     = scene.Meshes[meshIndex];
                string meshName = mesh.Name;
                if (string.IsNullOrEmpty(meshName))
                {
                    meshName = $"mesh_{meshIndex}";
                }
                int counter = 1;
                while (!encounteredNames.Add(meshName))
                {
                    meshName = mesh.Name + "_" + counter.ToString();
                    counter += 1;
                }
                int vertexCount = mesh.VertexCount;

                int positionOffset    = 0;
                int normalOffset      = 12;
                int texCoordsOffset   = -1;
                int boneWeightOffset  = -1;
                int boneIndicesOffset = -1;

                List <VertexElementDescription> elementDescs = new List <VertexElementDescription>();
                elementDescs.Add(new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float3));
                elementDescs.Add(new VertexElementDescription("Normal", VertexElementSemantic.Normal, VertexElementFormat.Float3));
                normalOffset = 12;

                int vertexSize = 24;

                bool hasTexCoords = mesh.HasTextureCoords(0);
                elementDescs.Add(new VertexElementDescription("TexCoords", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2));
                texCoordsOffset = vertexSize;
                vertexSize     += 8;

                bool hasBones = mesh.HasBones;
                if (hasBones)
                {
                    elementDescs.Add(new VertexElementDescription("BoneWeights", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float4));
                    elementDescs.Add(new VertexElementDescription("BoneIndices", VertexElementSemantic.TextureCoordinate, VertexElementFormat.UInt4));

                    boneWeightOffset = vertexSize;
                    vertexSize      += 16;

                    boneIndicesOffset = vertexSize;
                    vertexSize       += 16;
                }

                byte[]            vertexData = new byte[vertexCount * vertexSize];
                VertexDataBuilder builder    = new VertexDataBuilder(vertexData, vertexSize);
                Vector3           min        = vertexCount > 0 ? mesh.Vertices[0].ToSystemVector3() : Vector3.Zero;
                Vector3           max        = vertexCount > 0 ? mesh.Vertices[0].ToSystemVector3() : Vector3.Zero;

                for (int i = 0; i < vertexCount; i++)
                {
                    Vector3 position = mesh.Vertices[i].ToSystemVector3();
                    min = Vector3.Min(min, position);
                    max = Vector3.Max(max, position);

                    builder.WriteVertexElement(
                        i,
                        positionOffset,
                        position);

                    Vector3 normal = mesh.Normals[i].ToSystemVector3();
                    builder.WriteVertexElement(i, normalOffset, normal);

                    if (mesh.HasTextureCoords(0))
                    {
                        builder.WriteVertexElement(
                            i,
                            texCoordsOffset,
                            new Vector2(mesh.TextureCoordinateChannels[0][i].X, mesh.TextureCoordinateChannels[0][i].Y));
                    }
                    else
                    {
                        builder.WriteVertexElement(
                            i,
                            texCoordsOffset,
                            new Vector2());
                    }
                }

                List <int> indices = new List <int>();
                foreach (Face face in mesh.Faces)
                {
                    if (face.IndexCount == 3)
                    {
                        indices.Add(face.Indices[0]);
                        indices.Add(face.Indices[1]);
                        indices.Add(face.Indices[2]);
                    }
                }

                Dictionary <string, uint>   boneIDsByName = new Dictionary <string, uint>();
                System.Numerics.Matrix4x4[] boneOffsets   = new System.Numerics.Matrix4x4[mesh.BoneCount];

                if (hasBones)
                {
                    Dictionary <int, int> assignedBoneWeights = new Dictionary <int, int>();
                    for (uint boneID = 0; boneID < mesh.BoneCount; boneID++)
                    {
                        Bone   bone     = mesh.Bones[(int)boneID];
                        string boneName = bone.Name;
                        int    suffix   = 1;
                        while (boneIDsByName.ContainsKey(boneName))
                        {
                            boneName = bone.Name + "_" + suffix.ToString();
                            suffix  += 1;
                        }

                        boneIDsByName.Add(boneName, boneID);
                        foreach (VertexWeight weight in bone.VertexWeights)
                        {
                            int relativeBoneIndex = GetAndIncrementRelativeBoneIndex(assignedBoneWeights, weight.VertexID);
                            builder.WriteVertexElement(weight.VertexID, boneIndicesOffset + (relativeBoneIndex * sizeof(uint)), boneID);
                            builder.WriteVertexElement(weight.VertexID, boneWeightOffset + (relativeBoneIndex * sizeof(float)), weight.Weight);
                        }

                        System.Numerics.Matrix4x4 offsetMat = bone.OffsetMatrix.ToSystemMatrixTransposed();
                        System.Numerics.Matrix4x4.Decompose(offsetMat, out var scale, out var rot, out var trans);
                        offsetMat = System.Numerics.Matrix4x4.CreateScale(scale)
                                    * System.Numerics.Matrix4x4.CreateFromQuaternion(rot)
                                    * System.Numerics.Matrix4x4.CreateTranslation(trans);

                        boneOffsets[boneID] = offsetMat;
                    }
                }
                builder.FreeGCHandle();

                uint indexCount = (uint)indices.Count;

                int[]  int32Indices = indices.ToArray();
                byte[] indexData    = new byte[indices.Count * sizeof(uint)];
                fixed(byte *indexDataPtr = indexData)
                {
                    fixed(int *int32Ptr = int32Indices)
                    {
                        Buffer.MemoryCopy(int32Ptr, indexDataPtr, indexData.Length, indexData.Length);
                    }
                }

                ProcessedMeshPart part = new ProcessedMeshPart(
                    vertexData,
                    elementDescs.ToArray(),
                    indexData,
                    IndexFormat.UInt32,
                    (uint)indices.Count,
                    boneIDsByName,
                    boneOffsets);
                parts.Add(part);
            }

            // Nodes
            Node rootNode = scene.RootNode;
            List <ProcessedNode> processedNodes = new List <ProcessedNode>();

            ConvertNode(rootNode, -1, processedNodes);

            ProcessedNodeSet nodes = new ProcessedNodeSet(processedNodes.ToArray(), 0, rootNodeInverseTransform.ToSystemMatrixTransposed());

            for (int animIndex = 0; animIndex < scene.AnimationCount; animIndex++)
            {
                Animation animation = scene.Animations[animIndex];
                Dictionary <string, ProcessedAnimationChannel> channels = new Dictionary <string, ProcessedAnimationChannel>();
                for (int channelIndex = 0; channelIndex < animation.NodeAnimationChannelCount; channelIndex++)
                {
                    NodeAnimationChannel nac = animation.NodeAnimationChannels[channelIndex];
                    channels[nac.NodeName] = ConvertChannel(nac);
                }

                string baseAnimName = animation.Name;
                if (string.IsNullOrEmpty(baseAnimName))
                {
                    baseAnimName = "anim_" + animIndex;
                }

                string animationName = baseAnimName;


                int counter = 1;
                while (!encounteredNames.Add(animationName))
                {
                    animationName = baseAnimName + "_" + counter.ToString();
                    counter      += 1;
                }
            }

            return(new ProcessedModel()
            {
                MeshParts = parts.ToArray(),
                Animations = animations.ToArray(),
                Nodes = nodes
            });
        }
Пример #28
0
 public static unsafe System.Numerics.Matrix4x4 ToSystemMatrixTransposed(this aiMatrix4x4 mat)
 {
     return(System.Numerics.Matrix4x4.Transpose(Unsafe.Read <System.Numerics.Matrix4x4>(&mat)));
 }
Пример #29
0
        private Mesh ProcessMesh(Assimp.Mesh mesh, Assimp.Scene scene, Assimp.Matrix4x4 transform)
        {
            List <Vertex>  vertices = new List <Vertex>();
            List <uint>    indices  = new List <uint>();
            List <Texture> textures = new List <Texture>();

            for (int i = 0; i < mesh.VertexCount; ++i)
            {
                var vertex = new Vertex()
                {
                    Position = new Vector3(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z),
                    Normal   = new Vector3(mesh.Normals[i].X, mesh.Normals[i].Y, mesh.Normals[i].Z)
                };

                if (mesh.HasTextureCoords(0))
                {
                    var texCoords = new Vector2(mesh.TextureCoordinateChannels[0][i].X, mesh.TextureCoordinateChannels[0][i].Y);
                    vertex.TexCoords = texCoords;
                }
                else
                {
                    vertex.TexCoords = new Vector2(0, 0);
                }

                if (mesh.HasTangentBasis)
                {
                    vertex.Tangent   = new Vector3(mesh.Tangents[i].X, mesh.Tangents[i].Y, mesh.Tangents[i].Z);
                    vertex.BiTangent = new Vector3(mesh.BiTangents[i].X, mesh.BiTangents[i].Y, mesh.BiTangents[i].Z);
                }

                vertices.Add(vertex);
            }

            for (int i = 0; i < mesh.FaceCount; ++i)
            {
                var face = mesh.Faces[i];
                for (int f = 0; f < face.IndexCount; ++f)
                {
                    indices.Add((uint)face.Indices[f]);
                }
            }

            if (mesh.MaterialIndex >= 0)
            {
                var material    = scene.Materials[mesh.MaterialIndex];
                var diffuseMaps = LoadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse");
                textures.AddRange(diffuseMaps);

                if (diffuseMaps.Count == 0)
                {
                    textures.Add(Texture.LoadFromData(new[]
                    {
                        (byte)(material.ColorDiffuse.R * 255),
                        (byte)(material.ColorDiffuse.G * 255),
                        (byte)(material.ColorDiffuse.B * 255),
                        (byte)(material.ColorDiffuse.A * 255)
                    }, 1, 1, 4, "texture_diffuse"));
                }

                var specularMaps = LoadMaterialTextures(material, TextureType.Specular, "texture_specular");
                textures.AddRange(specularMaps);

                if (specularMaps.Count == 0)
                {
                    textures.Add(Texture.LoadFromData(new[]
                    {
                        (byte)(material.ColorSpecular.R * 255),
                        (byte)(material.ColorSpecular.G * 255),
                        (byte)(material.ColorSpecular.B * 255),
                        (byte)(material.ColorSpecular.A * 255)
                    }, 1, 1, 4, "texture_specular"));
                }

                var normalMaps = LoadMaterialTextures(material, TextureType.Normals, "texture_normal");
                textures.AddRange(normalMaps);

                var emissiveMaps = LoadMaterialTextures(material, TextureType.Emissive, "texture_emissive");
                textures.AddRange(emissiveMaps);

                if (specularMaps.Count == 0)
                {
                    textures.Add(Texture.LoadFromData(new[]
                    {
                        (byte)(material.ColorEmissive.R * 255),
                        (byte)(material.ColorEmissive.G * 255),
                        (byte)(material.ColorEmissive.B * 255),
                        (byte)(material.ColorEmissive.A * 255)
                    }, 1, 1, 4, "texture_emissive"));
                }

                var unknownMaps = LoadMaterialTextures(material, TextureType.Unknown, "texture_unknown"); // includes roughness
                textures.AddRange(unknownMaps);
            }

            var oglTransform = new System.Numerics.Matrix4x4(
                transform.A1, transform.A2, transform.A3, transform.A4,
                transform.B1, transform.B2, transform.B3, transform.B4,
                transform.C1, transform.C2, transform.C3, transform.C4,
                transform.D1, transform.D2, transform.D3, transform.D4
                );

            return(new Mesh(vertices, indices, textures, oglTransform));
        }
Пример #30
0
 public static Math3d.Matrix4x4 ToMath3D(this Assimp.Matrix4x4 m)
 => new Math3d.Matrix4x4(
     m.A1, m.A2, m.A3, m.A4,
     m.B1, m.B2, m.B3, m.B4,
     m.C1, m.C2, m.C3, m.C4,
     m.D1, m.D2, m.D3, m.D4);