public H1StaticMeshLODResource(H1MeshContext context) { // defaultly pointing first material m_MaterialIndex = 0; // create local vertex factory m_LocalVertexFactory = new H1LocalVertexFactory(); // process mesh context for H1StaticMeshLODResource ProcessMeshContext(context); }
// private methods private void ProcessMeshContext(H1MeshContext context) { // offset tracking int currOffset = 0; // process vertex buffers and index buffer // 1. positions var positions = context.Positions.ToArray(); if (positions.Count() != 0) { LocalVertexFactory.PositionVertexBuffer = H1VertexBuffer.ProcessVertexBuffer(positions); LocalVertexFactory.PositionStreamComponent = new H1VertexStreamComponent(H1VertexStreamSematicType.Position, H1VertexElementType.Float3, currOffset++); } // 2. normals var normals = context.Normals.ToArray(); if (normals.Count() != 0) { LocalVertexFactory.NormalVertexBuffer = H1VertexBuffer.ProcessVertexBuffer(normals); LocalVertexFactory.NormalStreamComponent = new H1VertexStreamComponent(H1VertexStreamSematicType.Normal, H1VertexElementType.Float3, currOffset++); } // 3. texcoords // 3-1. looping UVBuffers foreach (var texcoords in context.UVBuffers) { if (texcoords.Buffer.Count() != 0) { LocalVertexFactory.TexcoordVertexBuffers.Add(H1VertexBuffer.ProcessVertexBuffer(texcoords.Buffer.ToArray())); LocalVertexFactory.AddTexcoordStreamComponent(new H1VertexStreamComponent(H1VertexStreamSematicType.Texcoord, H1VertexElementType.Float2, currOffset++)); } } // 3-2. looping UVWBuffers foreach (var texcoords in context.UVWBuffers) { if (texcoords.Buffer.Count() != 0) { LocalVertexFactory.TexcoordVertexBuffers.Add(H1VertexBuffer.ProcessVertexBuffer(texcoords.Buffer.ToArray())); LocalVertexFactory.AddTexcoordStreamComponent(new H1VertexStreamComponent(H1VertexStreamSematicType.Texcoord, H1VertexElementType.Float3, currOffset++)); } } // @TODO - temporal color component int numVertices = context.Positions.Count; Vector4[] colors = new Vector4[numVertices]; for (int i = 0; i < numVertices; ++i) { colors[i].X = 1.0f; colors[i].Y = 0.0f; colors[i].Z = 0.0f; colors[i].W = 1.0f; } LocalVertexFactory.ColorVertexBuffer = H1VertexBuffer.ProcessVertexBuffer(colors); LocalVertexFactory.ColorStreamComponent = new H1VertexStreamComponent(H1VertexStreamSematicType.Color, H1VertexElementType.Float4, currOffset++); // generate RHIVertexFormatDeclaration LocalVertexFactory.GenerateVertexDeclaration(); // 4. indices var indices = context.Indices.ToArray(); m_IndexBuffer = H1IndexBuffer.ProcessIndexBuffer(indices); }
private Boolean ExtractMeshData(Scene scene, ref List <H1MeshContext> meshContexts) { Int32 currMeshContextIndex = 0; foreach (Mesh mesh in scene.Meshes) // process each mesh in the scene { H1MeshContext currMeshContext = new H1MeshContext(); // set mesh name currMeshContext.Name = mesh.Name; // get the offset matrix Matrix globalOffsetMtx = GetOffsetMatrix(scene, currMeshContextIndex); // store LocalToTransform for later usage (converting offset matrix space to root node space) Vector3 translation; SharpDX.Quaternion rotation; Vector3 scaling; globalOffsetMtx.Decompose(out scaling, out rotation, out translation); currMeshContext.LocalToGlobalTransform.Scaling = scaling; currMeshContext.LocalToGlobalTransform.Rotation = rotation; currMeshContext.LocalToGlobalTransform.Translation = translation; // if mesh doesn't follow the rule below, do not process mesh in Assimp if (mesh.HasVertices && mesh.HasNormals && mesh.HasTangentBasis && mesh.TextureCoordinateChannels[0].Count > 0 && mesh.HasFaces) // process vertices in the mesh { int vertexCount = mesh.VertexCount; foreach (Vector3D vertex in mesh.Vertices) { Vector3 convertedVertex = new Vector3(vertex.X, vertex.Y, vertex.Z); // transform with the 'offsetMtx' Vector4 result = Vector3.Transform(convertedVertex, globalOffsetMtx); // divide by w for homogeneous vector result /= result.W; convertedVertex.X = result.X; convertedVertex.Y = result.Y; convertedVertex.Z = result.Z; currMeshContext.Positions.Add(convertedVertex); } foreach (Vector3D normal in mesh.Normals) { // @TODO - need to transform space appropriately (normal transform is applied by different algorithm! - scaling!) Vector3 convertedNormal = new Vector3(normal.X, normal.Y, normal.Z); currMeshContext.Normals.Add(convertedNormal); } foreach (Vector3D biTangent in mesh.BiTangents) { // @TODO - need to transform this appropriately Vector3 convertedBiTangent = new Vector3(biTangent.X, biTangent.Y, biTangent.Z); currMeshContext.BiTangents.Add(convertedBiTangent); } foreach (Vector3D tangent in mesh.Tangents) { // @TODO - need to transform this appropriately Vector3 convertedTangent = new Vector3(tangent.X, tangent.Y, tangent.Z); currMeshContext.Tangents.Add(convertedTangent); } // only handling one texture coordinates (first one and only UV type (not UVW type)), currently if (mesh.UVComponentCount[0] == 3) // if UVW type { throw new Exception("invalid UV component type (UVW), please check!"); } List <Vector2> Tecoord2Ds = currMeshContext.AddTexcoord2DBufferContext(); foreach (Vector3D texCoord in mesh.TextureCoordinateChannels[0]) { Vector2 convertedTexCoord = new Vector2(texCoord.X, texCoord.Y); Tecoord2Ds.Add(convertedTexCoord); } foreach (Face face in mesh.Faces) { if (face.IndexCount != 3) { // @TODO - split polygon to triangles! continue; //throw new Exception("invalid index count, it is over 3, please check!"); } foreach (UInt32 index in face.Indices) { currMeshContext.Indices.Add(index); } } meshContexts.Add(currMeshContext); } currMeshContextIndex++; } return(true); }