GetIndices() public method

Convienence method for accumulating all face indices into a single index array.
public GetIndices ( ) : int[]
return int[]
        internal void LoadPrimitveFromFile(string fileName, out DebugVertexType[] vertices, out UInt16[] indices)
        {
            Assimp.Scene scene = m_importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessPreset.ConvertToLeftHanded);
            // Loaded primitive files should always only contain a single mesh so we load only the first mesh
            if (scene.HasMeshes)
            {
                Assimp.Mesh assimpMesh = scene.Meshes[0];
                vertices = new DebugVertexType[assimpMesh.Vertices.Count];
                indices  = new UInt16[assimpMesh.GetIndices().Length];

                for (int i = 0; i < assimpMesh.Vertices.Count; ++i)
                {
                    Vector3 position = FromAssimpVector(assimpMesh.Vertices[i]);
                    vertices[i].position = position;
                }

                for (int i = 0; i < assimpMesh.GetIndices().Length; i++)
                {
                    int index = assimpMesh.GetIndices()[i];
                    indices[i] = (UInt16)index;
                }
            }
            else
            {
                vertices = new DebugVertexType[0];
                indices  = new UInt16[0];
            }
        }
Beispiel #2
0
        /// <summary>
        /// Import a mesh from a model file.
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static Mesh Load(string path)
        {
            Mesh mesh = new Mesh()
            {
                Path = path
            };

            a.AssimpContext context = new a.AssimpContext();
            a.Scene         scene   = context.ImportFile(path, a.PostProcessSteps.Triangulate);
            a.Mesh          aMesh   = scene.Meshes[0];

            mesh.vertices = new Vector4[aMesh.VertexCount];
            mesh.normals  = new Vector4[aMesh.VertexCount];
            mesh.uvs      = new Vector4[aMesh.VertexCount];

            for (int i = 0; i < aMesh.VertexCount; i++)
            {
                a.Vector3D aVertex = aMesh.Vertices[i];
                a.Vector3D aNormal = aMesh.Normals[i];
                a.Vector3D aUv     = aMesh.TextureCoordinateChannels[0][i];

                mesh.vertices[i] = new Vector4(aVertex.X, aVertex.Y, aVertex.Z, 1f);
                mesh.normals[i]  = new Vector4(aNormal.X, aNormal.Y, aNormal.Z, 0f);
                mesh.uvs[i]      = new Vector4(aUv.X, aUv.Y, 0f, 0f);
            }
            mesh.indices = aMesh.GetIndices();

            return(mesh);
        }
Beispiel #3
0
 private static void ProcessMesh(ref Assimp.Mesh mesh, ref Mesh result)
 {
     if (mesh != null)
     {
         if (!string.IsNullOrWhiteSpace(mesh.Name))
         {
             result.Name = mesh.Name;
         }
         List <float> vertices = new List <float>();
         foreach (Vector3D pos in mesh.Vertices)
         {
             vertices.Add(pos.X);
             vertices.Add(pos.Y);
             vertices.Add(pos.Z);
         }
         result.Vertices = vertices.ToArray();
         List <float> uvs = new List <float>();
         foreach (Vector3D uv in mesh.TextureCoordinateChannels[0])
         {
             uvs.Add(uv.X);
             uvs.Add(1.0f - uv.Y);
         }
         result.UVs = uvs.ToArray();
         List <float> normals = new List <float>();
         foreach (Vector3D normal in mesh.Normals)
         {
             normals.Add(normal.X);
             normals.Add(normal.Y);
             normals.Add(normal.Z);
         }
         result.Normals = normals.ToArray();
         result.Indices = mesh.GetIndices().Select(i => (uint)i).ToArray();
     }
 }
Beispiel #4
0
        public DX11IndexedGeometry LoadFromMesh(Assimp.Mesh mesh, AssimpLoadInformation loadInfo, bool allowRawView = false)
        {
            uint[] inds = mesh.GetIndices();

            if (inds.Length > 0 && mesh.VertexCount > 0)
            {
                int vertexsize;
                var layout = mesh.InputLayout(loadInfo, out vertexsize);

                BoundingBox bb;
                DataStream  ds = mesh.LoadVertices(loadInfo, vertexsize, out bb);

                DX11IndexedGeometry geom = new DX11IndexedGeometry(device)
                {
                    HasBoundingBox = true,
                    BoundingBox    = bb,
                    IndexBuffer    = DX11IndexBuffer.CreateImmutable(device, inds, allowRawView),
                    InputLayout    = layout,
                    PrimitiveType  = "AssimpModel",
                    Tag            = null,
                    Topology       = SharpDX.Direct3D.PrimitiveTopology.TriangleList,
                    VertexBuffer   = DX11VertexBuffer.CreateImmutable(device, mesh.VertexCount, vertexsize, ds, allowRawView)
                };

                ds.Dispose();
                return(geom);
            }

            return(null);
        }
        private Core.Entities.Mesh convertAssimpToEngineFormat(Mesh assimpMesh)
        {
            Core.Entities.Mesh mesh = new Core.Entities.Mesh();

            mesh.Vertices = assimpMesh.Vertices.AssimpListToOpentkVector().ToArray();
            mesh.Normals  = assimpMesh.Normals.AssimpListToOpentkVector().ToArray();
            mesh.UvCoords = assimpMesh.TextureCoordinateChannels[0].GetUVCoordChanel().ToArray();
            mesh.Indeces  = assimpMesh.GetIndices();

            return(mesh);
        }
Beispiel #6
0
        static meshData ProcessMesh(Assimp.Mesh mesh, Assimp.Scene scene)
        {
            Vector3[] post = mesh.Vertices.Select(x => x.V()).ToArray();
            Vector3[] norm = mesh.Normals.Select(x => x.V()).ToArray();
            Vector3[] tang = mesh.Tangents.Select(x => x.V()).ToArray();
            Vector2[] uves = mesh.TextureCoordinateChannels[0].Select(x => x.VX()).ToArray();
            int[]     inde = mesh.GetIndices();

            var materialIndex = mesh.MaterialIndex;

            return(new meshData(post, inde, norm, tang, uves));
        }
Beispiel #7
0
        public virtual int[] GetIndices(int offset = 0)
        {
            int[] indices = AssMesh.GetIndices();

            if (offset != 0)
            {
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] += offset;
                }
            }

            return(indices);
        }
Beispiel #8
0
        public static Mesh Clone(this Mesh mesh)
        {
            var newMesh = new Mesh(mesh.PrimitiveType);

            newMesh.Vertices.AddRange(mesh.Vertices);
            newMesh.SetIndices(mesh.GetIndices(), mesh.Faces[0].IndexCount);
            if (newMesh.HasNormals)
            {
                newMesh.Normals.AddRange(mesh.Normals);
            }

            for (int i = 0; i < mesh.TextureCoordinateChannelCount; i++)
            {
                newMesh.TextureCoordinateChannels[i].AddRange(mesh.TextureCoordinateChannels[i]);
            }

            foreach (var bone in mesh.Bones)
            {
                newMesh.Bones.Add(new Bone(bone.Name, bone.OffsetMatrix, bone.VertexWeights.ToArray()));
            }
            return(newMesh);
        }
Beispiel #9
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;
        }
Beispiel #10
0
        private ModelData.MeshPart Process(ModelData.Mesh mesh, Assimp.Mesh assimpMesh, Node parentNode)
        {
            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 <Vector3>();

            // Add normals
            if (assimpMesh.HasNormals)
            {
                layout.Add(VertexElement.Normal(0, Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += 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.Color(localIndex, Format.R32G32B32A32_Float, vertexBufferElementSize));
                        vertexBufferElementSize += Utilities.SizeOf <Color4>();
                        localIndex++;
                    }
                }
            }

            // Add textures
            if (assimpMesh.TextureCoordinateChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.TextureCoordinateChannelCount; i++)
                {
                    if (assimpMesh.HasTextureCoords(i))
                    {
                        var uvCount = assimpMesh.UVComponentCount[i];

                        if (uvCount == 2)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += Utilities.SizeOf <Vector2>();
                        }
                        else if (uvCount == 3)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32B32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += Utilities.SizeOf <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 <Vector3>();

                layout.Add(VertexElement.BiTangent(Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf <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)
            {
                for (int i = 0; i < assimpMesh.Bones.Count; i++)
                {
                    var bone     = assimpMesh.Bones[i];
                    var boneNode = scene.RootNode.FindNode(bone.Name);

                    if (bone.HasVertexWeights)
                    {
                        var skinnedBoneIndex = meshPart.SkinnedBones.Count;

                        meshPart.SkinnedBones.Add(new ModelData.SkinnedBone
                        {
                            BoneIndex            = skeletonNodes[boneNode],
                            InverseBindTransform = ConvertMatrix(bone.OffsetMatrix)
                        });

                        for (int j = 0; j < bone.VertexWeightCount; j++)
                        {
                            var weights             = bone.VertexWeights[j];
                            var vertexSkinningCount = skinningCount[weights.VertexID];

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

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

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

                        hasWeights = true;
                    }
                }

                if (hasWeights)
                {
                    layout.Add(VertexElement.BlendIndices(Format.R16G16B16A16_SInt, vertexBufferElementSize));
                    vertexBufferElementSize += 8;

                    layout.Add(VertexElement.BlendWeights(Format.R32G32B32A32_Float, vertexBufferElementSize));
                    vertexBufferElementSize += Utilities.SizeOf <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++)
            {
                Vector3 position = ConvertVector(assimpMesh.Vertices[i]);
                vertexStream.Write(position);

                // Store bounding points for BoundingSphere pre-calculation
                boundingPoints[currentBoundingPointIndex++] = position;

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

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

                // Add textures
                if (assimpMesh.TextureCoordinateChannelCount > 0)
                {
                    for (int j = 0; j < assimpMesh.TextureCoordinateChannelCount; j++)
                    {
                        if (assimpMesh.HasTextureCoords(j))
                        {
                            var uvCount = assimpMesh.UVComponentCount[j];

                            var uv = assimpMesh.TextureCoordinateChannels[j][i];

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

                // Add tangent / bitangent
                if (assimpMesh.HasTangentBasis)
                {
                    var tangent   = ConvertVector(assimpMesh.Normals[i]);
                    var bitangent = ConvertVector(assimpMesh.Normals[i]);
                    vertexStream.Write(tangent);
                    vertexStream.Write(bitangent);
                }

                // Add Skinning Indices/Weights
                if (assimpMesh.HasBones && hasWeights)
                {
                    var vertexSkinndingIndices = skinningIndices[i];
                    vertexStream.Write((short)vertexSkinndingIndices.X);
                    vertexStream.Write((short)vertexSkinndingIndices.Y);
                    vertexStream.Write((short)vertexSkinndingIndices.Z);
                    vertexStream.Write((short)vertexSkinndingIndices.W);
                    vertexStream.Write(skinningWeights[i]);
                }
            }
            vertexStream.Dispose();

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

            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);
        }
Beispiel #11
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;
        }
Beispiel #12
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 #13
0
        private void LoadMeshInternal(int meshIndex, CMeshAsset asset, CMeshLoadingJob loadingJob, string assetPath, string nameOverride = null, bool bAlwaysImport = false)
        {
            Assimp.Mesh assimpMesh = loadingJob.Scene.Meshes[meshIndex];

            // Load texture and material from the file if present
            //todo henning extract more textures
            Material material = loadingJob.Scene.Materials[assimpMesh.MaterialIndex];

            if (material != null && material.GetMaterialTextureCount(TextureType.Diffuse) > 0)
            {
                if (material.GetMaterialTexture(TextureType.Diffuse, 0, out TextureSlot texture))
                {
                    if (loadingJob.LoadedMaterials == null || !loadingJob.LoadedMaterials.TryGetValue(material.Name, out CMaterialAsset materialAsset))
                    {
                        materialAsset = new CMaterialAsset();
                        loadingJob.LoadedMaterials?.Add(material.Name, materialAsset);
                        // Make sure we only load each referenced texture once
                        if (loadingJob.LoadedTextures == null || !loadingJob.LoadedTextures.TryGetValue(texture.FilePath, out CTextureAsset textureAsset))
                        {
                            textureAsset = CImportManager.Instance.TextureImporter.ImportTextureAsync(loadingJob.BasePath + "\\" + texture.FilePath, assetPath + "Textures/");
                            loadingJob.LoadedTextures?.Add(texture.FilePath, textureAsset);
                        }

                        SShaderParameter textureParameter = new SShaderParameter()
                        {
                            parameterData = new CAssetReference <CTextureAsset>(textureAsset),
                            parameterType = EShaderParameterType.Texture
                        };
                        materialAsset.MaterialParameters.Add(new SMaterialParameterEntry(new SHashedName("DiffuseTexture"), textureParameter));

                        materialAsset.Name = material.Name;
                        if (CAssetRegistry.Instance.RequestRegisterAsset(materialAsset, assetPath + "Materials/", out CMaterialAsset existingMaterial))
                        {
                            existingMaterial.WaitUntilLoaded();
                            existingMaterial.CopyFrom(existingMaterial);
                        }
                        materialAsset.LoadFinished();
                    }
                    asset.MaterialAsset = materialAsset;
                }
            }

            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;

            switch (assimpMesh.PrimitiveType)
            {
            case PrimitiveType.Point:
                asset.PrimitiveTopology = PrimitiveTopology.PointList;
                break;

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

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

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

            asset.FaceCount  = assimpMesh.FaceCount;
            asset.VertexData = new SVertexInfo[assimpMesh.VertexCount];

            Vector3 boundingBoxMin = new Vector3(1e10f, 1e10f, 1e10f);
            Vector3 boundingBoxMax = new Vector3(-1e10f, -1e10f, -1e10f);

            for (int i = 0; i < assimpMesh.VertexCount; i++)
            {
                SVertexInfo vertexInfo = new SVertexInfo();
                vertexInfo.position = FromAssimpVector(assimpMesh.Vertices[i]);
                boundingBoxMin.X    = Math.Min(vertexInfo.position.X, boundingBoxMin.X);
                boundingBoxMin.Y    = Math.Min(vertexInfo.position.Y, boundingBoxMin.Y);
                boundingBoxMin.Z    = Math.Min(vertexInfo.position.Z, boundingBoxMin.Z);

                boundingBoxMax.X = Math.Max(vertexInfo.position.X, boundingBoxMax.X);
                boundingBoxMax.Y = Math.Max(vertexInfo.position.Y, boundingBoxMax.Y);
                boundingBoxMax.Z = Math.Max(vertexInfo.position.Z, boundingBoxMax.Z);

                if (hasColors)
                {
                    vertexInfo.color = FromAssimpColor(assimpMesh.VertexColorChannels[0][i]);
                }
                else
                {
                    vertexInfo.color = Vector4.One;
                }

                if (hasNormals)
                {
                    vertexInfo.normal = FromAssimpVector(assimpMesh.Normals[i]);
                }

                if (hasBiTangents)
                {
                    vertexInfo.biTangent = FromAssimpVector(assimpMesh.BiTangents[i]);
                }

                if (hasTangents)
                {
                    vertexInfo.tangent = FromAssimpVector(assimpMesh.Tangents[i]);
                }

                if (hasTexCoords)
                {
                    Vector3D assimpTexCoord = assimpMesh.TextureCoordinateChannels[0][i];
                    vertexInfo.texCoord = new Vector2(assimpTexCoord.X, assimpTexCoord.Y);
                }

                asset.VertexData[i] = vertexInfo;
            }

            asset.AABBMin   = boundingBoxMin;
            asset.AABBMax   = boundingBoxMax;
            asset.IndexData = assimpMesh.GetIndices();
            asset.Name      = nameOverride ?? assimpMesh.Name;
            if (CAssetRegistry.Instance.RequestRegisterAsset(asset, assetPath, out CMeshAsset existingAsset, true))
            {
                existingAsset.WaitUntilLoaded();
                asset.CopyFrom(existingAsset);
            }
        }
Beispiel #14
0
        /// <summary>
        /// internal.
        /// </summary>
        internal static Scene ConvertFromAssimp(Assimp.Scene _Scene)
        {
            Scene Result = new Scene();

            LoadTextures(_Scene);
            Result.CompileEnable = false;
            for (int i = 0; i < _Scene.Meshes.Count; i++)
            {
                D3DMesh _M = new D3DMesh();
                _M.CompileEnable = false;
                Assimp.Mesh M        = _Scene.Meshes[i];
                List <int>  _Indices = new List <int>(M.Faces.Count * 4);
                if (M.Faces.Count > 0)
                {
                    for (int j = 0; j < M.Faces.Count; j++)
                    {
                        if (M.Faces[j].Indices.Count > 4)
                        {
                            _Indices.Add(M.Faces[j].Indices[0]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[4]);
                            _Indices.Add(M.Faces[j].Indices[4]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[2]);
                            _Indices.Add(M.Faces[j].Indices[4]);
                            _Indices.Add(M.Faces[j].Indices[2]);
                            _Indices.Add(M.Faces[j].Indices[3]);
                        }
                        else
                        if (M.Faces[j].Indices.Count > 3)
                        {
                            _Indices.Add(M.Faces[j].Indices[0]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[3]);
                            _Indices.Add(M.Faces[j].Indices[3]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[2]);
                        }
                        else
                        {
                            _Indices.Add(M.Faces[j].Indices[0]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[2]);
                        }
                    }
                    _M.Indices = _Indices.ToArray();
                }

                Result.Meshes.Add(_M);
                //----------------Indices--------------------

                int[] Indices = M.GetIndices();

                _M.Material = AssimpConv.ConvertMaterial(_Scene.Materials[M.MaterialIndex]);
                _M.Texture  = LoadTexture(_Scene.Materials[M.MaterialIndex]);
                List <Vector3D> Vertices = M.Vertices;
                _M.Position = new xyzf[Vertices.Count];
                for (int j = 0; j < Vertices.Count; j++)
                {
                    Vector3D V = Vertices[j];
                    _M.Position[j] = new xyzf(V.X, V.Y, V.Z);
                }
                List <Vector3D> Normals = M.Normals;
                _M.Normals = new xyzf[Normals.Count];

                for (int j = 0; j < Normals.Count; j++)
                {
                    Vector3D V = Normals[j];
                    _M.Normals[j] = new xyzf(V.X, V.Y, V.Z).normalized();
                }
                if (M.TextureCoordinateChannelCount > 0)
                {
                    _M.TextureCoords = new xyf[M.TextureCoordinateChannels[0].Count];
                    for (int j = 0; j < M.TextureCoordinateChannels[0].Count; j++)
                    {
                        Vector3D V = M.TextureCoordinateChannels[0][j];
                        _M.TextureCoords[j] = new xyf(V.X, V.Y);
                    }
                }


                _M.Bones = new List <Bone>();
                for (int k = 0; k < M.BoneCount; k++)
                {
                    Assimp.Bone    B  = M.Bones[k];
                    VertexWeight[] VW = new VertexWeight[B.VertexWeights.Count];
                    for (int g = 0; g < VW.Length; g++)
                    {
                        VW[g] = new VertexWeight(B.VertexWeights[g].VertexID, B.VertexWeights[g].Weight);
                    }
                    Bone _B = new Bone(B.Name, AssimpConv.ConvertTransform(B.OffsetMatrix), VW);
                    _M.Bones.Add(_B);
                }
            }

            LoadNode(_Scene, Result);
            MoveTranslucentAtEnd(Result);
            Result._Scene        = _Scene;
            Result.SceneAnimator = new SceneAnimator(Result);
            return(Result);
        }