HasTextureCoords() публичный Метод

Checks if the mesh has texture coordinates for the specified channel. This returns false if the list is null or empty. The channel, if it exists, should contain the same number of entries as VertexCount.
public HasTextureCoords ( int channelIndex ) : bool
channelIndex int Channel index
Результат bool
        /// <summary>
        /// Gets vertex data from a given <see cref="AssimpMesh"/>.
        /// </summary>
        /// <param name="sceneMesh">The <see cref="AssimpMesh"/> to get vertex information from.</param>
        /// <param name="boneIndexByName">A lookup of bone index by name information.</param>
        /// <returns>An output list of vertices.</returns>
        private Vertex[] GetMeshVertices(AssimpMesh sceneMesh, Dictionary <string, uint> boneIndexByName)
        {
            var positions                = sceneMesh.Vertices;
            var normals                  = sceneMesh.Normals;
            var tangents                 = sceneMesh.Tangents;
            var colors                   = sceneMesh.HasVertexColors(0) ? sceneMesh.VertexColorChannels[0] : null;
            var textureCoordinates       = sceneMesh.HasTextureCoords(0) ? sceneMesh.TextureCoordinateChannels[0] : null;
            var boneWeightsByVertexIndex = GetBoneWeightsByVertexIndex(boneIndexByName, sceneMesh);

            var vertices = new List <Vertex>();

            for (var i = 0; i < positions.Count; i++)
            {
                var position          = positions[i];
                var normal            = normals[i];
                var tangent           = tangents[i];
                var color             = colors?[i];
                var textureCoordinate = textureCoordinates?[i];
                TryGetBoneIndicesAndWeights(boneWeightsByVertexIndex, i, out var boneIndices, out var boneWeights);

                vertices.Add(new Vertex(new Vector3(position.X, position.Y, position.Z),
                                        new Vector3(normal.X, normal.Y, normal.Z),
                                        new Vector3(tangent.X, tangent.Y, tangent.Z),
                                        color != null ? new Color(color.Value.R, color.Value.G, color.Value.B, color.Value.A) : new Color(1.0f, 1.0f, 1.0f, 1.0f),
                                        textureCoordinate != null ? new Vector2(textureCoordinate.Value.X, textureCoordinate.Value.Y) : Vector2.Zero,
                                        new ReadOnlyCollection <uint>(boneIndices),
                                        new ReadOnlyCollection <float>(boneWeights)));
            }

            return(vertices.ToArray());
        }
Пример #2
0
        private void _initMesh(Assimp.Mesh mesh)
        {
            Assimp.Vector3D Zero3D = new Assimp.Vector3D(0f);

            if (mesh.PrimitiveType == Assimp.PrimitiveType.Triangle)
            {
                // Populate the vertex attribute vectors
                for (int i = 0; i < mesh.VertexCount; i++)
                {
                    Assimp.Vector3D pos    = mesh.Vertices[i];
                    Assimp.Vector3D normal = mesh.Normals[i];
                    Assimp.Vector3D uv     = mesh.HasTextureCoords(0) ? mesh.TextureCoordinateChannels[0][i] : Zero3D;

                    positions.Add(new Vector3f(pos.X, pos.Y, pos.Z));
                    normals.Add(new Vector3f(normal.X, normal.Y, normal.Z));
                    uvs.Add(new Vector2f(uv.X, uv.Y));
                }

                // Populate the index buffer
                for (int i = 0; i < mesh.FaceCount; i++)
                {
                    Assimp.Face face = mesh.Faces[i];
                    // TODO: Find a suitable way to draw vertices...
                    // Now only support triangulated faces
                    indices.Add(face.Indices[0]);
                    indices.Add(face.Indices[1]);
                    indices.Add(face.Indices[2]);
                }
            }
        }
Пример #3
0
        private Mesh ProcessMesh(Assimp.Mesh aMesh, Scene scene)
        {
            Mesh mesh = new Mesh();

            for (int i = 0; i < aMesh.VertexCount; i++)
            {
                Vertex vertex = new Vertex
                {
                    Position = new Vector3(aMesh.Vertices[i].X, aMesh.Vertices[i].Y, aMesh.Vertices[i].Z)
                };
                if (aMesh.HasNormals)
                {
                    vertex.Normals = new Vector3(aMesh.Normals[i].X, aMesh.Normals[i].Y, aMesh.Normals[i].Z);
                }
                if (aMesh.HasTextureCoords(0))
                {
                    vertex.TexCoords = new Vector2(aMesh.TextureCoordinateChannels[0][i].X, aMesh.TextureCoordinateChannels[0][i].Y);
                    if (aMesh.HasTangentBasis)
                    {
                        vertex.Tangent   = new Vector3(aMesh.Tangents[i].X, aMesh.Tangents[i].Y, aMesh.Tangents[i].Z);
                        vertex.Bitangent = new Vector3(aMesh.BiTangents[i].X, aMesh.BiTangents[i].Y, aMesh.BiTangents[i].Z);
                    }
                }
                else
                {
                    vertex.TexCoords = Vector2.Zero;
                }
                mesh.Vertices = mesh.Vertices.Append(vertex).ToArray();
            }

            for (int i = 0; i < aMesh.FaceCount; i++)
            {
                for (int j = 0; j < aMesh.Faces[i].IndexCount; j++)
                {
                    mesh.Indices = mesh.Indices.Append(aMesh.Faces[i].Indices[j]).ToArray();
                }
            }

            var material = scene.Materials[aMesh.MaterialIndex];

            List <Texture> diffuseMaps = LoadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse");

            mesh.Textures.AddRange(diffuseMaps);

            List <Texture> specularMaps = LoadMaterialTextures(material, TextureType.Specular, "texture_specular");

            mesh.Textures.AddRange(specularMaps);

            List <Texture> normalMaps = LoadMaterialTextures(material, TextureType.Normals, "texture_normal");

            mesh.Textures.AddRange(normalMaps);

            List <Texture> heightMaps = LoadMaterialTextures(material, TextureType.Height, "texture_height");

            mesh.Textures.AddRange(heightMaps);

            mesh.SetupMesh();
            return(mesh);
        }
Пример #4
0
        Mesh processMesh(Assimp.Mesh mesh, Assimp.Scene scene)
        {
            List <Vertex>  vertices = null;
            List <int>     indices  = null;
            List <Texture> textures = null;

            for (int i = 0; i < mesh.VertexCount; i++)
            {
                Vertex  vert = new Vertex();
                Vector3 vec  = new Vector3();
                vec.X         = mesh.Vertices[i].X;
                vec.Y         = mesh.Vertices[i].Y;
                vec.Z         = mesh.Vertices[i].Z;
                vert.position = vec;

                vec.X       = mesh.Normals[i].X;
                vec.Y       = mesh.Normals[i].Y;
                vec.Z       = mesh.Normals[i].Z;
                vert.normal = vec;

                if (mesh.HasTextureCoords(0))
                {
                    Vector2 vec2 = new Vector2();
                    vec2.X        = mesh.TextureCoordinateChannels[0][i].X;
                    vec2.Y        = mesh.TextureCoordinateChannels[0][i].Y;
                    vert.texCoord = vec2;
                }
                else
                {
                    vert.texCoord = new Vector2(0, 0);
                }

                vertices.Add(vert);
            }

            for (int i = 0; i < mesh.FaceCount; i++)
            {
                Assimp.Face face = new Face();
                face = mesh.Faces[i];
                for (int j = 0; j < face.IndexCount; j++)
                {
                    indices.Add(face.Indices[j]);
                }
            }

            if (mesh.MaterialIndex >= 0)
            {
                Material       material    = scene.Materials[mesh.MaterialIndex];
                List <Texture> diffuseMaps = new List <Texture>();
                diffuseMaps.AddRange(loadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse"));
                textures.InsertRange(textures.Count + 1, diffuseMaps);

                List <Texture> specularMaps = new List <Texture>();
                specularMaps.AddRange(loadMaterialTextures(material, TextureType.Specular, "texture_specular"));
                textures.InsertRange(textures.Count + 1, specularMaps);
            }

            return(new Mesh(vertices, indices, textures));
        }
Пример #5
0
        /// <summary>
        /// Processes a Mesh in an Assimp Scene
        /// </summary>
        /// <param name="mesh">The Current mesh to process</param>
        /// <param name="s">The root scene</param>
        /// <param name="dir">The Relative directory of the Mesh File</param>
        /// <returns>The mesh loaded.</returns>
        private static Mesh processMesh(AssimpMesh mesh, Scene s, string dir, object handleIdentifier)
        {
            List <Vertex>  vertices = new List <Vertex>();
            List <uint>    indices  = new List <uint>();
            List <Texture> textures = new List <Texture>();


            Logger.Log(DebugChannel.Log | DebugChannel.EngineIO,
                       "Converting Imported Mesh File Structure to GameEngine Engine Structure", 3);


            Logger.Log(DebugChannel.Log | DebugChannel.EngineIO, "Copying Vertex Data...", 2);
            for (int i = 0; i < mesh.VertexCount; i++)
            {
                Vector3D vert = mesh.Vertices[i];
                Vector3D norm = mesh.Normals[i];
                Vector3D tan  = mesh.HasTangentBasis ? mesh.Tangents[i] : new Vector3D(0);
                Vector3D bit  = mesh.HasTangentBasis ? mesh.BiTangents[i] : new Vector3D(0);
                Vector3D uv   = mesh.HasTextureCoords(0) ? mesh.TextureCoordinateChannels[0][i] : new Vector3D(0);

                Vertex v = new Vertex
                {
                    Position   = new Vector3(vert.X, vert.Y, vert.Z),
                    Normal     = new Vector3(norm.X, norm.Y, norm.Z),
                    UV         = new Vector2(uv.X, uv.Y),
                    Bittangent = new Vector3(bit.X, bit.Y, bit.Z),
                    Tangent    = new Vector3(tan.X, tan.Y, tan.Z)
                };

                vertices.Add(v);
            }


            Logger.Log(DebugChannel.Log | DebugChannel.EngineIO, "Calculating Indices...", 2);

            for (int i = 0; i < mesh.FaceCount; i++)
            {
                Face f = mesh.Faces[i];
                indices.AddRange(f.Indices.Select(x => (uint)x));
            }


            Material m = s.Materials[mesh.MaterialIndex];

            Logger.Log(DebugChannel.Log | DebugChannel.EngineIO, "Loading Baked Material: " + m.Name, 2);

            textures.AddRange(TextureLoader.LoadMaterialTextures(m, TextureType.Diffuse, dir));
            textures.AddRange(TextureLoader.LoadMaterialTextures(m, TextureType.Specular, dir));
            textures.AddRange(TextureLoader.LoadMaterialTextures(m, TextureType.Normals, dir));
            textures.AddRange(TextureLoader.LoadMaterialTextures(m, TextureType.Height, dir));

            setupMesh(indices.ToArray(), vertices.ToArray(), out int vao, out int vbo, out int ebo);

            long bytes = indices.Count * sizeof(uint) + vertices.Count * Vertex.VERTEX_BYTE_SIZE;

            return(new Mesh(ebo, vbo, vao, indices.Count, bytes, false, handleIdentifier));
        }
Пример #6
0
        private static void FbxIndexToFloatList(int faceIndex, Assimp.Mesh mesh, Face face, FbxMeshData fbxData)
        {
            int index = face.Indices[faceIndex];

            Vector3D v = mesh.Vertices[index];

            fbxData.vList.Add(v.X * fbxData.multiplier.X);
            fbxData.vList.Add(v.Y * fbxData.multiplier.Y);
            fbxData.vList.Add(v.Z * fbxData.multiplier.Z);

            if (mesh.HasTextureCoords(0))
            {
                Vector3D uv = mesh.TextureCoordinateChannels[0][index];
                fbxData.vtList.Add(uv.X);
                fbxData.vtList.Add(1 - uv.Y);
            }

            if (mesh.HasNormals)
            {
                Vector3D n = mesh.Normals[index];
                fbxData.vnList.Add(n.X);
                fbxData.vnList.Add(n.Y);
                fbxData.vnList.Add(n.Z);
            }

            if (mesh.HasBones)
            {
                float[] bonesMapping = { -1, -1, -1, -1 };
                float[] bonesWeight  = { -1, -1, -1, -1 };
                if (fbxData.bonesInfluences.ContainsKey(index))
                {
                    for (int i = 0; i < Math.Min(fbxData.bonesInfluences[index].Count, 4); i++)
                    {
                        int boneId = mesh.Bones.IndexOf(fbxData.bonesInfluences[index][i].bone);
                        bonesMapping[i] = boneId;
                        bonesWeight[i]  = fbxData.bonesInfluences[index][i].weight;
                    }
                }
                fbxData.bonesMappingList.Add(bonesMapping[0]);
                fbxData.bonesMappingList.Add(bonesMapping[1]);
                fbxData.bonesMappingList.Add(bonesMapping[2]);
                fbxData.bonesMappingList.Add(bonesMapping[3]);

                fbxData.bonesWeightList.Add(bonesWeight[0]);
                fbxData.bonesWeightList.Add(bonesWeight[1]);
                fbxData.bonesWeightList.Add(bonesWeight[2]);
                fbxData.bonesWeightList.Add(bonesWeight[3]);
            }
        }
Пример #7
0
        private static List <float> ProcessTextCoord(Assimp.Mesh mesh)
        {
            List <float> textCoord = new List <float>();

            if (mesh.HasTextureCoords(0))
            {
                foreach (var tc in mesh.TextureCoordinateChannels[0])
                {
                    textCoord.Add(tc.X);
                    textCoord.Add(1 - tc.Y);
                }
            }

            return(textCoord);
        }
Пример #8
0
        private Mesh ProgressMesh(Assimp.Mesh mesh, Assimp.Scene scene)
        {
            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++)
            {
                Vertex vertex = new Vertex();
                vertex.Position = new OpenTK.Vector3(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z);
                vertex.Normal   = new OpenTK.Vector3(mesh.Normals[i].X, mesh.Normals[i].Y, mesh.Normals[i].Z);
                if (mesh.HasTextureCoords(0))
                {
                    vertex.TexCoords = new OpenTK.Vector2(mesh.TextureCoordinateChannels[0][i].X, mesh.TextureCoordinateChannels[0][i].Y);
                }
                else
                {
                    vertex.TexCoords = new OpenTK.Vector2(0, 0);
                }

                vertices.Add(vertex);
            }

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

            if (mesh.MaterialIndex >= 0)
            {
                Material       material   = scene.Materials[mesh.MaterialIndex];
                List <Texture> diffuseMap = LoadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse");
                textures.InsertRange(textures.Count, diffuseMap);

                List <Texture> specularMap = LoadMaterialTextures(material, TextureType.Specular, "texture_specular");
                textures.InsertRange(textures.Count, specularMap);
            }

            return(new Mesh(vertices.ToArray(), indices.ToArray(), textures.ToArray()));
        }
Пример #9
0
 IEnumerable <AssimpVertex> GetVertex(Assimp.Mesh m)
 {
     for (int i = 0; i < m.VertexCount; ++i)
     {
         Vector3 cc = m.Vertices[i].ToVector3();
         var     bw = GetWAndB(m, i);
         yield return(new AssimpVertex()
         {
             position = cc,
             uv = m.HasTextureCoords(0) ? m.TextureCoordinateChannels[0][i].ToVector3() : new Vector3(),
             tangent = m.HasTangentBasis ? m.Tangents[i].ToVector3() : new Vector3(),
             biTangent = m.HasTangentBasis ? m.BiTangents[i].ToVector3() : new Vector3(),
             normal = m.HasNormals ? m.Normals[i].ToVector3() : new Vector3(),
             BoneID = HasAnimation && m.HasBones ? GetBoneID(bw) : new Vector4(),
             BoneWheight = HasAnimation && m.HasBones ? GetWheight(bw) : new Vector4(),
             Color = m.HasVertexColors(0) ? m.VertexColorChannels[0][i].ToColor4() : new Color4(0.5f, 0.5f, 0.5f, 1)
         });
     }
     yield break;
 }
Пример #10
0
        Mesh processMesh(Assimp.Mesh mesh, Scene scene)
        {
            List <Vertex>      vertices = new List <Vertex>();
            List <uint>        indices  = new List <uint>();
            List <MeshTexture> textures = new List <MeshTexture>();

            for (int i = 0; i < mesh.VertexCount; i++)
            {
                Vertex vertex = new Vertex();
                // 处理顶点位置、法线和纹理坐标
                vertex.pos    = mesh.Vertices[i].ToVector3();
                vertex.normal = mesh.Normals[i].ToVector3();
                if (mesh.HasTextureCoords(0))
                {
                    vertex.uv = mesh.TextureCoordinateChannels[0][i].XY().ToVector2();
                }

                vertices.Add(vertex);
            }
            // 处理索引
            foreach (var face in mesh.Faces)
            {
                foreach (uint indice in face.Indices)
                {
                    indices.Add(indice);
                }
            }
            // 处理材质
            if (mesh.MaterialIndex >= 0)
            {
                Material      material    = scene.Materials[mesh.MaterialIndex];
                MeshTexture[] diffuseMaps = loadMaterialTextures(material,
                                                                 TextureType.Diffuse, "material.diffuse");
                textures.AddRange(diffuseMaps);
                MeshTexture[] specularMaps = loadMaterialTextures(material,
                                                                  TextureType.Specular, "material.specular");
                textures.AddRange(specularMaps);
            }

            return(new Mesh(vertices.ToArray(), indices.ToArray(), textures.ToArray()));
        }
Пример #11
0
        //determine the number of elements in the vertex
        private int GetNoofInputElements(Assimp.Mesh mesh)
        {
            bool hasTexCoords  = mesh.HasTextureCoords(0);
            bool hasColors     = mesh.HasVertexColors(0);
            bool hasNormals    = mesh.HasNormals;
            bool hasTangents   = mesh.Tangents != null && mesh.Tangents.Count > 0;
            bool hasBitangents = mesh.BiTangents != null && mesh.BiTangents.Count > 0;

            int noofElements = 1;

            if (hasColors)
            {
                noofElements++;
            }

            if (hasNormals)
            {
                noofElements++;
            }

            if (hasTangents)
            {
                noofElements++;
            }

            if (hasBitangents)
            {
                noofElements++;
            }

            if (hasTexCoords)
            {
                noofElements++;
            }

            return(noofElements);
        }
Пример #12
0
        void WriteVertices(Mesh assimpMesh, ModelData.MeshPart meshPart, ModelData.VertexBuffer vertexBuffer, int vertexBufferElementSize)
        {
            // Write all vertices
            meshPart.VertexBufferRange.Count = assimpMesh.VertexCount;
            vertexBuffer.Count  = assimpMesh.VertexCount;
            vertexBuffer.Buffer = new byte[vertexBufferElementSize * assimpMesh.VertexCount];

            // Update the MaximumBufferSizeInBytes needed to load this model
            if (vertexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes)
            {
                model.MaximumBufferSizeInBytes = vertexBuffer.Buffer.Length;
            }

            var vertexStream = DataStream.Create(vertexBuffer.Buffer, true, true);

            for (int i = 0; i < assimpMesh.VertexCount; i++)
            {
                var position = assimpMesh.Vertices[i];
                vertexStream.Write(position);

                // Store bounding points for BoundingSphere pre-calculation
                boundingPoints[currentBoundingPointIndex++] = new Vector3(position.X, position.Y, position.Z);

                // Add normals
                if (assimpMesh.HasNormals)
                {
                    vertexStream.Write(assimpMesh.Normals[i]);
                }

                // Add colors
                if (assimpMesh.VertexColorChannelCount > 0)
                {
                    for (int j = 0; j < assimpMesh.VertexColorChannelCount; j++)
                    {
                        if (assimpMesh.HasVertexColors(j))
                        {
                            vertexStream.Write(assimpMesh.GetVertexColors(j)[i]);
                        }
                    }
                }

                // Add textures
                if (assimpMesh.TextureCoordsChannelCount > 0)
                {
                    for (int j = 0; j < assimpMesh.TextureCoordsChannelCount; j++)
                    {
                        if (assimpMesh.HasTextureCoords(j))
                        {
                            var uvCount = assimpMesh.GetUVComponentCount(j);

                            var uv = assimpMesh.GetTextureCoords(j)[i];

                            if (uvCount == 2)
                            {
                                vertexStream.Write(new Vector2(uv.X, uv.Y));
                            }
                            else
                            {
                                vertexStream.Write(uv);
                            }
                        }
                    }
                }

                // Add tangent / bitangent
                if (assimpMesh.HasTangentBasis)
                {
                    if (!options.ExcludeElements.Contains("Tangent"))
                    {
                        double w = Vector3D.Dot(assimpMesh.Normals[i],
                                                Vector3D.Cross(assimpMesh.Tangents[i], assimpMesh.Tangents[i]));
                        Vector3D t   = assimpMesh.Tangents[i];
                        Vector4  t4D = new Vector4(t.X, t.Y, t.Z, (float)w);
                        vertexStream.Write(t4D);
                    }
                    if (!options.ExcludeElements.Contains("BiTangent"))
                    {
                        vertexStream.Write(assimpMesh.BiTangents[i]);
                    }
                }
            }
            vertexStream.Dispose();
        }
Пример #13
0
        /// <summary>
        /// Draw a mesh using either its given material or a transparent "ghost" material.
        /// </summary>
        /// <param name="node">Current node</param>
        /// <param name="animated">Specifies whether animations should be played</param>
        /// <param name="showGhost">Indicates whether to substitute the mesh' material with a
        /// "ghost" surrogate material that allows looking through the geometry.</param>
        /// <param name="index">Mesh index in the scene</param>
        /// <param name="mesh">Mesh instance</param>
        /// <param name="flags"> </param>
        /// <returns></returns>
        protected override bool InternDrawMesh(Node node, bool animated, bool showGhost, int index, Mesh mesh, RenderFlags flags)
        {
            if (showGhost)
            {
                Owner.MaterialMapper.ApplyGhostMaterial(mesh, Owner.Raw.Materials[mesh.MaterialIndex], 
                    flags.HasFlag(RenderFlags.Shaded));
            }
            else
            {
                Owner.MaterialMapper.ApplyMaterial(mesh, Owner.Raw.Materials[mesh.MaterialIndex], 
                    flags.HasFlag(RenderFlags.Textured), 
                    flags.HasFlag(RenderFlags.Shaded));
            }

            if (GraphicsSettings.Default.BackFaceCulling)
            {
                GL.FrontFace(FrontFaceDirection.Ccw);
                GL.CullFace(CullFaceMode.Back);
                GL.Enable(EnableCap.CullFace);
            }
            else
            {
                GL.Disable(EnableCap.CullFace);
            }

            var hasColors = mesh.HasVertexColors(0);
            var hasTexCoords = mesh.HasTextureCoords(0);

            var skinning = mesh.HasBones && animated;

            foreach (var face in mesh.Faces)
            {
                BeginMode faceMode;
                switch (face.IndexCount)
                {
                    case 1:
                        faceMode = BeginMode.Points;
                        break;
                    case 2:
                        faceMode = BeginMode.Lines;
                        break;
                    case 3:
                        faceMode = BeginMode.Triangles;
                        break;
                    default:
                        faceMode = BeginMode.Polygon;
                        break;
                }

                GL.Begin(faceMode);
                for (var i = 0; i < face.IndexCount; i++)
                {
                    var indice = face.Indices[i];
                    if (hasColors)
                    {
                        var vertColor = AssimpToOpenTk.FromColor(mesh.VertexColorChannels[0][indice]);
                        GL.Color4(vertColor);
                    }
                    if (mesh.HasNormals)
                    {
                        Vector3 normal;
                        if (skinning)
                        {
                            Skinner.GetTransformedVertexNormal(node, mesh, (uint)indice, out normal);
                        }
                        else
                        {
                            normal = AssimpToOpenTk.FromVector(mesh.Normals[indice]);
                        }

                        GL.Normal3(normal);
                    }
                    if (hasTexCoords)
                    {
                        var uvw = AssimpToOpenTk.FromVector(mesh.TextureCoordinateChannels[0][indice]);
                        GL.TexCoord2(uvw.X, 1 - uvw.Y);
                    }

                    Vector3 pos;
                    if (skinning)
                    {
                        Skinner.GetTransformedVertexPosition(node, mesh, (uint)indice, out pos);
                    }
                    else
                    {
                        pos = AssimpToOpenTk.FromVector(mesh.Vertices[indice]);
                    }
                    GL.Vertex3(pos);
                }
                GL.End();
            }
            GL.Disable(EnableCap.CullFace);
            return skinning;
        }
Пример #14
0
        private ModelData.MeshPart Process(ModelData.Mesh mesh, Assimp.Mesh assimpMesh)
        {
            var meshPart = new ModelData.MeshPart()
            {
                MaterialIndex     = assimpMesh.MaterialIndex,
                VertexBufferRange = new ModelData.BufferRange()
                {
                    Slot = mesh.VertexBuffers.Count
                },
                IndexBufferRange = new ModelData.BufferRange()
                {
                    Slot = mesh.IndexBuffers.Count
                }
            };

            var vertexBuffer = new ModelData.VertexBuffer()
            {
                Layout = new List <VertexElement>()
            };

            mesh.VertexBuffers.Add(vertexBuffer);

            var indexBuffer = new ModelData.IndexBuffer();

            mesh.IndexBuffers.Add(indexBuffer);

            var layout = vertexBuffer.Layout;

            int vertexBufferElementSize = 0;

            // Add position
            layout.Add(VertexElement.PositionTransformed(Format.R32G32B32_Float, 0));
            vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>();

            // Add normals
            if (assimpMesh.HasNormals)
            {
                layout.Add(VertexElement.Normal(0, Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>();
            }

            // Add colors
            if (assimpMesh.VertexColorChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.VertexColorChannelCount; i++)
                {
                    if (assimpMesh.HasVertexColors(i))
                    {
                        layout.Add(VertexElement.Color(localIndex, Format.R32G32B32A32_Float, vertexBufferElementSize));
                        vertexBufferElementSize += Utilities.SizeOf <SharpDX.Color4>();
                        localIndex++;
                    }
                }
            }

            // Add textures
            if (assimpMesh.TextureCoordsChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.TextureCoordsChannelCount; i++)
                {
                    if (assimpMesh.HasTextureCoords(i))
                    {
                        var uvCount = assimpMesh.GetUVComponentCount(i);

                        if (uvCount == 2)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector2>();
                        }
                        else if (uvCount == 3)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32B32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>();
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexpected uv count");
                        }

                        localIndex++;
                    }
                }
            }

            // Add tangent / bitangent
            if (assimpMesh.HasTangentBasis)
            {
                layout.Add(VertexElement.Tangent(Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>();

                layout.Add(VertexElement.BiTangent(Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector3>();
            }

            // Extract Skinning Indices / Weights
            bool hasWeights      = false;
            var  skinningCount   = new int[assimpMesh.VertexCount];
            var  skinningIndices = new Int4[assimpMesh.VertexCount];
            var  skinningWeights = new Vector4[assimpMesh.VertexCount];

            if (assimpMesh.HasBones)
            {
                meshPart.BoneOffsetMatrices = new Matrix[assimpMesh.BoneCount];
                for (int i = 0; i < assimpMesh.Bones.Length; i++)
                {
                    var bone = assimpMesh.Bones[i];
                    meshPart.BoneOffsetMatrices[i] = ConvertMatrix(bone.OffsetMatrix);
                    if (bone.HasVertexWeights)
                    {
                        var boneNode  = scene.RootNode.FindNode(bone.Name);
                        var boneIndex = skinnedBones[boneNode];
                        for (int j = 0; j < bone.VertexWeightCount; j++)
                        {
                            var weights             = bone.VertexWeights[j];
                            var vertexSkinningCount = skinningCount[weights.VertexID];

                            skinningIndices[weights.VertexID][vertexSkinningCount] = boneIndex;

                            skinningWeights[weights.VertexID][vertexSkinningCount] = weights.Weight;

                            skinningCount[weights.VertexID] = ++vertexSkinningCount;
                        }

                        hasWeights = true;
                    }
                }

                if (hasWeights)
                {
                    layout.Add(VertexElement.BlendIndices(Format.R16G16B16A16_SInt, vertexBufferElementSize));
                    vertexBufferElementSize += Utilities.SizeOf <SharpDX.Int4>();

                    layout.Add(VertexElement.BlendWeights(Format.R32G32B32A32_Float, vertexBufferElementSize));
                    vertexBufferElementSize += Utilities.SizeOf <SharpDX.Vector4>();
                }
            }

            // Write all vertices
            meshPart.VertexBufferRange.Count = assimpMesh.VertexCount;
            vertexBuffer.Count  = assimpMesh.VertexCount;
            vertexBuffer.Buffer = new byte[vertexBufferElementSize * assimpMesh.VertexCount];

            // Update the MaximumBufferSizeInBytes needed to load this model
            if (vertexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes)
            {
                model.MaximumBufferSizeInBytes = vertexBuffer.Buffer.Length;
            }

            var vertexStream = DataStream.Create(vertexBuffer.Buffer, true, true);

            for (int i = 0; i < assimpMesh.VertexCount; i++)
            {
                var position = assimpMesh.Vertices[i];
                vertexStream.Write(position);

                // Store bounding points for BoundingSphere pre-calculation
                boundingPoints[currentBoundingPointIndex++] = new Vector3(position.X, position.Y, position.Z);

                // Add normals
                if (assimpMesh.HasNormals)
                {
                    vertexStream.Write(assimpMesh.Normals[i]);
                }

                // Add colors
                if (assimpMesh.VertexColorChannelCount > 0)
                {
                    for (int j = 0; j < assimpMesh.VertexColorChannelCount; j++)
                    {
                        if (assimpMesh.HasVertexColors(j))
                        {
                            vertexStream.Write(assimpMesh.GetVertexColors(j)[i]);
                        }
                    }
                }

                // Add textures
                if (assimpMesh.TextureCoordsChannelCount > 0)
                {
                    for (int j = 0; j < assimpMesh.TextureCoordsChannelCount; j++)
                    {
                        if (assimpMesh.HasTextureCoords(j))
                        {
                            var uvCount = assimpMesh.GetUVComponentCount(j);

                            var uv = assimpMesh.GetTextureCoords(j)[i];

                            if (uvCount == 2)
                            {
                                vertexStream.Write(new Vector2(uv.X, uv.Y));
                            }
                            else
                            {
                                vertexStream.Write(uv);
                            }
                        }
                    }
                }

                // Add tangent / bitangent
                if (assimpMesh.HasTangentBasis)
                {
                    vertexStream.Write(assimpMesh.Tangents[i]);
                    vertexStream.Write(assimpMesh.BiTangents[i]);
                }

                // Add Skinning Indices/Weights
                if (assimpMesh.HasBones && hasWeights)
                {
                    vertexStream.Write(skinningIndices[i]);
                    vertexStream.Write(skinningWeights[i]);
                }
            }
            vertexStream.Dispose();

            // Write all indices
            var indices = assimpMesh.GetIntIndices();

            indexBuffer.Count = indices.Length;
            meshPart.IndexBufferRange.Count = indices.Length;
            if (meshPart.VertexBufferRange.Count < 65536)
            {
                // Write only short indices if count is less than the size of a short
                indexBuffer.Buffer = new byte[indices.Length * 2];
                using (var indexStream = DataStream.Create(indexBuffer.Buffer, true, true))
                    foreach (int index in indices)
                    {
                        indexStream.Write((ushort)index);
                    }
            }
            else
            {
                // Otherwise, use full 32-bit precision to store indices
                indexBuffer.Buffer = new byte[indices.Length * 4];
                using (var indexStream = DataStream.Create(indexBuffer.Buffer, true, true))
                    indexStream.WriteRange(indices);
            }

            // Update the MaximumBufferSizeInBytes needed to load this model
            if (indexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes)
            {
                model.MaximumBufferSizeInBytes = indexBuffer.Buffer.Length;
            }

            return(meshPart);
        }
Пример #15
0
            private void CreateBuffers(Node assimpnode, ModelNode parent_node, ref Matrix4x4 model_matrix)
            {
                // create new mesh
                ModelNode node = new ModelNode(_openGLFactory);

                if (parent_node != null)
                {
                    parent_node.AddChild(node);
                }
                else
                {
                    _model._root_node = node;
                }

                // set model matrix
                Matrix4x4 mm = assimpnode.Transform;

                node.ModelMatrix = new Matrix4(
                    mm.A1, mm.A2, mm.A3, mm.A4,
                    mm.B1, mm.B2, mm.B3, mm.B4,
                    mm.C1, mm.C2, mm.C3, mm.C4,
                    mm.D1, mm.D2, mm.D3, mm.D4);

                // combined model matrix
                Matrix4x4 prev_model    = model_matrix;
                Matrix4x4 new_transform = assimpnode.Transform;

                model_matrix = new_transform * model_matrix; // ? has this to be reversed link in OpneTK?

                if (assimpnode.HasMeshes)
                {
                    foreach (int index in assimpnode.MeshIndices)
                    {
                        Assimp.Mesh assimpmesh = _assimpmodel.Meshes[index];
                        AABB        mesh_box   = new AABB();

                        // extend bounding box by vertices
                        for (int i = 0; i < assimpmesh.VertexCount; i++)
                        {
                            Vector3D tmp = assimpmesh.Vertices[i];
                            mesh_box = mesh_box | new Vector3(tmp.X, tmp.Y, tmp.Z);

                            tmp = model_matrix * tmp;
                            _model._scene_box = _model._scene_box | new Vector3(tmp.X, tmp.Y, tmp.Z);
                        }

                        // create Mesh
                        uint tuple_index = 0;
                        List <TVertexFormat> formalist = new List <TVertexFormat>();

                        OpenTK_library.Scene.Mesh mesh = new OpenTK_library.Scene.Mesh();
                        mesh.Box = mesh_box;
                        node.Add(mesh);

                        // specify vertices
                        mesh.VertexAttribute = (tuple_index, 3);
                        formalist.Add(new TVertexFormat(0, vertex_index, 3, (int)tuple_index, false));
                        tuple_index += 3;

                        // specify normals
                        if (assimpmesh.HasNormals)
                        {
                            mesh.NormalAttribute = (tuple_index, 3);
                            formalist.Add(new TVertexFormat(0, normal_index, 3, (int)tuple_index, false));
                            tuple_index += 3;
                        }

                        // specify bi-normals and tangents
                        if (assimpmesh.HasTangentBasis)
                        {
                            mesh.BinormalAttribute = (tuple_index, 3);
                            formalist.Add(new TVertexFormat(0, binormal_index, 3, (int)tuple_index, false));
                            tuple_index += 3;

                            mesh.TangentAttribute = (tuple_index, 3);
                            formalist.Add(new TVertexFormat(0, tangent_index, 3, (int)tuple_index, false));
                            tuple_index += 3;
                        }

                        // specify texture channels
                        for (int textur_channel = 0; assimpmesh.HasTextureCoords(textur_channel); ++textur_channel)
                        {
                            mesh.AddTextureAttrib((tuple_index, 3));
                            int attr_i = textur_channel == 0 ? texture0_index : (textureN_index + textur_channel - 1);
                            formalist.Add(new TVertexFormat(0, attr_i, 3, (int)tuple_index, false));
                            tuple_index += 3;
                        }

                        // specify color channels
                        for (int color_channel = 0; assimpmesh.HasVertexColors(color_channel); ++color_channel)
                        {
                            mesh.AddColorAttrib((tuple_index, 4));
                            int attr_i = color_channel == 0 ? color0_index : (colorN_index + color_channel - 1);
                            formalist.Add(new TVertexFormat(0, attr_i, 4, (int)tuple_index, false));
                            tuple_index += 4;
                        }

                        // TODO $$$ bones
                        if (assimpmesh.HasBones)
                        {
                            // [...]
                            Console.WriteLine("bones not yet implemented");
                        }

                        // set tuple size
                        mesh.TupleSize = tuple_index;

                        // setup index buffer
                        List <float> attributes = new List <float>();
                        List <uint>  indices    = new List <uint>();
                        uint         elem_index = 0;
                        foreach (Face face in assimpmesh.Faces)
                        {
                            if (face.IndexCount < 3)
                            {
                                continue; // lines?
                            }
                            for (uint i = 2; i < (uint)face.IndexCount; i++)
                            {
                                indices.Add(elem_index);
                                indices.Add(elem_index + 1);
                                indices.Add(elem_index + i);
                            }
                            elem_index += (uint)face.IndexCount;

                            for (int i = 0; i < face.IndexCount; i++)
                            {
                                int ei = face.Indices[i];

                                // add vertex attribute
                                var vertex = assimpmesh.Vertices[ei];
                                attributes.Add(vertex.X);
                                attributes.Add(vertex.Y);
                                attributes.Add(vertex.Z);

                                // add normals
                                if (assimpmesh.HasNormals)
                                {
                                    var normal = assimpmesh.Normals[ei];
                                    attributes.Add(normal.X);
                                    attributes.Add(normal.Y);
                                    attributes.Add(normal.Z);
                                }

                                // add bi-normals and tangents
                                if (assimpmesh.HasTangentBasis)
                                {
                                    var binormal = assimpmesh.BiTangents[ei];
                                    attributes.Add(binormal.X);
                                    attributes.Add(binormal.Y);
                                    attributes.Add(binormal.Z);

                                    var tangent = assimpmesh.Tangents[ei];
                                    attributes.Add(tangent.X);
                                    attributes.Add(tangent.Y);
                                    attributes.Add(tangent.Z);
                                }

                                // add texture coordinates
                                for (int textur_channel = 0; assimpmesh.HasTextureCoords(textur_channel); ++textur_channel)
                                {
                                    var uvw = assimpmesh.TextureCoordinateChannels[textur_channel][ei];
                                    attributes.Add(uvw.X);
                                    attributes.Add(uvw.Y);
                                    attributes.Add(uvw.Z);
                                }

                                // add color attributes
                                for (int color_channel = 0; assimpmesh.HasVertexColors(color_channel); ++color_channel)
                                {
                                    var vertColor = assimpmesh.VertexColorChannels[color_channel][ei];
                                    attributes.Add(vertColor.R);
                                    attributes.Add(vertColor.G);
                                    attributes.Add(vertColor.B);
                                    attributes.Add(vertColor.A);
                                }
                            }
                        }

                        // setup vertex arrays and index array
                        TVertexFormat[] format = formalist.ToArray();
                        var             vao    = _openGLFactory.NewVertexArrayObject();
                        vao.AppendVertexBuffer(0, (int)tuple_index, attributes.ToArray());
                        vao.Create(format, indices.ToArray());

                        mesh.FaceSize    = 3;
                        mesh.VertexArray = vao;
                    }
                }

                for (int i = 0; i < assimpnode.ChildCount; i++)
                {
                    CreateBuffers(assimpnode.Children[i], node, ref model_matrix);
                }
                model_matrix = prev_model;
            }
Пример #16
0
        private Mesh ProcessMesh(Assimp.Mesh mesh, Scene scene)
        {
            List <Vertex>      vertices = new List <Vertex>();
            List <uint>        indices  = new List <uint>();
            List <TextureInfo> textures = new List <TextureInfo>();

            for (int i = 0; i < mesh.VertexCount; i++)
            {
                Vertex  vertex = new Vertex();
                Vector3 vector;

                vector.X        = mesh.Vertices[i].X;
                vector.Y        = mesh.Vertices[i].Y;
                vector.Z        = mesh.Vertices[i].Z;
                vertex.Position = vector;


                vector.X      = mesh.Normals[i].X;
                vector.Y      = mesh.Normals[i].Y;
                vector.Z      = mesh.Normals[i].Z;
                vertex.Normal = vector;

                if (mesh.HasTextureCoords(0))
                {
                    Vector2 vec;
                    vec.X            = mesh.TextureCoordinateChannels[0][i].X;
                    vec.Y            = mesh.TextureCoordinateChannels[0][i].Y;
                    vertex.TexCoords = vec;
                }
                else
                {
                    vertex.TexCoords = Vector2.Zero;
                }

                vector.X       = mesh.Tangents[i].X;
                vector.Y       = mesh.Tangents[i].Y;
                vector.Z       = mesh.Tangents[i].Z;
                vertex.Tangent = vector;
                // bitangent
                vector.X         = mesh.BiTangents[i].X;
                vector.Y         = mesh.BiTangents[i].Y;
                vector.Z         = mesh.Tangents[i].Z;
                vertex.Bitangent = vector;

                vertices.Add(vertex);
            }

            for (int i = 0; i < mesh.FaceCount; i++)
            {
                Face face = mesh.Faces[i];
                // retrieve all indices of the face and store them in the indices vector
                for (int j = 0; j < face.IndexCount; j++)
                {
                    indices.Add((uint)face.Indices[j]);
                    //Console.WriteLine(face.Indices[j]);
                }
            }
            Material material = scene.Materials[mesh.MaterialIndex];

            /*int test = 0;
             * foreach (TextureSlot slot in material.GetAllMaterialTextures())
             * {
             *      if (!paths.Contains(slot.FilePath))
             *      {
             *              Console.WriteLine(slot.TextureType + " -- " + slot.FilePath);
             *              paths.Add(slot.FilePath);
             *              test++;
             *      }
             * }*/

            List <TextureInfo> diffuseMaps = LoadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse");

            textures.AddRange(diffuseMaps);
            // 2. specular maps
            List <TextureInfo> specularMaps = LoadMaterialTextures(material, TextureType.Specular, "texture_specular");

            textures.AddRange(specularMaps);
            // 3. normal maps
            List <TextureInfo> normalMaps = LoadMaterialTextures(material, TextureType.Height, "texture_normal");

            textures.AddRange(normalMaps);
            // 4. height maps
            List <TextureInfo> heightMaps = LoadMaterialTextures(material, TextureType.Ambient, "texture_height");

            textures.AddRange(heightMaps);

            return(new Mesh(vertices.ToArray(), indices.ToArray(), textures.ToArray()));
        }
Пример #17
0
        Mesh processMesh(Assimp.Mesh mesh, Scene scene)
        {
            List <VertexStruct>  vertices = new List <VertexStruct>();
            List <int>           indices  = new List <int>();
            List <TextureStruct> textures = new List <TextureStruct>();


            // process vertices
            for (int i = 0; i < mesh.VertexCount; i++)
            {
                VertexStruct vertex = new VertexStruct();
                Vector3      vector3;
                vector3         = new Vector3(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z);
                vertex.Position = vector3;
                if (mesh.HasNormals)
                {
                    vector3       = new Vector3(mesh.Normals[i].X, mesh.Normals[i].Y, mesh.Normals[i].Z);
                    vertex.Normal = vector3;
                }
                if (mesh.HasTextureCoords(0))
                {
                    Vector2 vector2 = new Vector2();
                    vector2.X        = mesh.TextureCoordinateChannels[0][i].X;
                    vector2.Y        = mesh.TextureCoordinateChannels[0][i].Y;
                    vertex.TexCoords = vector2;
                }
                else
                {
                    vertex.TexCoords = new Vector2(0.0f, 0.0f);
                }
                vertices.Add(vertex);
            }

            // process indices
            for (int i = 0; i < mesh.FaceCount; i++)
            {
                Face face = mesh.Faces[i];
                for (int j = 0; j < face.IndexCount; j++)
                {
                    indices.Add(face.Indices[j]);
                }
            }

            // process material
            if (mesh.MaterialIndex >= 0)
            {
                Material material = scene.Materials[mesh.MaterialIndex];
                //System.Console.WriteLine(material.Name + " " + material.ShadingMode);
                TextureStruct[] diffuseMaps = loadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse");
                for (int i = 0; i < diffuseMaps.Length; i++)
                {
                    textures.Add(diffuseMaps[i]);
                }
                TextureStruct[] specularMaps = loadMaterialTextures(material, TextureType.Specular, "texture_specular");
                for (int i = 0; i < specularMaps.Length; i++)
                {
                    textures.Add(specularMaps[i]);
                }
            }

            return(new Mesh(mesh.Name, vertices.ToArray(), indices.ToArray(), textures.ToArray()));
        }
Пример #18
0
		void GetVertexFormat (Mesh mesh, int boneCount, out VertexFlags flags, out int stride) {
			stride = 3;
			flags = 0;
			if (mesh.HasNormals) {
				stride += 3;
				flags |= VertexFlags.Normal;
			}
			if (mesh.HasTextureCoords(0)) {
				stride += 2;
				flags |= VertexFlags.TexCoord0;
			}
			if (mesh.HasTextureCoords(1)) {
				stride += 2;
				flags |= VertexFlags.TexCoord0;
			}
			if (mesh.HasTextureCoords(2)) {
				stride += 2;
				flags |= VertexFlags.TexCoord0;
			}
			if (mesh.HasTextureCoords(3)) {
				stride += 2;
				flags |= VertexFlags.TexCoord0;
			}
			if (mesh.HasVertexColors(0)) {
				stride += 4;
				flags |= VertexFlags.Color0;
			}
			if (mesh.HasVertexColors(1)) {
				stride += 4;
				flags |= VertexFlags.Color1;
			}
			if (mesh.HasVertexColors(2)) {
				stride += 4;
				flags |= VertexFlags.Color2;
			}
			if (mesh.HasVertexColors(3)) {
				stride += 4;
				flags |= VertexFlags.Color3;
			}
			stride += boneCount * 2;
		}
Пример #19
0
        public void Build(
            string filename,
            string intermediateDir,
            string outputDir,
            MyModelConfiguration configuration,
            byte[] havokCollisionShapes,
            bool checkOpenBoundaries,
            float[] lodDistances,
            bool overrideLods,
            Func <string, MyMaterialConfiguration> getMaterialByRef,
            IMyBuildLogger logger)
        {
            logger.LogMessage(MessageType.Info, "**FileName: " + filename);

            string withoutExtension = Path.GetFileNameWithoutExtension(filename);

            logger.LogMessage(MessageType.Info, "**Filename (without extension): " + withoutExtension);

            string directoryName = Path.GetDirectoryName(filename);

            logger.LogMessage(MessageType.Info, "**Directory Name: " + directoryName);

            //string contentDirectoryString = "content";
            // int numberOfPathCharactersToCull = directoryName.ToLower().LastIndexOf(contentDirectoryString) + contentDirectoryString.Length + 1;

            var numberOfPathCharactersToCull = filename.LastIndexOf("models\\", StringComparison.OrdinalIgnoreCase);

            if (numberOfPathCharactersToCull == -1)
            {
                throw new Exception("Couldn't find 'models\\' in path provided: " + filename);
            }

            logger.LogMessage(MessageType.Info, "**Number of characters to cull: " + numberOfPathCharactersToCull);
            string culledPath = directoryName.Substring(numberOfPathCharactersToCull, directoryName.Length - numberOfPathCharactersToCull); // Used to cull 'content' from path name to create relative pathing.

            logger.LogMessage(MessageType.Info, "**Culled Path: " + culledPath);

            directoryName.Substring(0, numberOfPathCharactersToCull);
            Path.Combine(directoryName, withoutExtension + ".FBX");
            AssimpContext assimpContext = new AssimpContext();

            assimpContext.SetConfig((PropertyConfig) new NormalSmoothingAngleConfig(66f));
            assimpContext.SetConfig((PropertyConfig) new FBXPreservePivotsConfig(false));
            Scene scene = assimpContext.ImportFile(filename,
                                                   PostProcessSteps.CalculateTangentSpace |
                                                   PostProcessSteps.JoinIdenticalVertices |
                                                   PostProcessSteps.Triangulate |
                                                   PostProcessSteps.GenerateSmoothNormals |
                                                   PostProcessSteps.SplitLargeMeshes |
                                                   PostProcessSteps.LimitBoneWeights |
                                                   PostProcessSteps.SortByPrimitiveType |
                                                   PostProcessSteps.FindInvalidData |
                                                   PostProcessSteps.GenerateUVCoords |
                                                   PostProcessSteps.FlipWindingOrder);

            string outputDir1 = outputDir;

            if (scene.MeshCount == 0 && scene.AnimationCount == 0)
            {
                throw new Exception("Number of meshes is 0 and no animation present!");
            }
            else
            {
                logger.LogMessage(MessageType.Info, "Found " + scene.MeshCount + " meshe(s).", "Meshes");
                logger.LogMessage(MessageType.Info, "Found " + scene.AnimationCount + " animation(s).", "Animations");
            }

            #region check UV for 0-sized faces
            if (scene.MeshCount > 0)
            {
                void LogUVError(Assimp.Mesh mesh, string message)
                {
                    //logger.LogMessage(MessageType.Error, $"Mesh '{mesh.Name}' {message}");
                    throw new Exception($"Mesh '{mesh.Name}' {message}");
                }

                for (int meshIdx = 0; meshIdx < scene.MeshCount; meshIdx++)
                {
                    Assimp.Mesh mesh = scene.Meshes[meshIdx];

                    if (mesh.TextureCoordinateChannels == null || mesh.TextureCoordinateChannels.Length == 0)
                    {
                        LogUVError(mesh, "has no UV map/channel!");
                        continue;
                    }

                    int channels = 1; // don't care about other channels; if you want to, replace with: mesh.TextureCoordinateChannels.Length;
                    for (int chIdx = 0; chIdx < channels; chIdx++)
                    {
                        if (!mesh.HasTextureCoords(0))
                        {
                            LogUVError(mesh, "has no UV map/channel!");
                            continue;
                        }

                        List <Assimp.Vector3D> vectors = mesh.TextureCoordinateChannels[chIdx];
                        if (vectors == null || vectors.Count == 0)
                        {
                            LogUVError(mesh, "has no UV vectors in first map/channel!");
                            continue;
                        }

                        //Console.WriteLine($"  channel={chIdx}");
                        //for (int v = 0; v < vectors.Count; v++)
                        //{
                        //    Console.WriteLine($"  {v} == {vectors[v]}");
                        //}

                        Assimp.Vector3D?lastVec       = null;
                        int             sameVecInARow = 1;

                        // these can be triangles, quads and prob more... so not safe to assume they're in pairs of 3.
                        for (int v = 0; v < vectors.Count; v++)
                        {
                            Assimp.Vector3D vec = vectors[v];

                            if (!lastVec.HasValue)
                            {
                                lastVec = vec;
                            }
                            else
                            {
                                if (lastVec.Value == vec)
                                {
                                    sameVecInARow++;

                                    if (sameVecInARow >= 3)
                                    {
                                        // Changed this to a warning instead of a LogUVError
                                        logger.LogMessage(MessageType.Warning, mesh.ToString() + "has UV with 3 identical vectors in a row, this likely means you have a face with an UV is 0-size which will cause SE to make the entire model shaderless.");
                                        break;
                                    }
                                }
                                else
                                {
                                    lastVec       = vec;
                                    sameVecInARow = 1;
                                }
                            }
                        }
                    }
                }
            }
            #endregion

            if (scene.MaterialCount > 0)
            {
                List <MyMaterialConfiguration> materialConfigurationList = new List <MyMaterialConfiguration>();
                for (int index = 0; index < scene.MaterialCount; ++index)
                {
                    MyMaterialConfiguration materialConfiguration = getMaterialByRef(scene.Materials[index].Name);
                    if (materialConfiguration != null)
                    {
                        materialConfigurationList.Add(materialConfiguration);
                    }
                }
                if (materialConfigurationList.Count > 0)
                {
                    configuration.Materials = configuration.Materials != null ? ((IEnumerable <MyMaterialConfiguration>)configuration.Materials).Union <MyMaterialConfiguration>((IEnumerable <MyMaterialConfiguration>)materialConfigurationList.ToArray()).ToArray <MyMaterialConfiguration>() : materialConfigurationList.ToArray();
                }
            }

            MyModelProcessor processor = this.CreateProcessor(configuration);
            if (configuration.Materials != null)
            {
                foreach (MyMaterialConfiguration material in configuration.Materials)
                {
                    try
                    {
                        Dictionary <string, object> dictionary = new Dictionary <string, object>();
                        if (processor.MaterialProperties.Keys.Contains <string>(material.Name))
                        {
                            logger.LogMessage(MessageType.Warning, "Material: " + material.Name + " is already defined in the processor. Not adding it again..", filename);
                        }
                        else
                        {
                            processor.MaterialProperties.Add(material.Name, dictionary);
                            foreach (MyModelParameter parameter in material.Parameters)
                            {
                                dictionary.Add(parameter.Name, (object)parameter.Value);
                            }
                        }
                    }
                    catch (ArgumentException ex)
                    {
                        logger.LogMessage(MessageType.Warning, "Problem when processing materials: " + ex.Message, filename);
                    }
                }
            }
            int num2 = 999;
            List <MyLODDescriptor> myLodDescriptorList = new List <MyLODDescriptor>();
            for (int index = 0; index < num2; ++index)
            {
                string path = Path.Combine(directoryName, withoutExtension + "_LOD" + (object)(index + 1)) + ".fbx";
                string str2 = Path.Combine(culledPath, withoutExtension + "_LOD" + (object)(index + 1));

                if (File.Exists(path))
                {
                    if (overrideLods && lodDistances != null && (index < lodDistances.Length && (double)lodDistances[index] > 0.0))
                    {
                        MyLODDescriptor myLodDescriptor = new MyLODDescriptor()
                        {
                            Distance = lodDistances[index],
                            Model    = str2
                        };
                        myLodDescriptorList.Add(myLodDescriptor);
                    }
                    else if (configuration.LODs != null && index < configuration.LODs.Length)
                    {
                        MyLODConfiguration loD             = configuration.LODs[index];
                        MyLODDescriptor    myLodDescriptor = new MyLODDescriptor()
                        {
                            Distance      = loD.Distance,
                            Model         = str2,
                            RenderQuality = loD.RenderQuality
                        };


                        if (str2.ToLower() != loD.Model.ToLower())
                        {
                            logger.LogMessage(MessageType.Warning, "LOD" + (object)(index + 1) + " name differs " + str2 + " and " + loD.Model, filename);
                        }
                        myLodDescriptorList.Add(myLodDescriptor);
                    }
                    else
                    {
                        logger.LogMessage(MessageType.Warning, "LOD" + (object)(index + 1) + " model exists but configuration is missing", filename);
                    }
                }
                else if (configuration.LODs != null && index < configuration.LODs.Length)
                {
                    logger.LogMessage(MessageType.Warning, "LOD model " + configuration.LODs[index].Model + " is missing", filename);
                }
                else
                {
                    break;
                }
            }
            processor.LODs                 = myLodDescriptorList.ToArray();
            processor.BoneGridMapping      = configuration.BoneGridSize;
            processor.BoneMapping          = configuration.BoneMapping != null ? ((IEnumerable <MyModelVector>)configuration.BoneMapping).Select <MyModelVector, Vector3>((Func <MyModelVector, Vector3>)(s => new Vector3((float)s.X, (float)s.Y, (float)s.Z))).ToArray <Vector3>() : (Vector3[])null;
            processor.HavokCollisionShapes = havokCollisionShapes;
            processor.Process(scene, filename, outputDir1, checkOpenBoundaries, logger);
            if (configuration.BoneGridSize.HasValue)
            {
                configuration.BoneMapping = ((IEnumerable <Vector3>)processor.BoneMapping).Select <Vector3, MyModelVector>((Func <Vector3, MyModelVector>)(s => (MyModelVector)s)).ToArray <MyModelVector>();
            }
            List <MyMaterialConfiguration> materialConfigurationList1 = new List <MyMaterialConfiguration>();
            foreach (KeyValuePair <string, Dictionary <string, object> > materialProperty in processor.MaterialProperties)
            {
                materialConfigurationList1.Add(new MyMaterialConfiguration()
                {
                    Name       = materialProperty.Key,
                    Parameters = MyModelBuilder.GetParameters(materialProperty)
                });
            }
            configuration.Materials = materialConfigurationList1.Count <= 0 ? (MyMaterialConfiguration[])null : materialConfigurationList1.ToArray();
            if (processor.LODs == null)
            {
                return;
            }
            List <MyLODConfiguration> lodConfigurationList = new List <MyLODConfiguration>();
            foreach (MyLODDescriptor loD in processor.LODs)
            {
                lodConfigurationList.Add(new MyLODConfiguration()
                {
                    Distance      = loD.Distance,
                    Model         = loD.Model,
                    RenderQuality = loD.RenderQuality
                });
            }
            configuration.LODs = lodConfigurationList.ToArray();
        }
Пример #20
0
        // Processa a malha lida pelo Assimp
        private Mesh ProcessMesh(Assimp.Mesh amesh, Assimp.Scene scene)
        {
            List <Vertex>  vertices = new List <Vertex>();
            List <uint>    indices  = new List <uint>();
            List <Texture> textures = new List <Texture>();
            Random         r        = new Random();

            // Carrego pela malha do Assimp, a lista de vértice com a normal, UV (ST), tangente, bitangente
            for (int i = 0; i < amesh.VertexCount; i++)
            {
                Vertex vertex = new Vertex();
                vertex.positionX = amesh.Vertices[i].X;
                vertex.positionY = amesh.Vertices[i].Y;
                vertex.positionZ = amesh.Vertices[i].Z;
                if (amesh.HasNormals)
                {
                    vertex.normalX = amesh.Normals[i].X;
                    vertex.normalY = amesh.Normals[i].Y;
                    vertex.normalZ = amesh.Normals[i].Z;
                }

                if (amesh.HasTextureCoords(0))
                {
                    vertex.textureX   = amesh.TextureCoordinateChannels[0][i].X;
                    vertex.textureY   = amesh.TextureCoordinateChannels[0][i].Y;
                    vertex.bitangentX = amesh.BiTangents[i].X;
                    vertex.bitangentY = amesh.BiTangents[i].Y;
                    vertex.bitangentZ = amesh.BiTangents[i].Z;
                    vertex.tangentX   = amesh.Tangents[i].X;
                    vertex.tangentY   = amesh.Tangents[i].Y;
                    vertex.tangentZ   = amesh.Tangents[i].Z;
                }
                else
                {
                    vertex.textureX = 0f;
                    vertex.textureY = 0f;
                }
                vertex.colorA = (float)r.NextDouble();
                vertex.colorR = (float)r.NextDouble();
                vertex.colorB = (float)r.NextDouble();
                vertex.colorG = 1f;
                vertices.Add(vertex);
            }

            // Carrega as informações das faces dos triâgulos, ou seja, informa quais vertices formam um triângulo da malha
            for (int i = 0; i < amesh.FaceCount; i++)
            {
                Assimp.Face face = amesh.Faces[i];
                for (int j = 0; j < face.IndexCount; j++)
                {
                    indices.Add((uint)face.Indices[j]);
                }
            }

            // Verifica se possui alguma textura ou arquivo mtl vinculado ao obj
            if (amesh.MaterialIndex >= 0)
            {
                Assimp.Material material    = scene.Materials[amesh.MaterialIndex];
                List <Texture>  diffuseMaps = loadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse");
                textures.InsertRange(textures.Count, diffuseMaps);
                List <Texture> specularMaps = loadMaterialTextures(material, TextureType.Specular, "texture_specular");
                textures.InsertRange(textures.Count, specularMaps);
                List <Texture> normalMaps = loadMaterialTextures(material, TextureType.Height, "texture_normal");
                textures.InsertRange(textures.Count, normalMaps);
            }

            return(new Mesh(vertices, indices, textures));
        }
Пример #21
0
        private MonoKnight.Mesh ProcessMesh(Assimp.Mesh mesh, Assimp.Scene scene)
        {
            List <Vertex>  vertices = new List <Vertex>();
            List <int>     indices  = new List <int>();
            List <Texture> textures = new List <Texture>();

            //         var boneDic = new Dictionary<string, Bone>();
            ////
            //var invertGlobalTransform = AssimpMat4ToOpenTKMat4(scene.RootNode.Transform).Inverted();
            //       //
            //       if(mesh.HasBones)
            //       {
            //           for (int i = 0; i < mesh.BoneCount; i++)
            //           {
            //               var assimpBone = mesh.Bones[i];
            //               if (!boneDic.ContainsKey(assimpBone.Name))
            //{
            //                   var bone = new Bone();
            //                   bone.name = assimpBone.Name;
            //                   bone.offset = AssimpMat4ToOpenTKMat4(assimpBone.OffsetMatrix);
            //	for (int j = 0; j < assimpBone.VertexWeightCount; j++)
            //	{
            //		VertexWeight vertexWeight;
            //		vertexWeight.vertexId = assimpBone.VertexWeights[j].VertexID;
            //		vertexWeight.weight = assimpBone.VertexWeights[j].Weight;
            //		bone.weightList.Add(vertexWeight);
            //	}
            //	boneDic[assimpBone.Name] = bone;
            //}
            //    }
            //}
            //
            for (int i = 0; i < mesh.VertexCount; i++)
            {
                Vertex  vertex = new Vertex();
                Vector3 vector = new Vector3();
                vector.X        = mesh.Vertices[i].X;
                vector.Y        = mesh.Vertices[i].Y;
                vector.Z        = mesh.Vertices[i].Z;
                vertex.position = vector;
                //
                if (mesh.HasNormals)
                {
                    vector.X      = mesh.Normals[i].X;
                    vector.Y      = mesh.Normals[i].Y;
                    vector.Z      = mesh.Normals[i].Z;
                    vertex.normal = vector;
                }
                else
                {
                    vertex.normal = Vector3.Zero;
                }
                //
                if (mesh.HasTextureCoords(0))
                {
                    Vector2 vec = new Vector2();
                    vec.X           = mesh.TextureCoordinateChannels[0][i].X;
                    vec.Y           = mesh.TextureCoordinateChannels[0][i].Y;
                    vertex.texCoord = vec;
                }
                else
                {
                    vertex.texCoord = new Vector2(0.0f, 0.0f);
                }
                vertices.Add(vertex);
            }

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

            if (mesh.MaterialIndex >= 0)
            {
                Assimp.Material material = scene.Materials[mesh.MaterialIndex];

                for (int i = 0; i < material.GetMaterialTextures(TextureType.Diffuse).Length; i++)
                {
                    var     texSlot = material.GetMaterialTextures(TextureType.Diffuse)[i];
                    Texture texture = new Texture();
                    texture.LoadFromPath(Path.Combine(modelDirPath, texSlot.FilePath));
                    textures.Add(texture);
                }
                //TODO other type texture
            }
            //
            return(new Mesh(ref vertices, ref indices, ref textures));
        }
Пример #22
0
        private void LoadFromNode(Assimp.Scene _scene, Assimp.Node _node, GraphicsDevice _device, SharpDX.Toolkit.Content.ContentManager _content, Matrix _transform)
        {
            // Sum up transformations recursively
            _transform = FromMatrix(_node.Transform) * _transform;
            Matrix transformInvTr = Helpers.CreateInverseTranspose(ref _transform);

            // Recursive load from scene
            if (_node.HasChildren)
            {
                foreach (Assimp.Node node in _node.Children)
                {
                    LoadFromNode(_scene, node, _device, _content, _transform);
                }
            }

            if (_node.HasMeshes)
            {
                foreach (int meshIndex in _node.MeshIndices)
                {
                    Assimp.Mesh mesh      = _scene.Meshes[meshIndex];
                    ModelMesh   modelMesh = new ModelMesh();

                    // if mesh has a diffuse texture extract it
                    Assimp.Material material = _scene.Materials[mesh.MaterialIndex];
                    if (material != null && material.GetTextureCount(TextureType.Diffuse) > 0)
                    {
                        TextureSlot texture = material.GetTexture(TextureType.Diffuse, 0);
                        // Create new texture for mesh
                        var dxtexture = _content.Load <Texture2D>(texture.FilePath);
                        modelMesh.DiffuseTexture = dxtexture;
                    }

                    // Position is mandarory
                    if (!mesh.HasVertices)
                    {
                        throw new Exception("Model::Model(): Model has no vertices.");
                    }

                    // Determine the elements in the vertex
                    bool hasTexCoords  = mesh.HasTextureCoords(0);
                    bool hasColors     = mesh.HasVertexColors(0);
                    bool hasNormals    = mesh.HasNormals;
                    bool hasTangents   = mesh.Tangents != null;
                    bool hasBitangents = mesh.BiTangents != null;
                    int  numElements   = 1 + (hasTexCoords ? 1 : 0) + (hasColors ? 1 : 0) + (hasNormals ? 1 : 0) + (hasTangents ? 1 : 0) + (hasBitangents ? 1 : 0);

                    // Create vertex element list: Here starts the section of creating SharpDX stuff
                    VertexElement[] vertexElements = new VertexElement[numElements];
                    uint            elementIndex   = 0;
                    vertexElements[elementIndex++] = new VertexElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0);
                    int vertexSize = Utilities.SizeOf <Vector3>();

                    if (hasColors)
                    {
                        vertexElements[elementIndex++] = new VertexElement("COLOR", 0, SharpDX.DXGI.Format.R8G8B8A8_UInt, vertexSize);
                        vertexSize += Utilities.SizeOf <Color>();
                    }
                    if (hasNormals)
                    {
                        vertexElements[elementIndex++] = new VertexElement("NORMAL", 0, SharpDX.DXGI.Format.R32G32B32_Float, vertexSize);
                        vertexSize += Utilities.SizeOf <Vector3>();
                    }
                    if (hasTangents)
                    {
                        vertexElements[elementIndex++] = new VertexElement("TANGENT", 0, SharpDX.DXGI.Format.R32G32B32_Float, vertexSize);
                        vertexSize += Utilities.SizeOf <Vector3>();
                    }
                    if (hasBitangents)
                    {
                        vertexElements[elementIndex++] = new VertexElement("BITANGENT", 0, SharpDX.DXGI.Format.R32G32B32_Float, vertexSize);
                        vertexSize += Utilities.SizeOf <Vector3>();
                    }
                    if (hasTexCoords)
                    {
                        vertexElements[elementIndex++] = new VertexElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, vertexSize);
                        vertexSize += Utilities.SizeOf <Vector2>();
                    }

                    // Set the vertex elements and size
                    modelMesh.InputLayout = VertexInputLayout.New(VertexBufferLayout.New(0, vertexElements));
                    modelMesh.VertexSize  = vertexSize;

                    // Determine primitive type
                    switch (mesh.PrimitiveType)
                    {
                    case Assimp.PrimitiveType.Point:    modelMesh.PrimitiveTopology = SharpDX.Toolkit.Graphics.PrimitiveType.PointList;    break;

                    case Assimp.PrimitiveType.Line:     modelMesh.PrimitiveTopology = SharpDX.Toolkit.Graphics.PrimitiveType.LineList;     break;

                    case Assimp.PrimitiveType.Triangle: modelMesh.PrimitiveTopology = SharpDX.Toolkit.Graphics.PrimitiveType.TriangleList; break;

                    default:                            throw new Exception("Model::Model(): Unknown primitive type");
                    }

                    // Create data stream for vertices
                    //System.IO.MemoryStream vertexStream = new System.IO.MemoryStream(mesh.VertexCount * vertexSize);
                    DataStream vertexStream = new DataStream(mesh.VertexCount * vertexSize, true, true);

                    for (int i = 0; i < mesh.VertexCount; i++)
                    {
                        vertexStream.Write <Vector3>(Helpers.Transform(FromVector(mesh.Vertices[i]), ref _transform));
                        if (hasColors)
                        {
                            vertexStream.Write <Color>(FromColor(mesh.GetVertexColors(0)[i]));
                        }
                        if (hasNormals)
                        {
                            vertexStream.Write <Vector3>(Helpers.Transform(FromVector(mesh.Normals[i]), ref transformInvTr));
                        }
                        if (hasTangents)
                        {
                            vertexStream.Write <Vector3>(Helpers.Transform(FromVector(mesh.Tangents[i]), ref transformInvTr));
                        }
                        if (hasBitangents)
                        {
                            vertexStream.Write <Vector3>(Helpers.Transform(FromVector(mesh.BiTangents[i]), ref transformInvTr));
                        }
                        if (hasTexCoords)
                        {
                            vertexStream.Write <Vector2>(new Vector2(mesh.GetTextureCoords(0)[i].X, mesh.GetTextureCoords(0)[i].Y));
                        }
                    }

                    vertexStream.Position = 0;

                    // Create new vertex buffer
                    var vertexBuffer = SharpDX.Toolkit.Graphics.Buffer.Vertex.New(_device, vertexStream);

                    // Add it to the mesh
                    modelMesh.VertexBuffer   = vertexBuffer;
                    modelMesh.VertexCount    = mesh.VertexCount;
                    modelMesh.PrimitiveCount = mesh.FaceCount;

                    // Create new index buffer
                    var indexBuffer = SharpDX.Toolkit.Graphics.Buffer.Index.New(_device, mesh.GetIndices());

                    // Add it to the mesh
                    modelMesh.IndexBuffer = indexBuffer;
                    modelMesh.IndexCount  = mesh.GetIndices().GetLength(0);

                    m_meshes.Add(modelMesh);
                }
            }
        }
Пример #23
0
        private IEnumerable<PosNormalTexTanSkinned> ExtractVertices(Mesh mesh, IReadOnlyDictionary<uint, List<VertexWeight>> vertToBoneWeights, bool flipTexY)
        {
            var verts = new List<PosNormalTexTanSkinned>();
            for (var i = 0; i < mesh.VertexCount; i++) {
                var pos = mesh.HasVertices ? mesh.Vertices[i].ToVector3() : new Vector3();
                _min = Vector3.Minimize(_min, pos);
                _max = Vector3.Maximize(_max, pos);

                var norm = mesh.HasNormals ? mesh.Normals[i] : new Vector3D();

                var tan = mesh.HasTangentBasis ? mesh.Tangents[i] : new Vector3D();
                var texC = new Vector3D();
                if (mesh.HasTextureCoords(0)) {
                    var coord = mesh.GetTextureCoords(0)[i];
                    if (flipTexY) {
                        coord.Y = -coord.Y;
                    }
                    texC = coord;
                }

                var weights = vertToBoneWeights[(uint) i].Select(w => w.Weight).ToArray();
                var boneIndices = vertToBoneWeights[(uint) i].Select(w => (byte) w.VertexID).ToArray();

                var v = new PosNormalTexTanSkinned(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3(), weights.First(), boneIndices);
                verts.Add(v);
            }
            return verts;
        }
Пример #24
0
        void ProcessMesh(Assimp.Mesh mesh, Assimp.Scene scene, VertexMode mode)
        {
            Mesh m = new Mesh();

            for (int i = 0; i < mesh.VertexCount; i++)
            {
                if (mesh.HasVertices)
                {
                    Vec3 vec3 = new Vec3(mesh.Vertices[i]);
                    m.positions.Add(vec3);
                }
                else
                {
                    Console.WriteLine("[" + i + "]: " + "No Vertices");
                }

                if (mesh.HasNormals)
                {
                    Vec3 normal = new Vec3(mesh.Normals[i]);
                    m.normals.Add(normal);
                }
                else
                {
                    Console.WriteLine("[" + i + "]: " + "No Normals");
                }

                if (mode == VertexMode.TextureAndNormal)
                {
                    if (mesh.HasTangentBasis)
                    {
                        Vec3 tangent = new Vec3(mesh.Tangents[i]);
                        m.tangents.Add(tangent);
                    }
                    else
                    {
                        Console.WriteLine("[" + i + "]: " + "No Tangents");
                    }
                }

                if (mode == VertexMode.TextureAndNormal || mode == VertexMode.TextureOnly)
                {
                    if (mesh.HasTextureCoords(0))
                    {
                        Vec2 uv = new Vec2(mesh.TextureCoordinateChannels[0][i]);
                        m.uvs.Add(uv);
                    }
                    else
                    {
                        Console.WriteLine("[" + i + "]: " + "No TextureCoordinate");
                    }
                }
            }

            foreach (Face f in mesh.Faces)
            {
                for (int j = 0;
                     j < f.IndexCount;
                     j++)
                {
                    m.indices.Add(f.Indices[j]);
                }
            }

            m.materialIndex = mesh.MaterialIndex;
            this._meshes.Add(m);
        }
Пример #25
0
        //Create meshes and add vertex and index buffers
        private void AddVertexData(Model model, Scene scene, Node node, Device device, ref Matrix transform)
        {
            Matrix previousTransform = transform;

            transform = Matrix.Multiply(previousTransform, FromMatrix(node.Transform));

            //also calculate inverse transpose matrix for normal/tangent/bitagent transformation
            Matrix invTranspose = transform;

            invTranspose.Invert();
            invTranspose.Transpose();

            if (node.HasMeshes)
            {
                foreach (int index in node.MeshIndices)
                {
                    //get a mesh from the scene
                    Assimp.Mesh mesh = scene.Meshes[index];

                    //create new mesh to add to model
                    ModelMesh modelMesh = new ModelMesh();
                    model.AddMesh(ref modelMesh);

                    //if mesh has a material extract the diffuse texture, if present
                    Material material = scene.Materials[mesh.MaterialIndex];
                    if (material != null && material.GetMaterialTextureCount(TextureType.Diffuse) > 0)
                    {
                        material.GetMaterialTexture(TextureType.Diffuse, 0, out TextureSlot texture);
                        //create new texture for mesh
                        modelMesh.AddTextureDiffuse(device, m_modelPath + "\\" + texture.FilePath);
                    }

                    //determine the elements in the vertex
                    bool hasTexCoords  = mesh.HasTextureCoords(0);
                    bool hasColors     = mesh.HasVertexColors(0);
                    bool hasNormals    = mesh.HasNormals;
                    bool hasTangents   = mesh.Tangents != null && mesh.Tangents.Count > 0;
                    bool hasBitangents = mesh.BiTangents != null && mesh.BiTangents.Count > 0;

                    //create vertex element list
                    InputElement[] vertexElements = new InputElement[GetNoofInputElements(mesh)];
                    uint           elementIndex   = 0;
                    vertexElements[elementIndex++] = new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0);
                    short vertexSize = (short)Utilities.SizeOf <Vector3>();

                    if (hasColors)
                    {
                        vertexElements[elementIndex++] = new InputElement("COLOR", 0, Format.R8G8B8A8_UInt, vertexSize, 0);
                        vertexSize += (short)Utilities.SizeOf <Color>();
                    }
                    if (hasNormals)
                    {
                        vertexElements[elementIndex++] = new InputElement("NORMAL", 0, Format.R32G32B32_Float, vertexSize, 0);
                        vertexSize += (short)Utilities.SizeOf <Vector3>();
                    }
                    if (hasTangents)
                    {
                        vertexElements[elementIndex++] = new InputElement("TANGENT", 0, Format.R32G32B32_Float, vertexSize, 0);
                        vertexSize += (short)Utilities.SizeOf <Vector3>();
                    }
                    if (hasBitangents)
                    {
                        vertexElements[elementIndex++] = new InputElement("BITANGENT", 0, Format.R32G32B32_Float, vertexSize, 0);
                        vertexSize += (short)Utilities.SizeOf <Vector3>();
                    }
                    if (hasTexCoords)
                    {
                        vertexElements[elementIndex++] = new InputElement("TEXCOORD", 0, Format.R32G32_Float, vertexSize, 0);
                        vertexSize += (short)Utilities.SizeOf <Vector2>();
                    }

                    //set the vertex elements and size
                    modelMesh.InputElements = vertexElements;
                    modelMesh.VertexSize    = vertexSize;

                    //get pointers to vertex data
                    var positions  = mesh.Vertices;
                    var texCoords  = mesh.TextureCoordinateChannels[0];
                    var normals    = mesh.Normals;
                    var tangents   = mesh.Tangents;
                    var biTangents = mesh.BiTangents;
                    var colours    = mesh.VertexColorChannels[0];

                    //also determine primitive type
                    switch (mesh.PrimitiveType)
                    {
                    case PrimitiveType.Point:
                        modelMesh.PrimitiveTopology = PrimitiveTopology.PointList;
                        break;

                    case PrimitiveType.Line:
                        modelMesh.PrimitiveTopology = PrimitiveTopology.LineList;
                        break;

                    case PrimitiveType.Triangle:
                        modelMesh.PrimitiveTopology = PrimitiveTopology.TriangleList;
                        break;

                    default:
                        throw new Exception("ModelLoader::AddVertexData(): Unknown primitive type");
                    }

                    //create data stream for vertices
                    DataStream vertexStream = new DataStream(mesh.VertexCount * vertexSize, true, true);

                    for (int i = 0; i < mesh.VertexCount; i++)
                    {
                        //add position, after transforming it with accumulated node transform
                        {
                            Vector4 result;
                            Vector3 pos = FromVector(positions[i]);
                            Vector3.Transform(ref pos, ref transform, out result);
                            vertexStream.Write <Vector3>(new Vector3(result.X, result.Y, result.Z));
                        }

                        if (hasColors)
                        {
                            Color vertColor = FromColor(mesh.VertexColorChannels[0][i]);
                            vertexStream.Write <Color>(vertColor);
                        }
                        if (hasNormals)
                        {
                            Vector4 result;
                            Vector3 normal = FromVector(normals[i]);
                            Vector3.Transform(ref normal, ref invTranspose, out result);
                            vertexStream.Write <Vector3>(new Vector3(result.X, result.Y, result.Z));
                        }
                        if (hasTangents)
                        {
                            Vector4 result;
                            Vector3 tangent = FromVector(tangents[i]);
                            Vector3.Transform(ref tangent, ref invTranspose, out result);
                            vertexStream.Write <Vector3>(new Vector3(result.X, result.Y, result.Z));
                        }
                        if (hasBitangents)
                        {
                            Vector4 result;
                            Vector3 biTangent = FromVector(biTangents[i]);
                            Vector3.Transform(ref biTangent, ref invTranspose, out result);
                            vertexStream.Write <Vector3>(new Vector3(result.X, result.Y, result.Z));
                        }
                        if (hasTexCoords)
                        {
                            vertexStream.Write <Vector2>(new Vector2(texCoords[i].X, 1 - texCoords[i].Y));
                        }
                    }

                    vertexStream.Position = 0;

                    //create new vertex buffer
                    var vertexBuffer = new Buffer(device,
                                                  vertexStream,
                                                  new BufferDescription()
                    {
                        BindFlags      = BindFlags.VertexBuffer,
                        CpuAccessFlags = CpuAccessFlags.None,
                        OptionFlags    = ResourceOptionFlags.None,
                        SizeInBytes    = mesh.VertexCount * vertexSize,
                        Usage          = ResourceUsage.Default
                    }
                                                  );

                    //add it to the mesh
                    modelMesh.VertexBuffer   = vertexBuffer;
                    modelMesh.VertexCount    = mesh.VertexCount;
                    modelMesh.PrimitiveCount = mesh.FaceCount;

                    //get pointer to indices data
                    uint[] indices = mesh.GetIndices().Select(i => (uint)i).ToArray();

                    //create data stream for indices
                    DataStream indexStream = new DataStream(indices.GetLength(0) * sizeof(uint), true, true);

                    for (int i = 0; i < indices.GetLength(0); i++)
                    {
                        indexStream.Write <uint>(indices[i]);
                    }

                    indexStream.Position = 0;

                    //create new index buffer
                    var indexBuffer = new Buffer(device,
                                                 indexStream,
                                                 new BufferDescription()
                    {
                        BindFlags      = BindFlags.IndexBuffer,
                        CpuAccessFlags = CpuAccessFlags.None,
                        OptionFlags    = ResourceOptionFlags.None,
                        SizeInBytes    = indices.GetLength(0) * sizeof(uint),
                        Usage          = ResourceUsage.Default
                    }
                                                 );

                    //add it to the mesh
                    modelMesh.IndexBuffer = indexBuffer;
                    modelMesh.IndexCount  = indices.GetLength(0);
                }
            }

            //if node has more children process them as well
            for (int i = 0; i < node.ChildCount; i++)
            {
                AddVertexData(model, scene, node.Children[i], device, ref transform);
            }

            transform = previousTransform;
        }
Пример #26
0
        private Mesh processMesh(Assimp.Mesh mesh, Assimp.Scene scene)
        {
            // Data to fill
            List <Vertex>  vertices = new List <Vertex>();
            List <uint>    indices  = new List <uint>();
            List <Texture> textures = new List <Texture>();

            // Walk through each of the mesh's vertices
            for (int i = 0; i < mesh.VertexCount; i++)
            {
                Vertex vertex = new Vertex();
                //Vertex3 vector = new Vertex3();
                // We declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to glm's vec3 class so we transfer the data to this placeholder glm::vec3 first.
                // Positions
                vertex.Position.X = mesh.Vertices[i].X;
                vertex.Position.Y = mesh.Vertices[i].Y;
                vertex.Position.Z = mesh.Vertices[i].Z;
                //vertex.Position = vector;
                // Normals
                vertex.Normal.X = mesh.Normals[i].X;
                vertex.Normal.Y = mesh.Normals[i].Y;
                vertex.Normal.Z = mesh.Normals[i].Z;
                //vertex.Normal = vector;
                // Texture Coordinates
                if (mesh.HasTextureCoords(0)) // Does the mesh contain texture coordinates?
                {
                    Vertex2f vec;
                    // A vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
                    // use models where a vertex can have multiple texture coordinates so we always take the first set (0).
                    vec.x = mesh.TextureCoordinateChannels[0][i].X;
                    vec.y = mesh.TextureCoordinateChannels[0][i].Y;
                    vertex.TexCoords.X = vec.X;
                    vertex.TexCoords.Y = vec.Y;
                }
                else
                {
                    vertex.TexCoords.X = vertex.TexCoords.Y = 0;
                }
                vertices.Add(vertex);
            }
            // Now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
            for (int i = 0; i < mesh.FaceCount; i++)
            {
                Assimp.Face face = mesh.Faces[i];
                // Retrieve all indices of the face and store them in the indices vector
                for (int j = 0; j < face.IndexCount; j++)
                {
                    indices.Add((uint)face.Indices[j]);
                }
            }
            // Process materials
            if (mesh.MaterialIndex >= 0)
            {
                Assimp.Material material = scene.Materials[mesh.MaterialIndex];
                // We assume a convention for sampler names in the shaders. Each diffuse texture should be named
                // as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER.
                // Same applies to other texture as the following list summarizes:
                // Diffuse: texture_diffuseN
                // Specular: texture_specularN
                // Normal: texture_normalN

                // 1. Diffuse maps
                List <Texture> diffuseMaps = this.loadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse");
                textures.InsertRange(textures.Count, diffuseMaps);
                // 2. Specular maps
                List <Texture> specularMaps = this.loadMaterialTextures(material, TextureType.Specular, "texture_specular");
                textures.InsertRange(textures.Count, specularMaps);
            }

            // Return a mesh object created from the extracted mesh data
            return(new Mesh(vertices, indices, textures));
        }
Пример #27
0
        public void SetMesh(MainWindow host, Mesh mesh, string meshName) 
        {
            Debug.Assert(mesh != null);
            Debug.Assert(host != null);
            Debug.Assert(meshName != null);

            _mesh = mesh;
            _host = host;

            labelVertexCount.Text = mesh.VertexCount + " Vertices";
            labelFaceCount.Text = mesh.FaceCount + " Faces";
            Text = meshName + " - Details";

            checkedListBoxPerFace.CheckOnClick = false;
            checkedListBoxPerFace.SetItemCheckState(0,
                mesh.PrimitiveType.HasFlag(PrimitiveType.Triangle)
                ? CheckState.Checked
                : CheckState.Unchecked);

            checkedListBoxPerFace.SetItemCheckState(1,
                mesh.PrimitiveType.HasFlag(PrimitiveType.Line)
                ? CheckState.Checked
                : CheckState.Unchecked);

            checkedListBoxPerFace.SetItemCheckState(2,
                mesh.PrimitiveType.HasFlag(PrimitiveType.Point)
                ? CheckState.Checked
                : CheckState.Unchecked);

            checkedListBoxPerVertex.CheckOnClick = false;
            checkedListBoxPerVertex.SetItemCheckState(0, CheckState.Checked);
            checkedListBoxPerVertex.SetItemCheckState(1, mesh.HasNormals
                ? CheckState.Checked
                : CheckState.Unchecked);
            checkedListBoxPerVertex.SetItemCheckState(2, mesh.HasTangentBasis
                ? CheckState.Checked
                : CheckState.Unchecked);

            Debug.Assert(mesh.TextureCoordinateChannels.Length >= 4);
            for (var i = 0; i < 4; ++i)
            {
                checkedListBoxPerVertex.SetItemCheckState(3 + i, mesh.HasTextureCoords(i)
                    ? CheckState.Checked
                    : CheckState.Unchecked);
            }

            Debug.Assert(mesh.VertexColorChannels.Length >= 4);
            for (var i = 0; i < 4; ++i)
            {
                checkedListBoxPerVertex.SetItemCheckState(7 + i, mesh.HasVertexColors(i)
                    ? CheckState.Checked
                    : CheckState.Unchecked);
            }

            checkedListBoxPerVertex.SetItemCheckState(11, mesh.HasBones
                ? CheckState.Checked
                : CheckState.Unchecked);
        }
Пример #28
0
        private Mesh ProcessMesh(Assimp.Mesh mesh, Scene scene)
        {
            var vertices = new List <MeshVertex>();
            var indices  = new List <int>();
            var textures = new List <MeshTexture>();
            var color    = new MeshColor();

            for (int i = 0; i < mesh.VertexCount; i++)
            {
                var vertex = new MeshVertex();

                // process vertex positions, normals and texture coordinates
                var pos = mesh.Vertices[i];
                vertex.Position = new Vector3(pos.X, pos.Y, pos.Z);

                var norm = mesh.Normals[i];
                vertex.Normal = new Vector3(norm.X, norm.Y, norm.Z);

                if (mesh.HasTextureCoords(0))  // does the mesh contain texture coordinates?
                {
                    var tex = mesh.TextureCoordinateChannels[0][i];
                    vertex.TexCoords = new Vector2(tex.X, tex.Y);
                }
                else
                {
                    vertex.TexCoords = Vector2.Zero;
                }

                vertices.Add(vertex);
            }

            // process indices
            for (int i = 0; i < mesh.FaceCount; i++)
            {
                Face face = mesh.Faces[i];
                for (int j = 0; j < face.IndexCount; j++)
                {
                    indices.Add(face.Indices[j]);
                }
            }

            // process material
            if (mesh.MaterialIndex >= 0)
            {
                Material material = scene.Materials[mesh.MaterialIndex];

                // get all the needed material textures
                if (material.HasTextureDiffuse)
                {
                    List <MeshTexture> diffuseMaps = LoadMaterialTextures(material, TextureType.Diffuse, "texture_diffuse");
                    textures.AddRange(diffuseMaps);
                }
                if (material.HasTextureSpecular)
                {
                    List <MeshTexture> specularMaps = LoadMaterialTextures(material, TextureType.Specular, "texture_specular");
                    textures.AddRange(specularMaps);
                }

                // get all the needed material colors (default values if they're not presented)
                color.Ambient   = material.ColorAmbient;
                color.Diffuse   = material.ColorDiffuse;
                color.Specular  = material.ColorSpecular;
                color.Shininess = material.Shininess;
            }

            return(new Mesh(mesh.Name, vertices.ToArray(), indices.ToArray(), textures.ToArray(), color));
        }
Пример #29
0
        private static Mesh ConvertAssimpMeshToGeometry(Ai.Mesh aiMesh, Ai.Material material, Dictionary <string, NodeInfo> nodeLookup, ref int nextBoneIndex, Dictionary <int, List <int> > nodeToBoneIndices, List <Matrix4x4> boneInverseBindMatrices, ref Matrix4x4 nodeWorldTransform, ref Matrix4x4 nodeInverseWorldTransform, List <Vector3> transformedVertices, ModelConverterOptions options)
        {
            if (!aiMesh.HasVertices)
            {
                throw new Exception("Assimp mesh has no vertices");
            }

            var geometry = new Mesh();
            var geometryTransformedVertices = new Vector3[aiMesh.VertexCount];

            geometry.Vertices = aiMesh.Vertices
                                .Select(x => new Vector3(x.X, x.Y, x.Z))
                                .ToArray();

            for (int i = 0; i < geometry.Vertices.Length; i++)
            {
                geometryTransformedVertices[i] = Vector3.Transform(geometry.Vertices[i], nodeWorldTransform);
            }

            transformedVertices.AddRange(geometryTransformedVertices);

            if (aiMesh.HasNormals)
            {
                geometry.Normals = aiMesh.Normals
                                   .Select(x => new Vector3(x.X, x.Y, x.Z))
                                   .ToArray();
            }

            if (aiMesh.HasTextureCoords(0))
            {
                geometry.TexCoordsChannel0 = aiMesh.TextureCoordinateChannels[0]
                                             .Select(x => new Vector2(x.X, x.Y))
                                             .ToArray();
            }

            if (aiMesh.HasTextureCoords(1))
            {
                geometry.TexCoordsChannel1 = aiMesh.TextureCoordinateChannels[1]
                                             .Select(x => new Vector2(x.X, x.Y))
                                             .ToArray();
            }

            if (aiMesh.HasTextureCoords(2))
            {
                geometry.TexCoordsChannel2 = aiMesh.TextureCoordinateChannels[2]
                                             .Select(x => new Vector2(x.X, x.Y))
                                             .ToArray();
            }

            if (aiMesh.HasVertexColors(0))
            {
                geometry.ColorChannel0 = aiMesh.VertexColorChannels[0]
                                         .Select(x => ( uint )(( byte )(x.B * 255f) | ( byte )(x.G * 255f) << 8 | ( byte )(x.R * 255f) << 16 | ( byte )(x.A * 255f) << 24))
                                         .ToArray();
            }
            else if (options.GenerateVertexColors)
            {
                geometry.ColorChannel0 = new uint[geometry.VertexCount];
                for (int i = 0; i < geometry.ColorChannel0.Length; i++)
                {
                    geometry.ColorChannel0[i] = 0xFFFFFFFF;
                }
            }

            if (aiMesh.HasVertexColors(1))
            {
                geometry.ColorChannel1 = aiMesh.VertexColorChannels[1]
                                         .Select(x => ( uint )(( byte )(x.B * 255f) | ( byte )(x.G * 255f) << 8 | ( byte )(x.R * 255f) << 16 | ( byte )(x.A * 255f) << 24))
                                         .ToArray();
            }

            if (aiMesh.HasFaces)
            {
                geometry.TriangleIndexFormat = aiMesh.VertexCount <= ushort.MaxValue ? TriangleIndexFormat.UInt16 : TriangleIndexFormat.UInt32;
                geometry.Triangles           = aiMesh.Faces
                                               .Select(x => new Triangle(( uint )x.Indices[0], ( uint )x.Indices[1], ( uint )x.Indices[2]))
                                               .ToArray();
            }

            if (aiMesh.HasBones)
            {
                geometry.VertexWeights = new VertexWeight[geometry.VertexCount];
                for (int i = 0; i < geometry.VertexWeights.Length; i++)
                {
                    geometry.VertexWeights[i].Indices = new byte[4];
                    geometry.VertexWeights[i].Weights = new float[4];
                }

                var vertexWeightCounts = new int[geometry.VertexCount];

                for (var i = 0; i < aiMesh.Bones.Count; i++)
                {
                    var aiMeshBone = aiMesh.Bones[i];

                    // Find node index for the bone
                    var boneLookupData = nodeLookup[AssimpConverterCommon.UnescapeName(aiMeshBone.Name)];
                    int nodeIndex      = boneLookupData.Index;

                    // Calculate inverse bind matrix
                    var boneNode   = boneLookupData.Node;
                    var bindMatrix = boneNode.WorldTransform * nodeInverseWorldTransform;

                    if (options.ConvertSkinToZUp)
                    {
                        bindMatrix *= YToZUpMatrix;
                    }

                    Matrix4x4.Invert(bindMatrix, out var inverseBindMatrix);

                    // Get bone index
                    int boneIndex;
                    if (!nodeToBoneIndices.TryGetValue(nodeIndex, out var boneIndices))
                    {
                        // No entry for the node was found, so we add a new one
                        boneIndex = nextBoneIndex++;
                        nodeToBoneIndices.Add(nodeIndex, new List <int>()
                        {
                            boneIndex
                        });
                        boneInverseBindMatrices.Add(inverseBindMatrix);
                    }
                    else
                    {
                        // Entry for the node was found
                        // Try to find the bone index based on whether the inverse bind matrix matches
                        boneIndex = -1;
                        foreach (int index in boneIndices)
                        {
                            if (boneInverseBindMatrices[index].Equals(inverseBindMatrix))
                            {
                                boneIndex = index;
                            }
                        }

                        if (boneIndex == -1)
                        {
                            // None matching inverse bind matrix was found, so we add a new entry
                            boneIndex = nextBoneIndex++;
                            nodeToBoneIndices[nodeIndex].Add(boneIndex);
                            boneInverseBindMatrices.Add(inverseBindMatrix);
                        }
                    }

                    foreach (var aiVertexWeight in aiMeshBone.VertexWeights)
                    {
                        int vertexWeightCount = vertexWeightCounts[aiVertexWeight.VertexID]++;

                        geometry.VertexWeights[aiVertexWeight.VertexID].Indices[vertexWeightCount] = ( byte )boneIndex;
                        geometry.VertexWeights[aiVertexWeight.VertexID].Weights[vertexWeightCount] = aiVertexWeight.Weight;
                    }
                }
            }

            geometry.MaterialName   = AssimpConverterCommon.UnescapeName(material.Name);
            geometry.BoundingBox    = BoundingBox.Calculate(geometry.Vertices);
            geometry.BoundingSphere = BoundingSphere.Calculate(geometry.BoundingBox.Value, geometry.Vertices);
            geometry.Flags         |= GeometryFlags.Flag80000000;

            return(geometry);
        }
Пример #30
0
		unsafe void WriteMesh (Mesh mesh, BinaryWriter writer) {
			var boneSlotCount = this.GetBoneSlotCount(mesh);

			VertexFlags flags;
			int stride;
			this.GetVertexFormat(mesh, boneSlotCount, out flags, out stride);
			var count = mesh.VertexCount;

			writer.Write(mesh.Name);
			writer.Write((uint)flags);
			writer.Write(boneSlotCount);
			writer.Write(mesh.MaterialIndex);
			var vertices = new float[stride * count];
			int idx = 0, offset = 0;
			foreach (var pos in mesh.Vertices) {
				vertices[idx] = pos.X;
				vertices[idx + 1] = pos.Y;
				vertices[idx + 2] = pos.Z;
				idx += stride;
			}
			offset = idx = 3;
			if (mesh.HasNormals) {
				foreach (var norm in mesh.Normals) {
					vertices[idx] = norm.X;
					vertices[idx + 1] = norm.Y;
					vertices[idx + 2] = norm.Z;
					idx += stride;
				}
				offset += 3;
				idx = offset;
			}
			for (var i = 0; i < 4; i++) {
				if (mesh.HasTextureCoords(i)) {
					if (mesh.UVComponentCount[i] != 2)
						Console.WriteLine("WARNING: texture coordinates should have 2 components, but this channel has " + mesh.UVComponentCount[i]);
					foreach (var uv in mesh.TextureCoordinateChannels[i]) {
						vertices[idx] = uv.X;
						vertices[idx + 1] = uv.Y;
						idx += stride;
					}
					offset += 2;
					idx = offset;
				}
			}
			for (var i = 0; i < 4; i++) {
				if (mesh.HasVertexColors(i)) {
					foreach (var c in mesh.VertexColorChannels[i]) {
						vertices[idx] = c.R;
						vertices[idx + 1] = c.G;
						vertices[idx + 2] = c.B;
						vertices[idx + 3] = c.A;
						idx += stride;
					}
					offset += 4;
					idx = offset;
				}
			}
			// add bone information to every vertex
			for(var i = 0; i < mesh.BoneCount; i++) {
				foreach (var weight in mesh.Bones[i].VertexWeights) {
					if (weight.Weight > 0f) {
						idx = (stride * weight.VertexID) + offset;
						while (vertices[idx] != 0f)
							idx++;
						vertices[idx] = weight.Weight;
						vertices[idx + boneSlotCount] = i;
					}
				}
			}
			writer.Write(vertices.Length);
			writer.Flush();
			fixed(float *fp = &vertices[0]) {
				byte* bp = (byte*)fp;
				using (var ms = new UnmanagedMemoryStream(bp, vertices.Length * sizeof(float))) {
					ms.CopyTo(writer.BaseStream);
				}
			}

			count = mesh.FaceCount;
			var indices = new int[count * 3];
			idx = 0;
			for (var i = 0; i < count; i++) {
				var face = mesh.Faces[i];
				var faceIndices = face.Indices;
				if (face.IndexCount != 3)
					throw new InvalidOperationException("Polygonal faces are not supported, faces must be triangles.");
				indices[idx++] = faceIndices[0];
				indices[idx++] = faceIndices[1];
				indices[idx++] = faceIndices[2];
			}
			writer.Write(indices.Length);
			writer.Flush();
			fixed(int *ip = &indices[0]) {
				byte* bp = (byte*)ip;
				using (var ms = new UnmanagedMemoryStream(bp, indices.Length * sizeof(float))) {
					ms.CopyTo(writer.BaseStream);
				}
			}

			count = mesh.BoneCount;
			writer.Write(count);
			for (var i = 0; i < count; i++) {
				var bone = mesh.Bones[i];
				writer.Write(bone.Name);
				writer.Write(bone.OffsetMatrix);
				var weightCount = bone.VertexWeightCount;
				writer.Write(weightCount);
				for (var j = 0; j < weightCount; j++) {
					var weight = bone.VertexWeights[i];
					writer.Write(weight.VertexID);
					writer.Write(weight.Weight);
				}
			}
		}
Пример #31
0
        //private const PostProcessSteps DefaultPostProcessSteps
        //    = PostProcessSteps.None;

        //TODO: add support for VertexPosition Type
        public static byte[] GenerateVertexBytesArrayFromAssimp(VertexRuntimeTypes henzaiVertexType, Assimp.Mesh aiMesh, int index)
        {
            Vector3D pPos       = aiMesh.Vertices[index];
            Vector3D pNormal    = aiMesh.Normals[index];
            Vector3D pTexCoord  = aiMesh.HasTextureCoords(0) ? aiMesh.TextureCoordinateChannels[0][index] : Zero3D;
            Color4D  pColor     = aiMesh.HasVertexColors(0) ? aiMesh.VertexColorChannels[0][index] : Nocolor;
            Vector3D pTangent   = aiMesh.HasTangentBasis ? aiMesh.Tangents[index] : Zero3D;
            Vector3D pBiTangent = aiMesh.HasTangentBasis ? aiMesh.BiTangents[index] : Zero3D;

            byte[] bytes;
            byte[] posAsBytes       = ByteMarshal.StructToBytes(pPos);
            byte[] colorAsBytes     = ByteMarshal.StructToBytes(pColor);
            byte[] normalAsBytes    = ByteMarshal.StructToBytes(pNormal);
            byte[] texCoordAsBytes  = ByteMarshal.StructToBytes(pTexCoord.ToVector2());
            byte[] tangentAsBytes   = ByteMarshal.StructToBytes(pTangent);
            byte[] bitangentAsBytes = ByteMarshal.StructToBytes(pBiTangent);

            switch (henzaiVertexType)
            {
            case VertexRuntimeTypes.VertexPosition:
                bytes = new byte[VertexPosition.SizeInBytes];
                Array.Copy(posAsBytes, 0, bytes, VertexPosition.PositionOffset, posAsBytes.Length);
                break;

            case VertexRuntimeTypes.VertexPositionColor:
                bytes = new byte[VertexPositionColor.SizeInBytes];
                Array.Copy(posAsBytes, 0, bytes, VertexPositionColor.PositionOffset, posAsBytes.Length);
                Array.Copy(colorAsBytes, 0, bytes, VertexPositionColor.ColorOffset, colorAsBytes.Length);
                break;

            case VertexRuntimeTypes.VertexPositionTexture:
                bytes = new byte[VertexPositionTexture.SizeInBytes];
                Array.Copy(posAsBytes, 0, bytes, VertexPositionTexture.PositionOffset, posAsBytes.Length);
                Array.Copy(texCoordAsBytes, 0, bytes, VertexPositionTexture.TextureCoordinatesOffset, texCoordAsBytes.Length);
                break;

            case VertexRuntimeTypes.VertexPositionNormalTexture:
                bytes = new byte[VertexPositionNormalTexture.SizeInBytes];
                Array.Copy(posAsBytes, 0, bytes, VertexPositionNormalTexture.PositionOffset, posAsBytes.Length);
                Array.Copy(normalAsBytes, 0, bytes, VertexPositionNormalTexture.NormalOffset, normalAsBytes.Length);
                Array.Copy(texCoordAsBytes, 0, bytes, VertexPositionNormalTexture.TextureCoordinatesOffset, texCoordAsBytes.Length);
                break;

            case VertexRuntimeTypes.VertexPositionNormal:
                bytes = new byte[VertexPositionNormal.SizeInBytes];
                Array.Copy(posAsBytes, 0, bytes, VertexPositionNormal.PositionOffset, posAsBytes.Length);
                Array.Copy(normalAsBytes, 0, bytes, VertexPositionNormal.NormalOffset, normalAsBytes.Length);
                break;

            case VertexRuntimeTypes.VertexPositionNormalTextureTangent:
                bytes = new byte[VertexPositionNormalTextureTangent.SizeInBytes];
                Array.Copy(posAsBytes, 0, bytes, VertexPositionNormalTextureTangent.PositionOffset, posAsBytes.Length);
                Array.Copy(normalAsBytes, 0, bytes, VertexPositionNormalTextureTangent.NormalOffset, normalAsBytes.Length);
                Array.Copy(texCoordAsBytes, 0, bytes, VertexPositionNormalTextureTangent.TextureCoordinatesOffset, texCoordAsBytes.Length);
                Array.Copy(tangentAsBytes, 0, bytes, VertexPositionNormalTextureTangent.TangentOffset, tangentAsBytes.Length);
                break;

            case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent:
                bytes = new byte[VertexPositionNormalTextureTangentBitangent.SizeInBytes];
                Array.Copy(posAsBytes, 0, bytes, VertexPositionNormalTextureTangentBitangent.PositionOffset, posAsBytes.Length);
                Array.Copy(normalAsBytes, 0, bytes, VertexPositionNormalTextureTangentBitangent.NormalOffset, normalAsBytes.Length);
                Array.Copy(texCoordAsBytes, 0, bytes, VertexPositionNormalTextureTangentBitangent.TextureCoordinatesOffset, texCoordAsBytes.Length);
                Array.Copy(tangentAsBytes, 0, bytes, VertexPositionNormalTextureTangentBitangent.TangentOffset, tangentAsBytes.Length);
                Array.Copy(bitangentAsBytes, 0, bytes, VertexPositionNormalTextureTangentBitangent.BitangentOffset, bitangentAsBytes.Length);
                break;

            default:
                throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented");
            }

            return(bytes);
        }
Пример #32
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));
        }
Пример #33
0
        /// <summary>
        /// Determine the number of elements in the vertex.
        /// </summary>
        private static int GetNumberOfInputElements(Mesh mesh)
        {
            bool hasTexCoords = mesh.HasTextureCoords(0);
            bool hasColors = mesh.HasVertexColors(0);
            bool hasNormals = mesh.HasNormals;
            bool hasTangents = mesh.Tangents != null;
            bool hasBitangents = mesh.BiTangents != null;

            int noofElements = 1;

            if (hasColors)
                noofElements++;

            if (hasNormals)
                noofElements++;

            if (hasTangents)
                noofElements++;

            if (hasBitangents)
                noofElements++;

            if (hasTexCoords)
                noofElements++;

            return noofElements;
        }
Пример #34
0
        void createMeshes(Node node)
        {
            if (node.HasMeshes)
            {
                foreach (int meshIndex in node.MeshIndices)
                {
                    Assimp.Mesh amesh = myScene.Meshes[meshIndex];

                    //create the material
                    Graphics.Material mat = createMaterial(myScene.Materials[amesh.MaterialIndex]);

                    //create the geometry
                    Graphics.Mesh mesh = new Graphics.Mesh();
                    mesh.primativeType = OpenTK.Graphics.OpenGL.PrimitiveType.Triangles;
                    mesh.indexBase     = currIndexOffset;
                    mesh.indexCount    = amesh.FaceCount * 3;
                    mesh.material      = mat;

                    //get the indices
                    foreach (Face face in amesh.Faces)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            index.Add((UInt16)(face.Indices[i] + currVertOffset));
                            currIndexOffset++;
                        }
                    }

                    //get the verts
                    for (int i = 0; i < amesh.VertexCount; i++)
                    {
                        V3N3T2 v = new V3N3T2();
                        v.Position = toVector(amesh.Vertices[i]);

                        if (amesh.HasNormals == true)
                        {
                            v.Normal = toVector(amesh.Normals[i]);
                        }

                        if (amesh.HasTextureCoords(0) == true)
                        {
                            v.TexCoord = toVector2D(amesh.TextureCoordinateChannels[0][i]);
                        }

                        myVerts.Add(v);
                    }

                    currVertOffset += amesh.VertexCount;

                    myModel.myMeshes.Add(mesh);
                }
            }

            if (node.HasChildren)
            {
                foreach (Node child in node.Children)
                {
                    createMeshes(child);
                }
            }
        }
Пример #35
0
        private void AddVertexData(CModel model, Assimp.Scene scene, Node node, Device device, ref Matrix transform, string modelPath, CShaderResource shaderResource)
        {
            // TODO henning With this we don't preserve hiearchy in the models meshes, for now this is the wanted behavior but maybe we want to think about this in the future
            Matrix previousTransform = transform;

            transform = Matrix.Multiply(previousTransform, FromAssimpMatrix(node.Transform));

            if (node.HasMeshes)
            {
                foreach (int index in node.MeshIndices)
                {
                    // Get the mesh from the scene
                    Assimp.Mesh assimpMesh = scene.Meshes[index];

                    // Create a mesh in our engine format
                    CMesh mesh = new CMesh();
                    mesh.Transform.SetFromMatrix(in transform);
                    model.AddMesh(ref mesh);

                    //Extract diffuse texture from Assimp Material
                    // TODO henning extract other textures if we want
                    Material material = scene.Materials[assimpMesh.MaterialIndex];
                    if (material != null && material.GetMaterialTextureCount(TextureType.Diffuse) > 0)
                    {
                        TextureSlot texture;
                        if (material.GetMaterialTexture(TextureType.Diffuse, 0, out texture))
                        {
                            // Create texture asset
                            mesh.Material = CMaterial.CreateDefaultMaterial();
                            CTextureSampler textureSampler = new CTextureSampler(device, device.ImmediateContext, modelPath + "\\" + texture.FilePath);
                            mesh.Material.SetTextureParameter(new SHashedName("DiffuseTexture"), textureSampler);
                            mesh.Material.FinishLoading();
                        }
                        else
                        {
                            mesh.Material = CRenderer.Instance.ResourceManager.DefaultTextureMaterial;
                        }
                    }
                    else
                    {
                        mesh.Material = CRenderer.Instance.ResourceManager.DefaultTextureMaterial;
                    }
                    mesh.Material.SetColorParameter(new SHashedName("tintColor"), new Vector4(1, 1, 1, 1));


                    int numInputElements = 6;                     // We always provide all data to the vertex buffer so shaders can rely on them being available if it is not in the asset we will add a default value

                    bool hasTexCoords  = assimpMesh.HasTextureCoords(0);
                    bool hasColors     = assimpMesh.HasVertexColors(0);
                    bool hasNormals    = assimpMesh.HasNormals;
                    bool hasTangents   = assimpMesh.Tangents != null && assimpMesh.Tangents.Count > 0;
                    bool hasBiTangents = assimpMesh.BiTangents != null && assimpMesh.BiTangents.Count > 0;

                    // Create InputElement list
                    InputElement[] vertexElements = new InputElement[numInputElements];
                    uint           elementIndex   = 0;
                    vertexElements[elementIndex] = new InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0);
                    elementIndex++;
                    int vertexSize = Utilities.SizeOf <Vector3>();

                    // TODO henning evaluate if we need 32bit vertex color range
                    vertexElements[elementIndex] = new InputElement("COLOR", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 0);
                    elementIndex++;
                    vertexSize += Utilities.SizeOf <Vector4>();
                    vertexElements[elementIndex] = new InputElement("NORMAL", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0);
                    elementIndex++;
                    vertexSize += Utilities.SizeOf <Vector3>();
                    vertexElements[elementIndex] = new InputElement("TANGENT", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0);
                    elementIndex++;
                    vertexSize += Utilities.SizeOf <Vector3>();
                    vertexElements[elementIndex] = new InputElement("BITANGENT", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0);
                    elementIndex++;
                    vertexSize += Utilities.SizeOf <Vector3>();
                    vertexElements[elementIndex] = new InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, 0);
                    elementIndex++;
                    vertexSize += Utilities.SizeOf <Vector2>();

                    // Set InputElements and Vertex Size on mesh
                    mesh.m_sizePerVertex = vertexSize;

                    List <Vector3D> positions  = assimpMesh.Vertices;
                    List <Vector3D> texCoords  = assimpMesh.TextureCoordinateChannels[0];                   // TODO henning support multiple UV channels if wanted
                    List <Vector3D> normals    = assimpMesh.Normals;
                    List <Vector3D> tangents   = assimpMesh.Tangents;
                    List <Vector3D> biTangents = assimpMesh.BiTangents;
                    List <Color4D>  colors     = assimpMesh.VertexColorChannels[0];

                    switch (assimpMesh.PrimitiveType)
                    {
                    case PrimitiveType.Point:
                        mesh.m_primitiveTopology = SharpDX.Direct3D.PrimitiveTopology.PointList;
                        break;

                    case PrimitiveType.Line:
                        mesh.m_primitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
                        break;

                    case PrimitiveType.Triangle:
                        mesh.m_primitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
                        break;

                    default:
                        throw new NotImplementedException("Primitive Type not supported: " + assimpMesh.PrimitiveType.ToString());
                    }

                    DataStream vertexStream = new DataStream(assimpMesh.VertexCount * vertexSize, true, true);

                    for (int i = 0; i < assimpMesh.VertexCount; i++)
                    {
                        //add position, after transforming it with accumulated node transform
                        {
                            Vector3 pos = FromAssimpVector(positions[i]);
                            vertexStream.Write(pos);
                        }

                        if (hasColors)
                        {
                            Vector4 vertColor = FromAssimpColor(colors[i]);
                            vertexStream.Write(vertColor);
                        }
                        else
                        {
                            vertexStream.Write(new Vector4(1, 1, 1, 1));
                        }
                        if (hasNormals)
                        {
                            Vector3 normal = FromAssimpVector(normals[i]);
                            vertexStream.Write(normal);
                        }
                        else
                        {
                            vertexStream.Write(new Vector3(0, 0, 0));
                        }
                        if (hasTangents)
                        {
                            Vector3 tangent = FromAssimpVector(tangents[i]);
                            vertexStream.Write(tangent);
                        }
                        else
                        {
                            vertexStream.Write(new Vector3(0, 0, 0));
                        }
                        if (hasBiTangents)
                        {
                            Vector3 biTangent = FromAssimpVector(biTangents[i]);
                            vertexStream.Write(biTangent);
                        }
                        else
                        {
                            vertexStream.Write(new Vector3(0, 0, 0));
                        }
                        if (hasTexCoords)
                        {
                            vertexStream.Write(new Vector2(texCoords[i].X, texCoords[i].Y));
                        }
                        else
                        {
                            vertexStream.Write(new Vector2(0, 0));
                        }
                    }

                    vertexStream.Position = 0;
                    BufferDescription vertexDescription = new BufferDescription
                    {
                        BindFlags      = BindFlags.VertexBuffer,
                        Usage          = ResourceUsage.Default,
                        CpuAccessFlags = CpuAccessFlags.None,
                        SizeInBytes    = assimpMesh.VertexCount * vertexSize,
                        OptionFlags    = ResourceOptionFlags.None
                    };

                    mesh.m_vertexBuffer = new Buffer(device, vertexStream, vertexDescription);
                    vertexStream.Dispose();

                    mesh.m_vertexCount    = assimpMesh.VertexCount;
                    mesh.m_primitiveCount = assimpMesh.FaceCount;


                    int[] indices = assimpMesh.GetIndices();
                    mesh.m_indexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, indices);
                    mesh.m_indexCount  = indices.Length;
                }
            }

            for (int i = 0; i < node.ChildCount; i++)
            {
                AddVertexData(model, scene, node.Children[i], device, ref transform, modelPath, shaderResource);
            }

            transform = previousTransform;
        }
Пример #36
0
        private ModelData.MeshPart Process(ModelData.Mesh mesh, Mesh assimpMesh)
        {
            var meshPart = new ModelData.MeshPart
            {
                PrimitiveTopology = PrimitiveTopology.TriangleList,
                VertexBufferRange = new ModelData.BufferRange {
                    Slot = mesh.VertexBuffers.Count
                },
                IndexBufferRange = new ModelData.BufferRange {
                    Slot = mesh.IndexBuffers.Count
                }
            };

            var vertexBuffer = new ModelData.VertexBuffer
            {
                Layout = new List <VertexElement>()
            };

            mesh.VertexBuffers.Add(vertexBuffer);

            var indexBuffer = new ModelData.IndexBuffer();

            mesh.IndexBuffers.Add(indexBuffer);

            var layout = vertexBuffer.Layout;

            int vertexBufferElementSize = 0;

            // Add position
            layout.Add(VertexElement.PositionTransformed(Format.R32G32B32_Float, 0));
            vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();

            // Add normals
            if (assimpMesh.HasNormals)
            {
                layout.Add(VertexElement.Normal(0, Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();
            }

            // Add colors
            if (assimpMesh.VertexColorChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.VertexColorChannelCount; i++)
                {
                    if (assimpMesh.HasVertexColors(i))
                    {
                        layout.Add(VertexElement.Normal(localIndex, Format.R32G32B32A32_Float, vertexBufferElementSize));
                        vertexBufferElementSize += SharpDX.Utilities.SizeOf <Color4>();
                        localIndex++;
                    }
                }
            }

            // Add textures
            if (assimpMesh.TextureCoordsChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.TextureCoordsChannelCount; i++)
                {
                    if (assimpMesh.HasTextureCoords(i))
                    {
                        var uvCount = assimpMesh.GetUVComponentCount(i);

                        if (uvCount == 2)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector2>();
                        }
                        else if (uvCount == 3)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32B32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexpected uv count");
                        }

                        localIndex++;
                    }
                }
            }

            if (options.ModelOperations.HasFlag(ModelOperation.CalculateBarycentricCoordinates))
            {
                layout.Add(new VertexElement("BARYCENTRIC", 0, Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();
            }
            else
            // Add tangent / bitangent
            if (assimpMesh.HasTangentBasis)
            {
                if (!options.ExcludeElements.Contains("Tangent"))
                {
                    layout.Add(VertexElement.Tangent(Format.R32G32B32A32_Float, vertexBufferElementSize));
                    vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector4>();
                }

                if (!options.ExcludeElements.Contains("BiTangent"))
                {
                    layout.Add(VertexElement.BiTangent(Format.R32G32B32_Float, vertexBufferElementSize));
                    vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();
                }
            }

            if (options.ModelOperations.HasFlag(ModelOperation.CalculateBarycentricCoordinates))
            {
                WriteBarycentricVertices(assimpMesh, meshPart, vertexBuffer, vertexBufferElementSize);
            }
            else
            {
                WriteVertices(assimpMesh, meshPart, vertexBuffer, vertexBufferElementSize);
            }
            WriteIndices(assimpMesh, meshPart, indexBuffer);
            return(meshPart);
        }