Ejemplo n.º 1
0
        /// <summary>
        /// Exports the given model to the given output stream.
        /// </summary>
        /// <param name="filename">Name of the model.</param>
        /// <param name="scene">The model to output.</param>
        /// <param name="baseoutstream">The stream to output to.</param>
        /// <returns>The texture output data.</returns>
        static string ExportModelData(string filename, Scene scene, Stream baseoutstream)
        {
            baseoutstream.WriteByte((byte)'F');
            baseoutstream.WriteByte((byte)'M');
            baseoutstream.WriteByte((byte)'D');
            baseoutstream.WriteByte((byte)'0');
            baseoutstream.WriteByte((byte)'0');
            baseoutstream.WriteByte((byte)'1');
            MemoryStream  outputStreamInternal = new MemoryStream();
            StreamWrapper outstream            = new StreamWrapper(outputStreamInternal);

            outstream.WriteMatrix4x4(scene.RootNode.Transform);
            outstream.WriteInt(scene.MeshCount);
            Console.WriteLine($"Writing {scene.MeshCount} meshes...");
            StringBuilder textureFileBuilder = new StringBuilder();

            textureFileBuilder.Append($"model={filename}\n");
            for (int meshId = 0; meshId < scene.MeshCount; meshId++)
            {
                Mesh mesh = scene.Meshes[meshId];
                Console.WriteLine($"Writing mesh: {mesh.Name}");
                string nodeName = mesh.Name.ToLower().Replace('#', '_').Replace('.', '_');
                if (PreTransformNode && GetNode(scene.RootNode, nodeName) == null)
                {
                    Console.WriteLine($"NO NODE FOR: {nodeName}");
                    continue;
                }
                Matrix4x4 transformMatrix = PreTransformNode ? GetNode(scene.RootNode, nodeName).Transform *scene.RootNode.Transform : Matrix4x4.Identity;
                if (UseModelTexture)
                {
                    Material mater = scene.Materials[mesh.MaterialIndex];
                    if (mater.HasTextureDiffuse)
                    {
                        textureFileBuilder.Append($"{mesh.Name}={mater.TextureDiffuse.FilePath}\n");
                    }
                    if (mater.HasTextureSpecular)
                    {
                        textureFileBuilder.Append($"{mesh.Name}:::specular={scene.Materials[mesh.MaterialIndex].TextureSpecular.FilePath}\n");
                    }
                    if (mater.HasTextureReflection)
                    {
                        textureFileBuilder.Append($"{mesh.Name}:::reflectivity={scene.Materials[mesh.MaterialIndex].TextureReflection.FilePath}\n");
                    }
                    if (mater.HasTextureNormal)
                    {
                        textureFileBuilder.Append($"{mesh.Name}:::normal={scene.Materials[mesh.MaterialIndex].TextureNormal.FilePath}\n");
                    }
                }
                else
                {
                    textureFileBuilder.Append($"{mesh.Name}=UNKNOWN\n");
                }
                outstream.WriteStringProper(mesh.Name);
                outstream.WriteInt(mesh.VertexCount);
                for (int v = 0; v < mesh.VertexCount; v++)
                {
                    outstream.WriteVector3D(transformMatrix * mesh.Vertices[v]);
                }
                outstream.WriteInt(mesh.FaceCount);
                for (int f = 0; f < mesh.FaceCount; f++)
                {
                    Face face = mesh.Faces[f];
                    outstream.WriteInt(face.Indices[0]);
                    outstream.WriteInt(face.Indices[face.IndexCount > 1 ? 1 : 0]);
                    outstream.WriteInt(face.Indices[face.IndexCount > 2 ? 2 : 0]);
                }
                outstream.WriteInt(mesh.TextureCoordinateChannels[0].Count);
                for (int t = 0; t < mesh.TextureCoordinateChannels[0].Count; t++)
                {
                    outstream.WriteFloat(mesh.TextureCoordinateChannels[0][t].X);
                    outstream.WriteFloat(mesh.TextureCoordinateChannels[0][t].Y);
                }
                outstream.WriteInt(mesh.Normals.Count);
                Matrix4x4 normalMatrixRaw = transformMatrix;
                normalMatrixRaw.Inverse();
                normalMatrixRaw.Transpose();
                Matrix3x3 normalMatrix3 = new Matrix3x3(normalMatrixRaw);
                for (int n = 0; n < mesh.Normals.Count; n++)
                {
                    outstream.WriteVector3D(normalMatrix3 * mesh.Normals[n]);
                }
                outstream.WriteInt(mesh.BoneCount);
                for (int b = 0; b < mesh.BoneCount; b++)
                {
                    Bone bone = mesh.Bones[b];
                    outstream.WriteStringProper(bone.Name);
                    outstream.WriteInt(bone.VertexWeightCount);
                    for (int v = 0; v < bone.VertexWeightCount; v++)
                    {
                        outstream.WriteInt(bone.VertexWeights[v].VertexID);
                        outstream.WriteFloat(bone.VertexWeights[v].Weight);
                    }
                    outstream.WriteMatrix4x4(bone.OffsetMatrix);
                }
            }
            OutputNode(scene.RootNode, outstream);
            byte[] outputBytesRaw = outputStreamInternal.ToArray();
            outputBytesRaw = GZip(outputBytesRaw);
            baseoutstream.Write(outputBytesRaw, 0, outputBytesRaw.Length);
            return(textureFileBuilder.ToString());
        }