Esempio n. 1
0
        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);
        }