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); } } }
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(); }