public void RotationMatrix_ToQuaternion_VsSystemNumerics()
        {
            RotationMatrix m;
            Quaternion     q;
            SysMatrix44    m44, m44bis;
            SysQuat        sq;
            Vector         vecX, vecY;
            int            dir;

            int runs = 500;

            for (var i = 0; i < runs; i++)
            {
                if (i < 0.5 * runs)
                {
                    vecX = Vector.RandomFromDoubles(-100, 100);
                    vecY = Vector.RandomFromDoubles(-100, 100);
                }
                else
                {
                    vecX = Vector.RandomFromInts(-1, 1);
                    vecY = Vector.RandomFromInts(-1, 1);
                }

                dir = Vector.CompareDirections(vecX, vecY);
                m   = new RotationMatrix(vecX, vecY);
                q   = m.ToQuaternion();

                Trace.WriteLine("");
                Trace.WriteLine(vecX + " " + vecY + " dir:" + dir);
                Trace.WriteLine(m);
                Trace.WriteLine(q);

                // Use the matrix's orthogonal values to create a M44 matrix with just rotation values:
                m44 = new SysMatrix44((float)m.m00, (float)m.m01, (float)m.m02, 0,
                                      (float)m.m10, (float)m.m11, (float)m.m12, 0,
                                      (float)m.m20, (float)m.m21, (float)m.m22, 0,
                                      0, 0, 0, 1);
                m44    = SysMatrix44.Transpose(m44); // Numerics.Matrix4x4 uses a transposed convention, meaning the translation vector is horizontal in m41-42-43 instead of vertical in m14-24-34
                sq     = SysQuat.CreateFromRotationMatrix(m44);
                m44bis = SysMatrix44.CreateFromQuaternion(sq);
                Trace.WriteLine(m44);
                Trace.WriteLine(sq);
                Trace.WriteLine(m44bis);

                Assert.IsTrue(q.IsEquivalent(new Quaternion(sq.W, sq.X, sq.Y, sq.Z)), "Quaternions are not equivalent!");
            }
        }
        private static void ProcessNode(
            ImportedModelContainer modelContainer,
            Scene scene, Node actNode, SceneObject?actParent,
            ObjectTreeBoundingBoxCalculator boundingBoxCalc)
        {
            SceneObject?nextParent = null;

            if (actNode.HasMeshes)
            {
                var actTransform = Matrix4x4.Transpose(AssimpHelper.MatrixFromAssimp(actNode.Transform));
                boundingBoxCalc.PushTransform(ref actTransform);

                // Count vertices
                var fullVertexCount = 0;
                foreach (var actMeshId in actNode.MeshIndices)
                {
                    var actMesh = scene.Meshes[actMeshId];
                    fullVertexCount += actMesh.VertexCount;
                }

                // This one has true geometry
                var meshCount    = actNode.MeshCount;
                var newGeometry  = new Geometry(fullVertexCount);
                var materialKeys = new NamedOrGenericKey[meshCount];
                for (var meshIndex = 0; meshIndex < meshCount; meshIndex++)
                {
                    var actMeshId     = actNode.MeshIndices[meshIndex];
                    var actBaseVertex = newGeometry.CountVertices;
                    var actMesh       = scene.Meshes[actMeshId];

                    List <Color4D>?vertexColors = null;
                    if (actMesh.HasVertexColors(0))
                    {
                        vertexColors = actMesh.VertexColorChannels[0];
                    }

                    List <Vector3D>?textureCoords1 = null;
                    if (actMesh.TextureCoordinateChannelCount > 0)
                    {
                        textureCoords1 = actMesh.TextureCoordinateChannels[0];
                    }

                    // Create all vertices
                    var vertexCount = actMesh.VertexCount;
                    for (var actVertexId = 0; actVertexId < vertexCount; actVertexId++)
                    {
                        var     vertexIndex = newGeometry.AddVertex();
                        ref var newVertex   = ref newGeometry.GetVertexBasicRef(vertexIndex);

                        newVertex.Position = AssimpHelper.Vector3FromAssimp(actMesh.Vertices[actVertexId]);
                        if (actMesh.HasNormals)
                        {
                            newVertex.Normal = AssimpHelper.Vector3FromAssimp(actMesh.Normals[actVertexId]);
                        }
                        if (vertexColors != null)
                        {
                            newVertex.Color = AssimpHelper.Color4FromAssimp(vertexColors[actVertexId]);
                        }
                        if (textureCoords1 != null)
                        {
                            newVertex.TexCoord1 = AssimpHelper.Vector2FromAssimp(textureCoords1[actVertexId]);
                        }

                        boundingBoxCalc.AddCoordinate(ref newVertex.Position);
                    }

                    // Create all faces
                    var newSurface = newGeometry.CreateSurface(actMesh.FaceCount * 3);
                    foreach (var actFace in actMesh.Faces)
                    {
                        if (actFace.IndexCount != 3)
                        {
                            continue;
                        }

                        newSurface.AddTriangle(
                            actBaseVertex + actFace.Indices[0],
                            actBaseVertex + actFace.Indices[1],
                            actBaseVertex + actFace.Indices[2]);
                    }

                    materialKeys[meshIndex] = modelContainer.GetResourceKey("Material", actMesh.MaterialIndex.ToString());
                }

                var geometryKey = modelContainer.GetResourceKey("Geometry", actNode.Name);
                modelContainer.AddResource(new ImportedResourceInfo(
                                               modelContainer.GetResourceKey("Geometry", actNode.Name),
                                               _ => new GeometryResource(newGeometry)));

                var newMesh = new Mesh(geometryKey, materialKeys);
                newMesh.CustomTransform    = actTransform;
                newMesh.TransformationType = SpacialTransformationType.CustomTransform;
                newMesh.Name = actNode.Name;
                modelContainer.AddObject(newMesh);
                nextParent = newMesh;

                if (actParent != null)
                {
                    modelContainer.AddParentChildRelationship(new ParentChildRelationship(actParent, newMesh));
                }
            }
 public Matrix4x4 NumericsTranspose()
 {
     return(Matrix4x4.Transpose(numericsMat1));
 }