Beispiel #1
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);
                }
            }
        }
Beispiel #2
0
        private void Load(AssetLoadContext context, Scene scene)
        {
            Node[] nodes = new[] { scene.RootNode };
            if (scene.RootNode.ChildCount > 0)
            {
                nodes = scene.RootNode.Children;
            }

            List <ModelMesh> meshList = new List <ModelMesh>();

            for (int i = 0; i < nodes.Length; i++)
            {
                Node node = nodes[i];
                if (!node.HasMeshes)
                {
                    continue;
                }

                for (int j = 0; j < node.MeshCount; j++)
                {
                    Mesh     mesh     = scene.Meshes[node.MeshIndices[j]];
                    Vertex[] vertices = new Vertex[mesh.VertexCount];

                    Assimp.Material assimpMaterial  = null;
                    Texture2D       diffuseTexture  = null;
                    Texture2D       specularTexture = null;
                    Texture2D       emissiveTexture = null;
                    Texture2D       normalMap       = null;
                    if (scene.HasMaterials && mesh.MaterialIndex >= 0)
                    {
                        assimpMaterial  = scene.Materials[mesh.MaterialIndex];
                        diffuseTexture  = LoadTexture(context, assimpMaterial.GetTexture(Assimp.TextureType.Diffuse, 0));
                        specularTexture = LoadTexture(context, assimpMaterial.GetTexture(Assimp.TextureType.Specular, 0));
                        emissiveTexture = LoadTexture(context, assimpMaterial.GetTexture(Assimp.TextureType.Emissive, 0));

                        bool usedSRGB = Texture.UseSRGB;
                        Texture.UseSRGB = false;                         // We need "default" texture loading because normal maps are already linear space
                        normalMap       = LoadTexture(context, assimpMaterial.GetTexture(Assimp.TextureType.Normals, 0));

                        Texture.UseSRGB = usedSRGB;
                    }

                    Vector3D[] texcoord0 = null;
                    Vector3D[] texcoord1 = null;

                    if (mesh.HasTextureCoords(0))
                    {
                        texcoord0 = mesh.GetTextureCoords(0);
                    }
                    if (mesh.HasTextureCoords(1))
                    {
                        texcoord1 = mesh.GetTextureCoords(1);
                    }

                    uint[] indices = mesh.GetIndices();
                    for (int k = 0; k < mesh.VertexCount; k++)
                    {
                        Vertex vertex = new Vertex();

                        vertex.Position = new Vector3(
                            mesh.Vertices[k].X,
                            mesh.Vertices[k].Y,
                            mesh.Vertices[k].Z);
                        if (mesh.HasNormals)
                        {
                            vertex.Normal = new Vector3(
                                mesh.Normals[k].X,
                                mesh.Normals[k].Y,
                                mesh.Normals[k].Z);
                        }
                        if (texcoord0 != null)
                        {
                            vertex.UV = new Vector2(
                                texcoord0[k].X,
                                texcoord0[k].Y);
                        }
                        if (texcoord1 != null)
                        {
                            vertex.UV2 = new Vector2(
                                texcoord1[k].X,
                                texcoord1[k].Y);
                        }

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

                            vertex.BiTangent = new Vector3(
                                mesh.BiTangents[k].X,
                                mesh.BiTangents[k].Y,
                                mesh.BiTangents[k].Z);
                        }

                        vertices[k] = vertex;
                    }

                    OpenGL.Invoke(() =>
                    {
                        ModelMesh modelMesh       = new ModelMesh(indices, vertices);
                        modelMesh.DiffuseTexture  = diffuseTexture;
                        modelMesh.SpecularTexture = specularTexture;
                        modelMesh.EmissiveTexture = emissiveTexture;
                        modelMesh.NormalMap       = normalMap;
                        meshList.Add(modelMesh);
                    });
                }
            }
            this.meshes = meshList.ToArray();
        }