/// <summary> /// Reads the index buffer data and converts it into a triangle list if necessary. /// </summary> /// <param name="reader">The mesh reader to use.</param> /// <param name="part">The mesh part to read.</param> /// <param name="resourceStream">A stream open on the resource data.</param> /// <returns>The index buffer converted into a triangle list.</returns> public static uint[] ReadIndices(MeshReader reader, Mesh.Part part, Stream resourceStream) { // Use index buffer 0 var indexBuffer = reader.IndexBuffers[0]; if (indexBuffer == null) { throw new InvalidOperationException("Index buffer 0 is null"); } // Read the indexes var indexStream = reader.OpenIndexBufferStream(indexBuffer, resourceStream); indexStream.Position = part.FirstIndex; switch (indexBuffer.Type) { case PrimitiveType.TriangleList: return(indexStream.ReadIndices(part.IndexCount)); case PrimitiveType.TriangleStrip: return(indexStream.ReadTriangleStrip(part.IndexCount)); default: throw new InvalidOperationException("Unsupported index buffer type: " + indexBuffer.Type); } }
/// <summary> /// Defines a part in the current mesh. /// </summary> /// <param name="materialIndex">Index of the material.</param> /// <param name="firstIndex">The first index.</param> /// <param name="indexCount">The index count.</param> /// <param name="vertexCount">The vertex count.</param> /// <exception cref="System.InvalidOperationException">Cannot define a part if no mesh is active</exception> public void DefinePart(short materialIndex, ushort firstIndex, ushort indexCount, ushort vertexCount) { if (_currentMesh == null) { throw new InvalidOperationException("Cannot define a part if no mesh is active"); } var part = new Mesh.Part { MaterialIndex = materialIndex, Unknown2 = -1, FirstIndex = firstIndex, IndexCount = indexCount, FirstSubPartIndex = (short)_currentMesh.Mesh.SubParts.Count, SubPartCount = 1, // TODO: Unknown values here VertexCount = vertexCount, }; // It doesn't seem like the game really ever uses subparts for // most models, but define one anyway var subPart = new Mesh.SubPart { FirstIndex = firstIndex, IndexCount = indexCount, PartIndex = (short)_currentMesh.Mesh.Parts.Count, VertexCount = vertexCount, }; _currentMesh.Mesh.Parts.Add(part); _currentMesh.Mesh.SubParts.Add(subPart); }
/// <summary> /// Defines a part in the current mesh. /// </summary> /// <param name="materialIndex">Index of the material.</param> /// <param name="firstIndex">The first index.</param> /// <param name="indexCount">The index count.</param> /// <param name="vertexCount">The vertex count.</param> /// <exception cref="System.InvalidOperationException">Cannot define a part if no mesh is active</exception> public void DefinePart(short materialIndex, ushort firstIndex, ushort indexCount, ushort vertexCount) { if (_currentMesh == null) throw new InvalidOperationException("Cannot define a part if no mesh is active"); var part = new Mesh.Part { MaterialIndex = materialIndex, Unknown2 = -1, FirstIndex = firstIndex, IndexCount = indexCount, FirstSubPartIndex = (short)_currentMesh.Mesh.SubParts.Count, SubPartCount = 1, // TODO: Unknown values here VertexCount = vertexCount, }; // It doesn't seem like the game really ever uses subparts for // most models, but define one anyway var subPart = new Mesh.SubPart { FirstIndex = firstIndex, IndexCount = indexCount, PartIndex = (short)_currentMesh.Mesh.Parts.Count, VertexCount = vertexCount, }; _currentMesh.Mesh.Parts.Add(part); _currentMesh.Mesh.SubParts.Add(subPart); }