/// <summary> /// Outputs an animation node to the given output stream. /// </summary> /// <param name="node">The node to output.</param> /// <param name="outstream">The stream to output to.</param> static void OutputNode(Node node, StreamWrapper outstream) { outstream.WriteStringProper(node.Name); Console.WriteLine($"Output node: {node.Name}"); outstream.WriteMatrix4x4(node.Transform); outstream.WriteInt(node.ChildCount); for (int i = 0; i < node.ChildCount; i++) { OutputNode(node.Children[i], outstream); } }
/// <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()); }