static void exportGroup(BinaryWriter dest, Assimp.Mesh mesh, Assimp.Scene scene, List<MeshNode> nodes) { UInt32 vertexFormat = VF(vertexPosition); if (mesh.HasBones) vertexFormat |= VF(vertexBone); if (mesh.HasNormals) vertexFormat |= VF(vertexNormal); if (mesh.HasTangentBasis) vertexFormat |= VF(vertexTangent) | VF(vertexBiTangent); for (int i = 0; i < mesh.TextureCoordinateChannelCount; i++ ) { vertexFormat |= VF(vertexUV0 + i); } dest.Write(vertexFormat); exportString(dest, mesh.Name); UInt16 vertexCount = (UInt16 ) mesh.VertexCount; UInt32 meshFlags = 0; dest.Write(meshFlags); dest.Write(vertexCount); MeshBlock vertexDataBlock; vertexDataBlock = new MeshBlock(dest, "VATX"); dest.Write(vertexPosition); dest.Write(typeVector3D); Matrix4x4 mat = scene.RootNode.Transform; for (int i = 0; i < mesh.VertexCount; i++) { Vector3D V = new Vector3D(); V.X = mesh.Vertices[i].X; V.Y = mesh.Vertices[i].Y; V.Z = mesh.Vertices[i].Z; dest.Write(V.X); dest.Write(V.Y); dest.Write(V.Z); } vertexDataBlock.EndBlock(dest); /*if (mesh.HasVertexColors(0)) { vertexDataBlock = new MeshBlock(w, "VATX"); dest.Write(vertexColor); dest.Write(typeColor); for (int i = 0; i < mesh.VertexCount; i++) { byte R = (byte)(mesh.VertexColorChannels[0][i].R * 255.0f); byte G = (byte)(mesh.VertexColorChannels[0][i].G * 255.0f); byte B = (byte)(mesh.VertexColorChannels[0][i].B * 255.0f); byte A = (byte)(mesh.VertexColorChannels[0][i].A * 255.0f); UInt32 color = (UInt32) (R + (G << 8) + (B << 16) + (A << 24)); dest.Write(color); } vertexDataBlock.EndBlock(w); }*/ if (mesh.HasBones) { vertexDataBlock = new MeshBlock(dest, "VATX"); dest.Write(vertexBone); dest.Write(typeFloat); for (int i = 0; i < mesh.VertexCount; i++) { int boneIndex = -1; for (int j = 0; j < nodes.Count; j++) { var bone = nodes[j].bone; if (bone == null) continue; if (bone.HasVertexWeights) { for (int k=0; k<bone.VertexWeightCount; k++) if (bone.VertexWeights[k].VertexID == i) { boneIndex = j; break; } } if (boneIndex >=0) { break; } } boneIndex++; float boneID = boneIndex; dest.Write(boneID); } vertexDataBlock.EndBlock(dest); } if (mesh.HasNormals) { vertexDataBlock = new MeshBlock(dest, "VATX"); dest.Write(vertexNormal); dest.Write(typeVector3D); for (int i = 0; i < mesh.VertexCount; i++) { dest.Write(mesh.Normals[i].X); dest.Write(mesh.Normals[i].Y); dest.Write(mesh.Normals[i].Z); } vertexDataBlock.EndBlock(dest); } if (mesh.HasTangentBasis) { vertexDataBlock = new MeshBlock(dest, "VATX"); dest.Write(vertexTangent); dest.Write(typeVector3D); for (int i = 0; i < mesh.VertexCount; i++) { dest.Write(mesh.Tangents[i].X); dest.Write(mesh.Tangents[i].Y); dest.Write(mesh.Tangents[i].Z); } vertexDataBlock.EndBlock(dest); vertexDataBlock = new MeshBlock(dest, "VATX"); dest.Write(vertexBiTangent); dest.Write(typeVector3D); for (int i = 0; i < mesh.VertexCount; i++) { dest.Write(mesh.BiTangents[i].X); dest.Write(mesh.BiTangents[i].Y); dest.Write(mesh.BiTangents[i].Z); } vertexDataBlock.EndBlock(dest); } for (int j = 0; j < mesh.TextureCoordinateChannelCount; j++) { vertexDataBlock = new MeshBlock(dest, "VATX"); byte uvSlot = (byte)(vertexUV0 + j); dest.Write(uvSlot); dest.Write(typeVector2D); for (int i = 0; i < mesh.VertexCount; i++) { dest.Write(mesh.TextureCoordinateChannels[j][i].X); dest.Write(mesh.TextureCoordinateChannels[j][i].Y); //dest.Write(mesh.TextureCoordinateChannels[j][i].Z); } vertexDataBlock.EndBlock(dest); } MeshBlock lodDataBlock; lodDataBlock = new MeshBlock(dest, "GLOD"); byte lodLevel = 0; UInt32 triangleCount = (UInt32) mesh.FaceCount; dest.Write(lodLevel); dest.Write(triangleCount); for (int i = 0; i < mesh.FaceCount; i++) { UInt16 A = (UInt16) mesh.Faces[i].Indices[0]; UInt16 B = (UInt16) mesh.Faces[i].Indices[1]; UInt16 C = (UInt16) mesh.Faces[i].Indices[2]; dest.Write(A); dest.Write(B); dest.Write(C); } lodDataBlock.EndBlock(dest); MeshBlock textureDataBlock; textureDataBlock = new MeshBlock(dest, "MDIF"); UInt32 diffuseColor = 0xFFFFFFFF; dest.Write(diffuseColor); exportString(dest, scene.Materials[mesh.MaterialIndex].TextureDiffuse.FilePath); textureDataBlock.EndBlock(dest); }
static void ExportFile(string fileName, string destFolder) { String targetMeshFile = Path.GetFileNameWithoutExtension(fileName) + ".mesh"; String targetAnimFile = Path.GetFileNameWithoutExtension(fileName) + ".anim"; Console.WriteLine("Exporting " + targetMeshFile + "..."); AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); importer.SetConfig(new VertexBoneWeightLimitConfig(4)); Scene scene = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessSteps.FlipUVs); System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone(); customCulture.NumberFormat.NumberDecimalSeparator = "."; System.Threading.Thread.CurrentThread.CurrentCulture = customCulture; FileStream fs = new FileStream(Path.Combine(destFolder, targetMeshFile), FileMode.Create); BinaryWriter dest = new BinaryWriter(fs); MeshBlock meshBlock = new MeshBlock(dest, "MX3D"); List<MeshNode> nodes = new List<MeshNode>(); addNodes(nodes, scene.RootNode, scene.Meshes[0]); for (int j = 0; j < 1; j++) { MeshBlock groupBlock = new MeshBlock(dest, "XGRP"); exportGroup(dest, scene.Meshes[j], scene, nodes); groupBlock.EndBlock(dest); } MeshBlock skeletonDataBlock; skeletonDataBlock = new MeshBlock(dest, "XSKL"); UInt32 boneCount = (UInt32)nodes.Count; dest.Write(boneCount); for (int j = 0; j < nodes.Count; j++) { exportBone(dest, nodes[j], scene, j); } skeletonDataBlock.EndBlock(dest); meshBlock.EndBlock(dest); dest.Close(); fs.Close(); for (int i = 0; i < scene.AnimationCount; i++) { Animation animation = scene.Animations[i]; String name = animation.Name; if (name.Length <= 0) { name = Path.GetFileNameWithoutExtension(targetAnimFile); int p = name.LastIndexOf("@"); if (p >= 0) { name = name.Substring(p + 1); } } Console.WriteLine("Exporting " + name + " animation..."); fs = new FileStream(Path.Combine(destFolder, targetAnimFile), FileMode.Create); dest = new BinaryWriter(fs); byte[] tagData = Encoding.ASCII.GetBytes("ANIM"); dest.Write(tagData); float FPS = (float)animation.TicksPerSecond; dest.Write(FPS); byte loop = 1; dest.Write(loop); float loopPoint = 0.0f; dest.Write(loopPoint); float animSpeed = 1.0f; dest.Write(animSpeed); String nextAnim = ""; exportString(dest, nextAnim); UInt32 channelCount = (UInt32)animation.NodeAnimationChannelCount; dest.Write(channelCount); for (int j = 0; j < channelCount; j++) { NodeAnimationChannel channel = animation.NodeAnimationChannels[j]; exportString(dest, channel.NodeName); UInt32 posCount = (UInt32)channel.PositionKeyCount; dest.Write(posCount); for (int k = 0; k < posCount; k++) { float t = (float)channel.PositionKeys[k].Time; float x = channel.PositionKeys[k].Value.X; float y = channel.PositionKeys[k].Value.Y; float z = channel.PositionKeys[k].Value.Z; float w = 1.0f; dest.Write(t); dest.Write(x); dest.Write(y); dest.Write(z); dest.Write(w); } UInt32 rotCount = (UInt32)channel.RotationKeyCount; dest.Write(rotCount); for (int k = 0; k < rotCount; k++) { float t = (float)channel.RotationKeys[k].Time; float x = channel.RotationKeys[k].Value.X; float y = channel.RotationKeys[k].Value.Y; float z = channel.RotationKeys[k].Value.Z; float w = channel.RotationKeys[k].Value.W; dest.Write(t); dest.Write(x); dest.Write(y); dest.Write(z); dest.Write(w); } UInt32 scaleCount = (UInt32)channel.ScalingKeyCount; dest.Write(scaleCount); for (int k = 0; k < scaleCount; k++) { float t = (float)channel.ScalingKeys[k].Time; float x = channel.ScalingKeys[k].Value.X; float y = channel.ScalingKeys[k].Value.Y; float z = channel.ScalingKeys[k].Value.Z; float w = 1.0f; dest.Write(t); dest.Write(x); dest.Write(y); dest.Write(z); dest.Write(w); } } dest.Close(); fs.Close(); } }