Exemple #1
0
        public FbxConverter(out AssimpSharp.Scene scene, Document doc)
        {
            this.Doc = doc;
            this.NodeNames = new Dictionary<string, bool>();
            this.RenamedNodes = new Dictionary<string, string>();
            this.Result = scene = new AssimpSharp.Scene();

            // animations need to be converted first since this will
            // populate the node_anim_chain_bits map, which is needed
            // to determine which nodes need to be generated.
            ConvertAnimations();
            ConvertRootNode();
            if (doc.Settings.ReadAllMaterials)
            {
                // unfortunately this means we have to evaluate all objects
                foreach(var v in doc.Objects)
                {
                    var ob = v.Value.Get();
                    if (ob == null)
                    {
                        continue;
                    }
                    var mat = ob as Material;
                    if (mat != null)
                    {
                        if (!MaterialsConverted.ContainsKey(mat))
                        {
                            ConvertMaterial(mat, null);
                        }
                    }
                }
            }
            TransferDataToScene();
        }
Exemple #2
0
 public FbxMesh(AssimpSharp.Mesh mesh, AssimpSharp.Material mat, Device device, string path)
 {
     this.device = device;
     this.path = path;
     LoadMesh(mesh);
     LoadMaterial(mat);
 }
Exemple #3
0
 /// <summary>
 /// Constructor for a specific scene to export
 /// </summary>
 public XFileExporter(AssimpSharp.Scene scene, IOSystem iosystem, string path, string file)
 {
     //Properties = Properties;
     IOSystem = iosystem;
     Path = path;
     File = file;
     Scene = scene;
     SceneOwned = false;
     End = "\n";
     WriteFile();
 }
Exemple #4
0
        /// <summary>
        /// Imports the given file into the given scene structure.
        /// See BaseImporter::InternReadFile() for details
        /// </summary>
        public void InternReadFile(string filename, AssimpSharp.Scene scene)
        {
            using (var stream = new FileStream(filename, FileMode.Open))
            {
                Buffer = new byte[stream.Length];
                stream.Read(Buffer, 0, (int)stream.Length);
            }

            var parser = new XFileParser(Buffer);

            CreateDataRepresentationFromImport(scene, parser.GetImportedData());

            if (scene.RootNode== null)
            {
                throw (new NotImplementedException("XFile is ill-formatted - no content imported."));
            }
        }
Exemple #5
0
        /// <summary>
        /// Converts all meshes in the given mesh array. Each mesh is split
        /// up per material, the indices of the generated meshes are stored in
        /// the node structure.
        /// </summary>
        /// <param name="scene">The scene to construct the return data in.</param>
        /// <param name="node">The target node structure that references the constructed meshes.</param>
        /// <param name="meshes">The array of meshes to convert</param>
        protected void CreateMeshes(AssimpSharp.Scene scene, AssimpSharp.Node node, List<AssimpSharp.XFile.Mesh> meshes)
        {
            if (meshes.Count == 0)
            {
                return;
            }

            // create a mesh for each mesh-material combination in the source node
            var result = new List<AssimpSharp.Mesh>();
            for (int a = 0; a < meshes.Count; a++)
            {
                var sourceMesh = meshes[a];
                // first convert its materials so that we can find them with their index afterwards
                ConvertMaterials(scene, sourceMesh.Materials);

                int numMaterials = Math.Max(sourceMesh.Materials.Count, 1);
                for (int b = 0; b < numMaterials; b++)
                {
                    // collect the faces belonging to this material
                    var faces = new List<int>();
                    var numVertices = 0;
                    if (sourceMesh.FaceMaterials.Count > 0)
                    {
                        // if there is a per-face material defined, select the faces with the corresponding material
                        for (int c = 0; c < sourceMesh.FaceMaterials.Count; c++)
                        {
                            if (sourceMesh.FaceMaterials[c] == b)
                            {
                                faces.Add(c);
                                numVertices += sourceMesh.PosFaces[c].Indices.Count;
                            }
                        }
                    }
                    else
                    {
                        // if there is no per-face material, place everything into one mesh
                        for (int c = 0; c < sourceMesh.PosFaces.Count; c++)
                        {
                            faces.Add(c);
                            numVertices += sourceMesh.PosFaces[c].Indices.Count;
                        }
                    }

                    // no faces/vertices using this material? strange...
                    if (numVertices == 0)
                    {
                        continue;
                    }

                    // create a submesh using this material
                    var mesh = new AssimpSharp.Mesh();
                    result.Add(mesh);

                    // find the material in the scene's material list. Either own material
                    // or referenced material, it should already have a valid index
                    if (sourceMesh.FaceMaterials.Count > 0)
                    {
                        mesh.MaterialIndex = sourceMesh.Materials[b].SceneIndex;
                    }
                    else
                    {
                        mesh.MaterialIndex = 0;
                    }

                    // Create properly sized data arrays in the mesh. We store unique vertices per face,
                    // as specified
                    mesh.NumVertices = numVertices;
                    mesh.Vertices = new Vector3[numVertices];
                    mesh.NumFaces = faces.Count;
                    mesh.Faces = new AssimpSharp.Face[mesh.NumFaces];

                    // normals?
                    if (sourceMesh.Normals.Count > 0)
                    {
                        mesh.Normals = new Vector3[numVertices];
                    }
                    // texture coords
                    for (int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; c++)
                    {
                        if (sourceMesh.TexCoords[c] != null && sourceMesh.TexCoords[c].Count > 0)
                        {
                            mesh.TextureCoords[c] = new Vector3[numVertices];
                        }
                    }
                    // vertex colors
                    mesh.Colors = new Color4[AI_MAX_NUMBER_OF_COLOR_SETS][];
                    for (int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; c++)
                    {
                        if (sourceMesh.Colors[c] != null && sourceMesh.Colors[c].Count > 0)
                        {
                            mesh.Colors[c] = new Color4[numVertices];
                        }
                    }

                    // now collect the vertex data of all data streams present in the imported mesh
                    int newIndex = 0;
                    var orgPoints = new int[numVertices];

                    for (int c = 0; c < faces.Count; c++)
                    {
                        int f = faces[c];
                        var pf = sourceMesh.PosFaces[f];

                        // create face. either triangle or triangle fan depending on the index count
                        var df = mesh.Faces[c] = new AssimpSharp.Face();
                        df.Indices = new int[pf.Indices.Count];

                        // collect vertex data for indices of this face
                        for (int d = 0; d < df.Indices.Length; d++)
                        {
                            df.Indices[d] = newIndex;
                            orgPoints[newIndex] = (int)pf.Indices[d];

                            // Position
                            mesh.Vertices[newIndex] = sourceMesh.Positions[(int)pf.Indices[d]];

                            // Normal, if present
                            if (mesh.HasNormals)
                            {
                                mesh.Normals[newIndex] = sourceMesh.Normals[(int)sourceMesh.NormalFaces[f].Indices[d]];
                            }

                            // texture coord sets
                            for (int e = 0; e < AI_MAX_NUMBER_OF_TEXTURECOORDS; e++)
                            {
                                if (mesh.HasTextureCoords(e))
                                {
                                    var tex = sourceMesh.TexCoords[e][(int)pf.Indices[d]];
                                    mesh.TextureCoords[e][newIndex] = new Vector3(tex.X, 1.0f - tex.Y, 0.0f);
                                }
                            }

                            // vertex color sets
                            for (int e = 0; e < AI_MAX_NUMBER_OF_COLOR_SETS; e++)
                            {
                                if (mesh.HasVertexColors(e))
                                {
                                    mesh.Colors[e][newIndex] = sourceMesh.Colors[e][(int)pf.Indices[d]];
                                }
                            }
                            newIndex++;
                        }
                    }

                    Debug.Assert(newIndex == numVertices);

                    var bones = sourceMesh.Bones;
                    var newBones = new List<AssimpSharp.Bone>();
                    for (int c = 0; c < bones.Count; c++)
                    {
                        var obone = bones[c];

                        var oldWeights = new float[sourceMesh.Positions.Count];
                        for (int d = 0; d < obone.Weights.Count; d++)
                        {
                            oldWeights[(int)obone.Weights[d].Vertex] = obone.Weights[d].Weight;
                        }

                        var newWeights = new List<AssimpSharp.VertexWeight>(numVertices);
                        for (int d = 0; d < orgPoints.Length; d++)
                        {
                            float w = oldWeights[orgPoints[d]];
                            if (w > 0.0f)
                            {
                                newWeights.Add(new VertexWeight(d, w));
                            }
                        }

                        if (newWeights.Count == 0)
                        {
                            continue;
                        }

                        // create
                        var nbone = new AssimpSharp.Bone();
                        newBones.Add(nbone);
                        // copy name end matrix
                        nbone.Name = obone.Name;
                        nbone.OffsetMatrix = obone.OffsetMatrix;
                        nbone.NumWeights = newWeights.Count;
                        nbone.Weights = new VertexWeight[nbone.NumWeights];
                        for (int d = 0; d < newWeights.Count; d++)
                        {
                            nbone.Weights[d] = newWeights[d];
                        }
                    }

                    mesh.NumBones = newBones.Count;
                    if (newBones.Count > 0)
                    {
                        mesh.Bones = mesh.Bones.ToArray();
                    }
                }
            }

            // allocate mesh index array in the node
            node.Meshes.Capacity = meshes.Count;

            // store all meshes in the mesh library of the scene and store their indices in the node
            for (int a = 0; a < result.Count; a++)
            {
                scene.Meshes.Add(result[a]);
                node.Meshes.Add(scene.Meshes.Count - 1);
            }
        }
Exemple #6
0
 public void LoadMaterial(AssimpSharp.Material material)
 {
     // Creates a basic effect
     basicEffect = new BasicEffect(device);
     //if (material.TextureDiffuse != null)
     //{
     //    basicEffect.Texture = Texture2D.Load(GraphicsDevice, Path.Combine(Path.GetDirectoryName(path), material.TextureDiffuse.TextureBase));
     //    basicEffect.TextureEnabled = true;
     //}
     //if (material.ColorDiffuse.HasValue)
     //{
     //    basicEffect.DiffuseColor = material.ColorDiffuse.Value.ToVector4();
     //}
 }
Exemple #7
0
        public void LoadMesh(AssimpSharp.Mesh mesh)
        {
            var vertexSource = new VertexPositionNormalTexture[mesh.Vertices.Length];
            for (int i = 0; i < mesh.Vertices.Length; i++)
            {
                vertexSource[i].Position = mesh.Vertices[i];
                vertexSource[i].Normal = mesh.Normals[i];
                vertexSource[i].TextureCoordinate = Vector2.Zero;
            }
            if (mesh.HasTextureCoords(0))
            {
                var channel = mesh.TextureCoords[0];
                for(int i=0; i<channel.Length; i++)
                {
                    vertexSource[i].TextureCoordinate.X = channel[i].X;
                    vertexSource[i].TextureCoordinate.Y = 1 - channel[i].Y;
                }
            }
            var vbd = new BufferDescription()
            {
                BindFlags = BindFlags.VertexBuffer,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.None,
                SizeInBytes = VertexPositionNormalTexture.Size * vertexSource.Length,
                Usage = ResourceUsage.Default,
                StructureByteStride = VertexPositionNormalTexture.Size,
            };
            vertices = Buffer.Create(device, vertexSource, vbd);

            var indexSource = new List<int>();
            for(int i=0; i<mesh.Faces.Length; i++)
            {
                var face = mesh.Faces[i];
                if (face.Indices.Length == 3)
                {
                    indexSource.AddRange(face.Indices.Reverse());
                }
                else if (face.Indices.Length == 4)
                {
                    indexSource.Add(face.Indices[2]);
                    indexSource.Add(face.Indices[1]);
                    indexSource.Add(face.Indices[0]);
                    indexSource.Add(face.Indices[0]);
                    indexSource.Add(face.Indices[3]);
                    indexSource.Add(face.Indices[2]);
                }
                else if (face.Indices.Length == 5)
                {
                    indexSource.Add(face.Indices[2]);
                    indexSource.Add(face.Indices[1]);
                    indexSource.Add(face.Indices[0]);
                    indexSource.Add(face.Indices[0]);
                    indexSource.Add(face.Indices[3]);
                    indexSource.Add(face.Indices[2]);
                    indexSource.Add(face.Indices[0]);
                    indexSource.Add(face.Indices[4]);
                    indexSource.Add(face.Indices[3]);
                }
                else
                {
                    throw (new Exception("invalid vertex count of polygon"));
                }
            }
            var ibd = new BufferDescription()
            {
                BindFlags = BindFlags.IndexBuffer,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.None,
                SizeInBytes = Utilities.SizeOf<int>() * indexSource.Count,
                Usage = ResourceUsage.Default,
                StructureByteStride = Utilities.SizeOf<int>(),
            };
            indices = Buffer.Create(device, indexSource.ToArray(), ibd);
            indexCount = indexSource.Count;
        }
Exemple #8
0
        void TestMesh(Assimp.Mesh netMesh, AssimpSharp.Mesh sharpMesh)
        {
            // Vertices
            Assert.AreEqual(netMesh.HasVertices, sharpMesh.Vertices != null);
            if (netMesh.HasVertices)
            {
                Assert.AreEqual(netMesh.VertexCount, sharpMesh.Vertices.Length);
                MathAssert.AreEqual(netMesh.Vertices, sharpMesh.Vertices);
            }
            // Faces
            Assert.AreEqual(netMesh.HasFaces, sharpMesh.Faces != null);
            if (netMesh.HasFaces)
            {
                Assert.AreEqual(netMesh.FaceCount, sharpMesh.Faces.Length);
                for (int i = 0; i < netMesh.FaceCount; i++)
                {
                    Assert.AreEqual(netMesh.Faces[i].HasIndices, sharpMesh.Faces[i].Indices != null);
                    Assert.AreEqual(netMesh.Faces[i].IndexCount, sharpMesh.Faces[i].Indices.Length);
                    Assert.AreEqual(netMesh.Faces[i].Indices, sharpMesh.Faces[i].Indices);
                }
            }
            // Normals
            Assert.AreEqual(netMesh.HasNormals, sharpMesh.Normals != null);
            if (netMesh.HasNormals)
            {
                MathAssert.AreEqual(netMesh.Normals, sharpMesh.Normals);
            }

            // BiTangents
            Assert.AreEqual(netMesh.HasTangentBasis, sharpMesh.Bitangents != null && sharpMesh.Bitangents.Length > 0);
            if (netMesh.HasTangentBasis)
            {
                MathAssert.AreEqual(netMesh.BiTangents, sharpMesh.Bitangents);
            }
            // PrimitiveType
            // AssimpNet BUG!!
            //Assert.AreEqual(netMesh.PrimitiveType.ToString(), Enum.GetName(typeof(AssimpSharp.PrimitiveType), sharpMesh.PrimitiveTypes));
            // TexureCoord
            for (int i = 0; i < netMesh.TextureCoordinateChannelCount; i++)
            {
                Assert.AreEqual(netMesh.HasTextureCoords(i), sharpMesh.HasTextureCoords(i));
                MathAssert.AreEqual(netMesh.TextureCoordinateChannels[i], sharpMesh.TextureCoords[i]);
            }
            // VertexColorChannels
            for (int i = 0; i < netMesh.VertexColorChannelCount; i++)
            {
                Assert.AreEqual(netMesh.HasVertexColors(i), sharpMesh.HasVertexColors(i));
                if (netMesh.HasVertexColors(i))
                {
                    Assert.AreEqual(netMesh.VertexColorChannels[i], sharpMesh.Colors[i]);
                }
            }
            // MaterialIndex
            Assert.AreEqual(netMesh.MaterialIndex, sharpMesh.MaterialIndex);
            // Name
            Assert.AreEqual(netMesh.Name, sharpMesh.Name);
            // UVComponentCount
            Assert.AreEqual(netMesh.UVComponentCount, sharpMesh.NumUVComponents);
            // MeshAnimationAttachments
            Assert.AreEqual(netMesh.HasMeshAnimationAttachments, sharpMesh.AnimMeshes != null);
            if (netMesh.HasMeshAnimationAttachments)
            {
                for (int i = 0; i < netMesh.MeshAnimationAttachmentCount; i++)
                {
                    TestAnimationAttachment(netMesh.MeshAnimationAttachments[i], sharpMesh.AnimMeshes[i]);
                }
            }
        }
Exemple #9
0
 private void ConvertTranslationKeys(AssimpSharp.NodeAnim na, List<AnimationCurveNode> nodes,
     LayerMap layers,
     long start, long stop,
     ref double maxTime,
     ref double minTime)
 {
     Debug.Assert(nodes.Count > 0);
     var inputs = GetKeyframeList(nodes, start, stop);
     var keys = GetKeyTimeList(inputs);
     na.PositionKeys = new AssimpSharp.VectorKey[keys.Count];
     InterpolateKeys(na.PositionKeys, keys, inputs, false, ref maxTime, ref minTime);
 }
Exemple #10
0
 public void TestEachNode(Assimp.Node netNode, AssimpSharp.Node sharpNode)
 {
     Assert.AreEqual(netNode.Name, sharpNode.Name);
     MathAssert.AreEqual(netNode.Transform, sharpNode.Transformation);
     Assert.AreEqual(netNode.HasMeshes, sharpNode.Meshes != null && sharpNode.Meshes.Count > 0);
     if (netNode.HasMeshes)
     {
         Assert.AreEqual(netNode.MeshCount, sharpNode.Meshes.Count);
         for (int i = 0; i < netNode.MeshCount; i++)
         {
             Assert.AreEqual(netNode.MeshIndices, sharpNode.Meshes);
         }
     }
     Assert.AreEqual(netNode.HasChildren, sharpNode.Children != null);
     if (netNode.HasChildren)
     {
         Assert.AreEqual(netNode.ChildCount, sharpNode.Children.Count);
         for (int nodeIndex = 0; nodeIndex < netNode.ChildCount; nodeIndex++)
         {
             TestEachNode(netNode.Children[nodeIndex], sharpNode.Children[nodeIndex]);
         }
     }
 }
Exemple #11
0
 void TestAnimationChannel(Assimp.NodeAnimationChannel netChannel, AssimpSharp.NodeAnim sharpChannel)
 {
     Assert.AreEqual(netChannel.NodeName, sharpChannel.NodeName);
     Assert.AreEqual(netChannel.PositionKeyCount, sharpChannel.PositionKeys.Length);
     for (int i = 0; i < netChannel.PositionKeyCount; i++)
     {
         Assert.AreEqual(netChannel.PositionKeys[i].Time, sharpChannel.PositionKeys[i].Time);
         MathAssert.AreEqual(netChannel.PositionKeys[i].Value, sharpChannel.PositionKeys[i].Value);
     }
     Assert.AreEqual(netChannel.RotationKeyCount, sharpChannel.RotationKeys.Length);
     for (int i = 0; i < netChannel.RotationKeyCount; i++)
     {
         Assert.AreEqual(netChannel.RotationKeys[i].Time, sharpChannel.RotationKeys[i].Time);
         MathAssert.AreEqual(netChannel.RotationKeys[i].Value, sharpChannel.RotationKeys[i].Value);
     }
     Assert.AreEqual(netChannel.ScalingKeyCount, sharpChannel.ScalingKeys.Length);
     for (int i = 0; i < netChannel.ScalingKeyCount; i++)
     {
         Assert.AreEqual(netChannel.ScalingKeys[i].Time, sharpChannel.ScalingKeys[i].Time);
         MathAssert.AreEqual(netChannel.ScalingKeys[i].Value, sharpChannel.ScalingKeys[i].Value);
     }
 }
Exemple #12
0
 void DrawSceneNode(AssimpSharp.Node node, Matrix view, Matrix projection, Matrix transform, float elapsedTime)
 {
     var context = device.ImmediateContext;
     transform = node.Transformation * transform;
     foreach(var meshId in node.Meshes ?? Enumerable.Empty<int>())
     {
         meshes[meshId].Draw(elapsedTime, view, projection, transform,context);
     }
     foreach(var child in node.Children ?? Enumerable.Empty<AssimpSharp.Node>())
     {
         DrawSceneNode(child, view, projection, transform, elapsedTime);
     }
 }
Exemple #13
0
 public static void ConvertToScene(out AssimpSharp.Scene result, Document doc)
 {
     new FbxConverter(out result, doc);
 }
Exemple #14
0
        /// <summary>
        /// Constructs the return data structure out of the imported data.
        /// </summary>
        /// <param name="scene">The scene to construct the return data in.</param>
        /// <param name="sdata">The imported data in the internal temporary representation.</param>
        protected void CreateDataRepresentationFromImport(AssimpSharp.Scene scene, Scene data)
        {
            // Read the global materials first so that meshes referring to them can find them later
            ConvertMaterials(scene, data.GlobalMaterial);

            // copy nodes, extracting meshes and materials on the way
            scene.RootNode = CreateNodes(scene, null, data.RootNode);

            // extract animations
            CreateAnimations(scene, data);

            // read the global meshes that were stored outside of any node
            if (data.GlobalMeshes.Count > 0)
            {
                // create a root node to hold them if there isn't any, yet
                if (scene.RootNode == null)
                {
                    scene.RootNode = new AssimpSharp.Node();
                    scene.RootNode.Name = "$dummy_node";
                }

                // convert all global meshes and store them in the root node.
                // If there was one before, the global meshes now suddenly have its transformation matrix...
                // Don't know what to do there, I don't want to insert another node under the present root node
                // just to avoid this.
                CreateMeshes(scene, scene.RootNode, data.GlobalMeshes);
            }

            if (scene.RootNode == null)
            {
                throw (new DeadlyImportError("No root node"));
            }

            // Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly
            var convertProcess = new MakeLeftHandedProcess();
            convertProcess.Execute(scene);

            var flipper = new FlipWindingOrderProcess();
            flipper.Execute(scene);

            // finally: create a dummy material if not material was imported
            if (scene.Materials.Count == 0)
            {
                var mat = new aiMaterial();
                mat.ShadingMode = ShadingMode.Gouraud;
                mat.ColorEmissive = new Color4(0, 0, 0, 1);
                mat.ColorSpecular = new Color4(0, 0, 0, 1);
                mat.ColorDiffuse = new Color4(0.5f, 0.5f, 0.5f, 1);
                mat.Shininess = 1.401298e-45f;
                scene.Materials.Add(mat);
            }
        }
Exemple #15
0
        /// <summary>
        /// Converts the animations from the given imported data and creates
        ///  them in the scene.
        /// </summary>
        /// <param name="scene">The scene to hold to converted animations</param>
        /// <param name="data">The data to read the animations from</param>
        protected void CreateAnimations(AssimpSharp.Scene scene, AssimpSharp.XFile.Scene data)
        {
            var newAnims = new List<AssimpSharp.Animation>();

            for (int a = 0; a < data.Anims.Count; a++)
            {
                var anim = data.Anims[a];
                if (anim.Anims.Count == 0)
                {
                    continue;
                }

                var nanim = new AssimpSharp.Animation();
                newAnims.Add(nanim);
                nanim.Name = anim.Name;
                nanim.Duration = 0;
                nanim.TicksPreSecond = data.AnimTicksPerSecond;
                nanim.Channels = new AssimpSharp.NodeAnim[anim.Anims.Count];

                for (int b = 0; b < anim.Anims.Count; b++)
                {
                    var bone = anim.Anims[b];
                    var nbone = new AssimpSharp.NodeAnim();
                    nbone.NodeName = bone.BoneName;
                    nanim.Channels[b] = nbone;

                    if (bone.TrafoKeys.Count > 0)
                    {
                        nbone.PositionKeys = new VectorKey[bone.TrafoKeys.Count];
                        nbone.RotationKeys = new QuatKey[bone.TrafoKeys.Count];
                        nbone.ScalingKeys = new VectorKey[bone.TrafoKeys.Count];

                        for (int c = 0; c < bone.TrafoKeys.Count; c++)
                        {
                            var time = bone.TrafoKeys[c].Key;
                            var trafo = bone.TrafoKeys[c].Value;

                            var pos = trafo.TranslationVector;

                            nbone.PositionKeys[c].Time = time;
                            nbone.PositionKeys[c].Value = pos;

                            Vector3 scale;
                            scale.X = new Vector3(trafo[0, 0], trafo[0, 1], trafo[0, 2]).Length();
                            scale.Y = new Vector3(trafo[1, 0], trafo[1, 1], trafo[1, 2]).Length();
                            scale.Z = new Vector3(trafo[2, 0], trafo[2, 1], trafo[2, 2]).Length();
                            nbone.ScalingKeys[c].Time = time;
                            nbone.ScalingKeys[c].Value = scale;

                            var rotmat = new Matrix3x3(
                        trafo[0, 0] / scale.X, trafo[0, 1] / scale.Y, trafo[0, 2] / scale.Z,
                        trafo[1, 0] / scale.X, trafo[1, 1] / scale.Y, trafo[1, 2] / scale.Z,
                        trafo[2, 0] / scale.X, trafo[2, 1] / scale.Y, trafo[2, 2] / scale.Z);

                            nbone.RotationKeys[c].Time = time;
                            throw (new NotImplementedException());
                            //nbone.RotationKeys[c].Value = ;
                        }
                        nanim.Duration = Math.Max(nanim.Duration, bone.TrafoKeys[bone.TrafoKeys.Count].Key);
                    }
                    else
                    {
                        // separate key sequences for position, rotation, scaling
                        nbone.PositionKeys = new VectorKey[bone.PosKeys.Count];
                        for (int c = 0; c < nbone.PositionKeys.Length; c++)
                        {
                            var pos = bone.PosKeys[c].Value;
                            nbone.PositionKeys[c].Time = bone.PosKeys[c].Time;
                            nbone.PositionKeys[c].Value = pos;
                        }

                        // rotation
                        nbone.RotationKeys = new QuatKey[bone.RotKeys.Count];
                        for (int c = 0; c < nbone.RotationKeys.Length; c++)
                        {
                            var rotmat = Matrix3x3.RotationQuaternion(bone.RotKeys[c].Value);
                            nbone.RotationKeys[c].Time = bone.RotKeys[c].Time;
                            Quaternion.RotationMatrix(ref rotmat, out nbone.RotationKeys[c].Value);
                            nbone.RotationKeys[c].Value.W *= -1.0f;
                        }

                        // longest lasting key sequence determines duration
                        nbone.ScalingKeys = new VectorKey[bone.ScaleKeys.Count];
                        for (int c = 0; c < nbone.ScalingKeys.Length; c++)
                        {
                            nbone.ScalingKeys[c] = bone.ScaleKeys[c];
                        }

                        // longest lasting key sequence determines duration
                        if (bone.PosKeys.Count > 0)
                        {
                            nanim.Duration = Math.Max(nanim.Duration, bone.PosKeys[bone.PosKeys.Count - 1].Time);
                        }
                        if (bone.RotKeys.Count > 0)
                        {
                            nanim.Duration = Math.Max(nanim.Duration, bone.RotKeys[bone.RotKeys.Count - 1].Time);
                        }
                        if (bone.ScaleKeys.Count > 0)
                        {
                            nanim.Duration = Math.Max(nanim.Duration, bone.ScaleKeys[bone.ScaleKeys.Count - 1].Time);
                        }
                    }
                }
            }

            // store all converted animations in the scene
            if (newAnims.Count > 0)
            {
                scene.Animations.Clear();
                scene.Animations.AddRange(newAnims);
            }
        }
Exemple #16
0
        /// <summary>
        /// Converts all materials in the given array and stores them in the
        ///  scene's material list.
        /// </summary>
        /// <param name="scene">The scene to hold the converted materials.</param>
        /// <param name="materials">The material array to convert.</param>
        protected void ConvertMaterials(AssimpSharp.Scene scene, List<AssimpSharp.XFile.Material> materials)
        {
            // count the non-referrer materials in the array
            var numNewMaterials = materials.Count(e => { return !e.IsReference; });

            // resize the scene's material list to offer enough space for the new materials
            if (numNewMaterials > 0)
            {
                scene.Materials.Capacity = scene.Materials.Count + numNewMaterials;

            }

            // convert all the materials given in the array
            for (int a = 0; a < materials.Count; a++)
            {
                XFile.Material oldMat = materials[a];
                if (oldMat.IsReference)
                {
                    // find the material it refers to by name, and store its index
                    for (int b = 0; b < scene.Materials.Count; b++)
                    {
                        var name = scene.Materials[b].Name;
                        if (name == oldMat.Name)
                        {
                            oldMat.SceneIndex = a;
                            break;
                        }
                    }

                    if (oldMat.SceneIndex == int.MaxValue)
                    {
                        throw (new Exception());
                        oldMat.SceneIndex = 0;
                    }
                    continue;
                }

                var mat = new aiMaterial();
                mat.Name = oldMat.Name;

                var shadeMode = (oldMat.SpecularExponent == 0.0f)
                    ? AssimpSharp.ShadingMode.Gouraud : ShadingMode.Phong;
                mat.ShadingMode = shadeMode;

                mat.ColorEmissive = new Color4(oldMat.Emissive, 1);
                mat.ColorDiffuse = oldMat.Diffuse;
                mat.ColorSpecular = new Color4(oldMat.Specular, 1);
                mat.Shininess = oldMat.SpecularExponent;

                if (1 == oldMat.Textures.Count)
                {
                    var otex = oldMat.Textures[0];
                    if (!string.IsNullOrEmpty(otex.Name))
                    {
                        string tex = otex.Name;
                        if (otex.IsNormalMap)
                        {
                            mat.TextureNormals = new TextureSlot() { TextureBase = tex };
                        }
                        else
                        {
                            mat.TextureDiffuse = new TextureSlot() { TextureBase = tex };
                        }
                    }
                }
                else
                {
                    int iHM = 0, iNM = 0, iDM = 0, iSM = 0, iAM = 0, iEM = 0;
                    for (int b = 0; b < oldMat.Textures.Count; b++)
                    {
                        var otex = oldMat.Textures[b];
                        var sz = otex.Name;
                        if (string.IsNullOrEmpty(sz))
                        {
                            continue;
                        }

                        int s = sz.LastIndexOf("\\/");
                        if (s == -1)
                        {
                            s = 0;
                        }

                        int sExt = sz.LastIndexOf('.');
                        if (sExt > 0)
                        {
                            sz = sz.Substring(0, sExt - 1) + '\0' + sz.Substring(sExt);
                        }

                        sz = sz.ToLower();

                        var tex = new TextureSlot() { TextureBase = oldMat.Textures[b].Name };

                        if (sz.Substring(s).Contains("bump") || sz.Substring(s).Contains("height"))
                        {
                            mat.TextureHeight = tex;
                        }
                        else if (otex.IsNormalMap || sz.Substring(s).Contains("normal") || sz.Substring(s).Contains("nm"))
                        {
                            mat.TextureNormals = tex;
                        }
                        else if (sz.Substring(s).Contains("spec") || sz.Substring(s).Contains("glanz"))
                        {
                            mat.TextureSpecular = tex;
                        }
                        else if (sz.Substring(s).Contains("ambi") || sz.Substring(s).Contains("env"))
                        {
                            mat.TextureAmbient = tex;
                        }
                        else if (sz.Substring(s).Contains("emissive") || sz.Substring(s).Contains("self"))
                        {
                            mat.TextureEmmisive = tex;
                        }
                        else
                        {
                            mat.TextureDiffuse = tex;
                        }
                    }
                }
                scene.Materials.Add(mat);
                //scene.Materials[scene.Materials.Count] = mat;
                oldMat.SceneIndex = scene.Materials.Count - 1;
            }
        }
Exemple #17
0
        private void InterpolateKeys(AssimpSharp.VectorKey[] valOut, KeyTimeList keys, KeyFrameListList inputs,
            bool geom,
            ref double maxTime,
            ref double minTime)
        {
            Debug.Assert(keys.Count > 0);
            Debug.Assert(valOut != null);

            var count = inputs.Count;
            var nextPos = new List<int>(count);

            int valOutIndex = 0;
            foreach (var time in keys)
            {
                var result = new float[] { 0, 0, 0 };
                if (geom)
                {
                    result[0] = result[1] = result[2] = 1.0f;
                }

                for (int i = 0; i < count; i++)
                {
                    var kfl = inputs[i];
                    var ksize = kfl.Item1.Count;
                    if (ksize > nextPos[i] && kfl.Item1[nextPos[i]] == time)
                    {
                        ++nextPos[i];
                    }

                    var id0 = nextPos[i] > 0 ? nextPos[i] - 1 : 0;
                    var id1 = nextPos[i] == ksize ? ksize - 1 : nextPos[i];

                    // use lerp for interpolation
                    var valueA = kfl.Item2[id0];
                    var valueB = kfl.Item2[id1];
                    var timeA = kfl.Item1[id0];
                    var timeB = kfl.Item1[id1];

                    // do the actual interpolation in double-precision arithmetics
                    // because it is a bit sensitive to rounding errors.
                    var factor = timeB == timeA ? 0.0 : (double)((time - timeA) / (timeB - timeA));
                    var interpValue = (float)(valueA + (valueB - valueA) * factor);

                    if (geom)
                    {
                        result[kfl.Item3] *= interpValue;
                    }
                    else
                    {
                        result[kfl.Item3] += interpValue;
                    }
                }

                // magic value to convert fbx times to seconds
                valOut[valOutIndex].Time = CONVERT_FBX_TIME(time) * AnimFps;

                minTime = Math.Min(minTime, valOut[valOutIndex].Time);
                maxTime = Math.Max(maxTime, valOut[valOutIndex].Time);

                valOut[valOutIndex].Value.X = result[0];
                valOut[valOutIndex].Value.Y = result[1];
                valOut[valOutIndex].Value.Z = result[2];

                valOutIndex++;
            }
        }
Exemple #18
0
        private void InterpolateKeys(AssimpSharp.QuatKey[] valOut, KeyTimeList keys, KeyFrameListList inputs,
            bool geom, ref double maxTime, ref double minTime, Model.RotOrder order)
        {
            Debug.Assert(keys.Count > 0);
            Debug.Assert(valOut != null);

            var temp = new AssimpSharp.VectorKey[keys.Count];
            InterpolateKeys(temp, keys, inputs, geom, ref maxTime, ref minTime);

            Matrix m;
            Quaternion lastq = Quaternion.Identity;
            for (int i = 0; i < keys.Count; i++)
            {
                valOut[i].Time = temp[i].Time;
                GetRotationMatrix(order, temp[i].Value, out m);
                var quat = Quaternion.RotationMatrix(m);
                if (Quaternion.Dot(quat, lastq) < 0)
                {
                    quat = -quat;
                }
                lastq = quat;
                valOut[i].Value = quat;
            }
        }
Exemple #19
0
 /// <summary>
 /// Recursively writes the given node
 /// </summary>
 protected void WriteNode(AssimpSharp.Node node)
 {
 }
Exemple #20
0
        /// <summary>
        /// Recursively creates scene nodes from the imported hierarchy.
        /// The meshes and materials of the nodes will be extracted on the way.
        /// </summary>
        /// <param name="scene">The scene to construct the return data in.</param>
        /// <param name="parent">The parent node where to create new child nodes</param>
        /// <param name="node">The temporary node to copy.</param>
        /// <returns>The created node</returns>
        protected AssimpSharp.Node CreateNodes(AssimpSharp.Scene scene, AssimpSharp.Node parent, AssimpSharp.XFile.Node node)
        {
            if (node == null)
            {
                return null;
            }

            // crate node
            var result = new AssimpSharp.Node();
            result.Name = node.Name;
            result.Transformation = node.TrafoMatrix;
            result.Parent = parent;

            // convert meshes from the source node
            CreateMeshes(scene, result, node.Meshes);

            // handle childs
            if (node.Children.Count > 0)
            {
                result.Children.Clear();
                foreach(var i in node.Children)
                {
                    result.Children.Add(CreateNodes(scene, result, i));
                }
            }

            return result;
        }
Exemple #21
0
 public static void ExportSceneXFile(string file, IOSystem iosystem, AssimpSharp.Scene scene, ExportProperties propoerties)
 {
     throw (new NotImplementedException());
 }
Exemple #22
0
        void CreateVertexArray(Model model, Object currentObject, int meshIndex, AssimpSharp.Mesh mesh, int numIndices)
        {
            Debug.Assert(null != currentObject);

            if (currentObject.Meshes.Count == 0)
            {
                return;
            }

            var objMesh = model.Meshes[meshIndex];
            if (null == objMesh || objMesh.NumIndices < 1)
            {
                return;
            }

            mesh.NumVertices = numIndices;
            if (mesh.NumVertices == 0)
            {
                throw (new DeadlyImportError("OBJ: no vertices"));
            }
            else if (mesh.NumVertices > int.MaxValue)
            {
                throw (new DeadlyImportError("OBJ: Too many vertices, would run out of memory"));
            }
            mesh.Vertices = new Vector3[mesh.NumVertices];

            if (model.Normals.Count != 0 && objMesh.HasNormals)
            {
                mesh.Normals = new Vector3[mesh.NumVertices];
            }

            if (model.TextureCoord.Count > 0 && objMesh.UVCoordinates[0] > 0)
            {
                mesh.NumUVComponents[0] = 2;
                mesh.TextureCoords[0] = new Vector3[mesh.NumVertices];
            }

            int newIndex = 0;
            int outIndex = 0;
            for (int index = 0; index < objMesh.Faces.Count; index++)
            {
                var sourceFace = objMesh.Faces[index];

                for (int vertexIndex = 0, outVertexIndex = 0; vertexIndex < sourceFace.Vertices.Count; vertexIndex++)
                {
                    int vertex = (int)sourceFace.Vertices[vertexIndex];
                    if (vertexIndex >= model.Vertices.Count)
                    {
                        throw (new DeadlyImportError("OBJ: vertex index out of range"));
                    }
                    mesh.Vertices[newIndex] = model.Vertices[vertex];

                }
            }
        }
Exemple #23
0
 void TestAnimationAttachment(Assimp.MeshAnimationAttachment netAnimMesh, AssimpSharp.AnimMesh sharpAnimMesh)
 {
     Assert.AreEqual(netAnimMesh.HasVertices, sharpAnimMesh.HasPosition);
     if (netAnimMesh.HasVertices)
     {
         Assert.AreEqual(netAnimMesh.Vertices, sharpAnimMesh.Vertices);
     }
     Assert.AreEqual(netAnimMesh.HasNormals, sharpAnimMesh.HasNormals);
     if (netAnimMesh.HasNormals)
     {
         Assert.AreEqual(netAnimMesh.Normals, sharpAnimMesh.Normals);
     }
     Assert.AreEqual(netAnimMesh.HasTangentBasis, sharpAnimMesh.HasTangentsAndBitangets);
     if (netAnimMesh.HasTangentBasis)
     {
         Assert.AreEqual(netAnimMesh.Tangents, sharpAnimMesh.Tangents);
         Assert.AreEqual(netAnimMesh.BiTangents, sharpAnimMesh.Bitangents);
     }
     for (int i = 0; i < netAnimMesh.TextureCoordinateChannelCount; i++)
     {
         Assert.AreEqual(netAnimMesh.HasTextureCoords(i), sharpAnimMesh.HasTextureCoords(i));
         if (netAnimMesh.HasTextureCoords(i))
         {
             Assert.AreEqual(netAnimMesh.TextureCoordinateChannels[i], sharpAnimMesh.TextureCoords[i]);
         }
     }
     for (int i = 0; i < netAnimMesh.VertexColorChannelCount; i++)
     {
         Assert.AreEqual(netAnimMesh.HasVertexColors(i), sharpAnimMesh.HasVertexColors(i));
         if (netAnimMesh.HasVertexColors(i))
         {
             Assert.AreEqual(netAnimMesh.VertexColorChannels[i], sharpAnimMesh.Colors[i]);
         }
     }
 }
Exemple #24
0
 /// <summary>
 /// Add clamp mode property to material if necessary
 /// </summary>
 void AddTextureMappingModeProperty(AssimpSharp.Material mat, AssimpSharp.TextureType type, int clampMode = 1)
 {
     Debug.Assert(null != mat);
     mat.TextureSlotCollection[type].MappingModeU = (TextureMapMode)clampMode;
     mat.TextureSlotCollection[type].MappingModeV = (TextureMapMode)clampMode;
 }
Exemple #25
0
 void TestAnimationChannel(Assimp. MeshAnimationChannel netChannel, AssimpSharp.MeshAnim sharpChannel)
 {
     Assert.AreEqual(netChannel.MeshName, sharpChannel.Name);
     Assert.AreEqual(netChannel.MeshKeyCount, sharpChannel.Keys.Length);
     for (int i = 0; i < netChannel.MeshKeyCount; i++)
     {
         Assert.AreEqual(netChannel.MeshKeys[i].Time, sharpChannel.Keys[i].Time);
         Assert.AreEqual(netChannel.MeshKeys[i].Value, sharpChannel.Keys[i].Value);
     }
 }
Exemple #26
0
        /// <summary>
        /// Appends this node to the parent node
        /// </summary>
        void AppendChildToParentNode(AssimpSharp.Node parent, AssimpSharp.Node child)
        {
            // Checking preconditions
            Debug.Assert(null != parent);
            Debug.Assert(null != child);

            // Assign parent to child
            child.Parent = parent;

            parent.Children.Add(child);
        }
Exemple #27
0
 void TestTexture(Assimp.EmbeddedTexture netTexture, AssimpSharp.Texture sharpTexture)
 {
     throw (new NotImplementedException());
 }
Exemple #28
0
        private void ConvertTransformOrder_TRStoSRT(
            AssimpSharp.QuatKey[] outQuat,
            AssimpSharp.VectorKey[] outScale,
            AssimpSharp.VectorKey[] outTranslation,
            KeyFrameListList scaling,
            KeyFrameListList translation,
            KeyFrameListList rotation,
            KeyTimeList times,
            ref double maxTime,
            ref double minTime,
            Model.RotOrder order,
            Vector3 defScasle,
            Vector3 defTranslate,
            Quaternion defRotation)
        {
            if (rotation.Count > 0)
            {
                InterpolateKeys(outQuat, times, rotation, false, ref maxTime, ref minTime, order);
            }
            else
            {
                for (int i = 0; i < times.Count; i++)
                {
                    outQuat[i].Time = CONVERT_FBX_TIME(times[i]) * AnimFps;
                    outQuat[i].Value = defRotation;
                }
            }

            if (scaling.Count > 0)
            {
                InterpolateKeys(outScale, times, scaling, true, ref maxTime, ref minTime);
            }
            else
            {
                for (int i = 0; i < times.Count; i++)
                {
                    outScale[i].Time = CONVERT_FBX_TIME(times[i]) * AnimFps;
                    outScale[i].Value = defScasle;
                }
            }

            if (translation.Count > 0)
            {
                InterpolateKeys(outTranslation, times, translation, false, ref maxTime, ref minTime);
            }
            else
            {
                for (int i = 0; i < times.Count; i++)
                {
                    outTranslation[i].Time = CONVERT_FBX_TIME(times[i]) * AnimFps;
                    outTranslation[i].Value = defTranslate;
                }
            }

            var count = times.Count;
            for (int i = 0; i < count; i++)
            {
                var r = outQuat[i].Value;
                var s = outScale[i].Value;
                var t = outTranslation[i].Value;

                Matrix mat;

                Matrix.Translation(ref t, out mat);
                mat *= Matrix.RotationQuaternion(r);
                mat *= Matrix.Scaling(s);
                mat.Decompose(out s, out r, out t);
                outQuat[i].Value = r;
                outScale[i].Value = s;
                outTranslation[i].Value = t;
            }
        }