public static ModelData ReadModelData(Stream stream)
        {
            EngineBinaryReader engineBinaryReader = new EngineBinaryReader(stream, false);
            ModelData          modelData          = new ModelData();

            modelData.Bones.Capacity = engineBinaryReader.ReadInt32();
            for (int i = 0; i < modelData.Bones.Capacity; i++)
            {
                ModelBoneData modelBoneData = new ModelBoneData();
                modelData.Bones.Add(modelBoneData);
                modelBoneData.ParentBoneIndex = engineBinaryReader.ReadInt32();
                modelBoneData.Name            = engineBinaryReader.ReadString();
                modelBoneData.Transform       = engineBinaryReader.ReadMatrix();
            }



            modelData.Meshes.Capacity = engineBinaryReader.ReadInt32();
            for (int j = 0; j < modelData.Meshes.Capacity; j++)
            {
                ModelMeshData modelMeshData = new ModelMeshData();
                modelData.Meshes.Add(modelMeshData);
                modelMeshData.ParentBoneIndex    = engineBinaryReader.ReadInt32();
                modelMeshData.Name               = engineBinaryReader.ReadString();
                modelMeshData.MeshParts.Capacity = engineBinaryReader.ReadInt32();
                modelMeshData.BoundingBox        = engineBinaryReader.ReadBoundingBox();
                for (int k = 0; k < modelMeshData.MeshParts.Capacity; k++)
                {
                    ModelMeshPartData modelMeshPartData = new ModelMeshPartData();
                    modelMeshData.MeshParts.Add(modelMeshPartData);
                    modelMeshPartData.BuffersDataIndex = engineBinaryReader.ReadInt32();
                    modelMeshPartData.StartIndex       = engineBinaryReader.ReadInt32();
                    modelMeshPartData.IndicesCount     = engineBinaryReader.ReadInt32();
                    modelMeshPartData.BoundingBox      = engineBinaryReader.ReadBoundingBox();
                }
            }



            modelData.Buffers.Capacity = engineBinaryReader.ReadInt32();
            for (int l = 0; l < modelData.Buffers.Capacity; l++)
            {
                ModelBuffersData modelBuffersData = new ModelBuffersData();
                modelData.Buffers.Add(modelBuffersData);
                VertexElement[] array = new VertexElement[engineBinaryReader.ReadInt32()];
                for (int m = 0; m < array.Length; m++)
                {
                    array[m] = new VertexElement(engineBinaryReader.ReadInt32(), (VertexElementFormat)engineBinaryReader.ReadInt32(), engineBinaryReader.ReadString());
                }
                modelBuffersData.VertexDeclaration = new VertexDeclaration(array);
                modelBuffersData.Vertices          = engineBinaryReader.ReadBytes(engineBinaryReader.ReadInt32());
                modelBuffersData.Indices           = engineBinaryReader.ReadBytes(engineBinaryReader.ReadInt32());
            }



            return(modelData);
        }
Exemple #2
0
        XElement GetGeometry(ModelData model, ModelMeshData data)
        {
            ModelMeshPartData meshPart = data.MeshParts[0];
            ModelBoneData     boneData = model.Bones[data.ParentBoneIndex];
            string            meshId   = data.Name;

            var vertexBuffer      = model.Buffers[meshPart.BuffersDataIndex];
            int count             = meshPart.IndicesCount;
            var vertexDeclaration = vertexBuffer.VertexDeclaration;

            byte[] original = new byte[count * 32];
            using (BinaryReader reader = new BinaryReader(new MemoryStream(vertexBuffer.Indices)))
            {
                reader.BaseStream.Position = meshPart.StartIndex * 2;
                for (int i = 0; i < count; i++)
                {
                    short index = reader.ReadInt16();
                    Buffer.BlockCopy(vertexBuffer.Vertices, index * 32, original, i * 32, 32);
                }
            }

            List <Vector3> vertices = new List <Vector3>();
            List <Vector3> normals  = new List <Vector3>();

            float[] textureCord = new float[count * 2];
            int[]   indexs      = new int[count * 3];
            using (EngineBinaryReader reader = new EngineBinaryReader(new MemoryStream(original)))
            {
                foreach (VertexElement elem in vertexDeclaration.VertexElements)
                {
                    if (elem.Semantic.StartsWith("POSITION"))
                    {
                        Vector3[] triangle = new Vector3[3];
                        for (int i = 0; i < count; i++)
                        {
                            reader.BaseStream.Position = vertexDeclaration.VertexStride * i + elem.Offset;
                            var p = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            if (!vertices.Contains(p))
                            {
                                vertices.Add(p);
                            }
                            var ii = i % 3;
                            triangle[ii] = p;
                            if (ii == 2)
                            {
                                indexs[i * 3 - 6] = vertices.IndexOf(triangle[0]);
                                indexs[i * 3 - 3] = vertices.IndexOf(triangle[2]);
                                indexs[i * 3]     = vertices.IndexOf(triangle[1]);
                            }
                        }
                    }
                    else if (elem.Semantic.StartsWith("NORMAL"))
                    {
                        Vector3[] triangle = new Vector3[3];
                        for (int i = 0; i < count; i++)
                        {
                            reader.BaseStream.Position = vertexDeclaration.VertexStride * i + elem.Offset;
                            var p = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            if (!normals.Contains(p))
                            {
                                normals.Add(p);
                            }
                            var ii = i % 3;
                            triangle[ii] = p;
                            if (ii == 2)
                            {
                                indexs[i * 3 - 5] = normals.IndexOf(triangle[0]);
                                indexs[i * 3 - 2] = normals.IndexOf(triangle[2]);
                                indexs[i * 3 + 1] = normals.IndexOf(triangle[1]);
                            }
                        }
                    }
                    else if (elem.Semantic.StartsWith("TEXCOORD"))
                    {
                        for (int i = 0; i < count; i++)
                        {
                            reader.BaseStream.Position = vertexDeclaration.VertexStride * i + elem.Offset;
                            textureCord[i * 2]         = reader.ReadSingle();
                            textureCord[i * 2 + 1]     = 1f - reader.ReadSingle();
                            if (i % 3 == 2)
                            {
                                indexs[i * 3 - 4] = i - 2;
                                indexs[i * 3 - 1] = i;
                                indexs[i * 3 + 2] = i - 1;
                            }
                        }
                    }
                }
            }

            XElement positionSource;

            XElement normalSource;

            XElement texturecoorSource;

            XElement vertexSource;

            XElement meshElem = new XElement(
                colladaNS + "mesh",
                positionSource = GetSourceArray(
                    meshId,
                    "-mesh-positions",
                    string.Join(" ", vertices.ConvertAll(v => string.Format("{0} {1} {2}", v.X.ToString("R"), v.Y.ToString("R"), v.Z.ToString("R")))),
                    vertices.Count * 3,
                    3,
                    XYZParam()
                    ),
                normalSource = GetSourceArray(
                    meshId,
                    "-mesh-normals",
                    string.Join(" ", normals.ConvertAll(v => string.Format("{0} {1} {2}", v.X.ToString("R"), v.Y.ToString("R"), v.Z.ToString("R")))),
                    normals.Count * 3,
                    3,
                    XYZParam()
                    ),
                texturecoorSource = GetSourceArray(
                    meshId,
                    "-mesh-map",
                    string.Join(" ", textureCord.Select(f => f.ToString("R"))),
                    textureCord.Length,
                    2,
                    STParam()
                    ),
                vertexSource = new XElement(
                    colladaNS + "vertices",
                    new XAttribute("id", meshId + "-mesh-vertices"),
                    GetInput("POSITION", positionSource)
                    ),
                new XElement(
                    colladaNS + "triangles",
                    new XAttribute("count", count / 3),
                    GetInput("VERTEX", vertexSource, 0),
                    GetInput("NORMAL", normalSource, 1),
                    GetInput("TEXCOORD", texturecoorSource, 2),
                    new XElement(colladaNS + "p", string.Join(" ", indexs))
                    )
                );

            XElement geometry;

            root.Element(colladaNS + "library_geometries").Add(
                geometry = new XElement(
                    colladaNS + "geometry",
                    new XAttribute("id", meshId + "-mesh"),
                    new XAttribute("name", meshId),
                    meshElem
                    )
                );

            return(geometry);
        }