Example #1
0
        private static MESH_DATA SerializeMeshGeometry(MESH_FILE file, ShaderDataHelper shaderData, MeshGeometry meshGeometry)
        {
            var meshData = MESH_DATA.Create(meshGeometry.VertexCount, meshGeometry.IndexCount, file.IsTextured, file.IsFlexible);

            var vertIndexer = new ListIndexer <Vertex>(meshGeometry.Vertices);

            bool isTextured = meshGeometry.IsTextured;

            for (int i = 0; i < meshGeometry.Vertices.Count; i++)
            {
                var vert = meshGeometry.Vertices[i];
                meshData.Positions[i] = vert.Position;
                meshData.Normals[i]   = vert.Normal;

                if (file.IsTextured)
                {
                    meshData.UVs[i] = isTextured ? vert.TexCoord : new Vector2(0f);
                }

                if (file.IsFlexible && vert.BoneWeights.Any())
                {
                    var boneWeights = vert.BoneWeights.Select(x => new MESH_BONE_WEIGHT {
                        BoneID = x.BoneID, Weight = x.Weight
                    });
                    meshData.Bones[i] = new MESH_BONE_MAPPING(boneWeights);
                }
            }

            for (int i = 0; i < meshGeometry.Indices.Count; i++)
            {
                var idx = meshGeometry.Indices[i];
                meshData.Indices[i].VertexIndex = vertIndexer.IndexOf(idx.Vertex);

                meshData.Indices[i].AverageNormalIndex = shaderData.AvgNormals.IndexOf(idx.AverageNormal);

                int reIdx = shaderData.RoundEdgeData.IndexOf(idx.RoundEdgeData);

                int reOffset = reIdx * 12 + ((int)Math.Floor(reIdx / 21d) * 4);

                meshData.Indices[i].REShaderOffset = reOffset;
            }

            return(meshData);
        }
Example #2
0
        private static MESH_DATA ReadAlternateMesh(BinaryReaderEx br, MESH_FILE mesh, long boneMappingPosition, long meshDataSize)
        {
            long startPosition = br.Position;

            int vertexCount = br.ReadInt32();
            int indexCount  = br.ReadInt32();

            var geom = MESH_DATA.Create(vertexCount, indexCount, mesh.IsTextured, mesh.IsFlexible);


            for (int i = 0; i < vertexCount; i++)
            {
                geom.Positions[i] = new Vector3(br.ReadSingles(3));
            }

            for (int i = 0; i < vertexCount; i++)
            {
                geom.Normals[i] = new Vector3(br.ReadSingles(3));
            }

            if (mesh.IsTextured)
            {
                for (int i = 0; i < vertexCount; i++)
                {
                    geom.UVs[i] = new Vector2(br.ReadSingles(2));
                }
            }

            for (int i = 0; i < indexCount; i++)
            {
                geom.Indices[i] = new MESH_INDEX()
                {
                    VertexIndex = br.ReadInt32()
                }
            }
            ;

            for (int i = 0; i < indexCount; i++)
            {
                geom.Indices[i].AverageNormalIndex = br.ReadInt32();
            }

            for (int i = 0; i < indexCount; i++)
            {
                geom.Indices[i].REShaderOffset = br.ReadInt32();
            }

            if (mesh.IsFlexible)
            {
                Trace.WriteLine("WARNING Flexible alternate mesh encountered!");
                if (br.Position < startPosition + meshDataSize)
                {
                    var dataOffsets = new List <int>();
                    for (int i = 0; i < vertexCount; i++)
                    {
                        dataOffsets.Add(br.ReadInt32());
                    }

                    long dataEndPosition = br.Position;
                    for (int i = 0; i < vertexCount; i++)
                    {
                        geom.Bones[i] = ReadBoneMapping(br, boneMappingPosition, dataOffsets[i]);
                    }

                    br.Position = dataEndPosition;
                }
                else
                {
                    Trace.WriteLine("Flexible alternate mesh does not seem to be supported!");
                    geom.Bones = new MESH_BONE_MAPPING[0];
                }
            }

            return(geom);
        }
Example #3
0
        public static MESH_FILE ReadMeshFile(Stream stream)
        {
            stream.Position = 0;

            var meshFile = new MESH_FILE();

            using (var br = new BinaryReaderEx(stream, Encoding.UTF8, true))
            {
                var fileHeader = br.ReadStruct <MESH_HEADER>();

                if (fileHeader.Header != "10GB")
                {
                    throw new IOException("The file is not a LDD mesh file (*.g)");
                }

                meshFile.Header   = fileHeader;
                meshFile.Geometry = MESH_DATA.Create(fileHeader);

                // Vertices & triangles
                {
                    for (int i = 0; i < fileHeader.VertexCount; i++)
                    {
                        meshFile.Geometry.Positions[i] = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    }


                    for (int i = 0; i < fileHeader.VertexCount; i++)
                    {
                        meshFile.Geometry.Normals[i] = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    }

                    if (fileHeader.MeshType == (int)MeshType.StandardTextured || fileHeader.MeshType == (int)MeshType.FlexibleTextured)
                    {
                        for (int i = 0; i < fileHeader.VertexCount; i++)
                        {
                            meshFile.Geometry.UVs[i] = new Vector2(br.ReadSingle(), br.ReadSingle());
                        }
                    }

                    for (int i = 0; i < fileHeader.IndexCount; i++)
                    {
                        meshFile.Geometry.Indices[i] = new MESH_INDEX {
                            VertexIndex = br.ReadInt32()
                        }
                    }
                    ;
                }

                // Edge shader data (brick outlines)
                {
                    int shaderDataLength = br.ReadInt32();

                    int valueCounter = 0;
                    var shaderData   = new List <ROUNDEDGE_SHADER_DATA>();

                    while (valueCounter < shaderDataLength)
                    {
                        bool endOfRow      = 256 - ((valueCounter + 12) % 256) < 12;
                        int  valueCount    = endOfRow ? 16 : 12;
                        int  remainingData = shaderDataLength - valueCounter;

                        if (valueCount > remainingData)
                        {
                            if (endOfRow && 12 <= remainingData)
                            {
                                valueCount = 12;
                            }
                            else
                            {
                                Trace.WriteLine("Shader data length error!!!");
                                stream.Skip(remainingData * 4);
                                break;
                            }
                        }

                        shaderData.Add(new ROUNDEDGE_SHADER_DATA(br.ReadSingles(valueCount)));
                        valueCounter += valueCount;
                    }

                    meshFile.RoundEdgeShaderData = shaderData.ToArray();

                    for (int i = 0; i < fileHeader.IndexCount; i++)
                    {
                        meshFile.Geometry.Indices[i].REShaderOffset = br.ReadInt32();
                    }
                }

                // Average Normals
                {
                    int averageNormalsCount = br.ReadInt32();

                    //we skip the first item because it looks like an header and the maximum referenced value seems always one less the specified length
                    var dataHeader = new Vector3(br.ReadSingles(3));
                    if (dataHeader.X != 83 || dataHeader.Y != 0 || dataHeader.Z != 0)
                    {
                        Trace.WriteLine($"Unexpected  average normal header: {dataHeader}");
                    }

                    meshFile.AverageNormals = new Vector3[averageNormalsCount - 1];
                    for (int i = 0; i < averageNormalsCount - 1; i++)
                    {
                        meshFile.AverageNormals[i] = new Vector3(br.ReadSingles(3));
                    }

                    for (int i = 0; i < fileHeader.IndexCount; i++)
                    {
                        meshFile.Geometry.Indices[i].AverageNormalIndex = br.ReadInt32();
                    }
                }

                long boneMappingPosition = 0;

                // Flex data
                if (fileHeader.MeshType == (int)MeshType.Flexible || fileHeader.MeshType == (int)MeshType.FlexibleTextured)
                {
                    int dataSize = br.ReadInt32();
                    boneMappingPosition = stream.Position;

                    stream.Seek(dataSize, SeekOrigin.Current); //skip over the data

                    var dataOffsets = new List <int>();
                    for (int i = 0; i < fileHeader.VertexCount; i++)
                    {
                        dataOffsets.Add(br.ReadInt32());
                    }
                    long dataEndPosition = stream.Position;

                    for (int i = 0; i < fileHeader.VertexCount; i++)
                    {
                        meshFile.Geometry.Bones[i] = ReadBoneMapping(br, boneMappingPosition, dataOffsets[i]);
                    }

                    stream.Position = dataEndPosition;
                }

                int cullingInfoCount = br.ReadInt32();
                int cullingInfoSize  = br.ReadInt32();

                meshFile.Cullings = new MESH_CULLING[cullingInfoCount];

                for (int i = 0; i < cullingInfoCount; i++)
                {
                    meshFile.Cullings[i] = ReadCullingInfo(br, meshFile, boneMappingPosition);
                }
            }

            return(meshFile);
        }