public void ExportAssImp(string fileName, string modelType, ExportSettings settings) { fileName = Path.GetFullPath(fileName); // Get absolute path instead of relative string outDir = Path.GetDirectoryName(fileName); string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); fileName = Path.Combine(outDir, fileNameNoExt + ".dae"); Scene outScene = new Scene(); outScene.RootNode = new Node("RootNode"); Materials.FillScene(outScene, Textures, outDir); Shapes.FillScene(outScene, VertexData.Attributes, Joints.FlatSkeleton, SkinningEnvelopes.InverseBindMatrices); Scenegraph.FillScene(outScene, Joints.FlatSkeleton, settings.UseSkeletonRoot); Scenegraph.CorrectMaterialIndices(outScene, Materials); Textures.DumpTextures(outDir); foreach (Mesh mesh in outScene.Meshes) { // Assimp has a JoinIdenticalVertices post process step, but we can't use that or the skinning info we manually add won't take it into account. RemoveDuplicateVertices(mesh); } AssimpContext cont = new AssimpContext(); cont.ExportFile(outScene, fileName, "collada", PostProcessSteps.ValidateDataStructure); //if (SkinningEnvelopes.Weights.Count == 0) // return; // There's no skinning information, so we can stop here // Now we need to add some skinning info, since AssImp doesn't do it for some bizarre reason StreamWriter test = new StreamWriter(fileName + ".tmp"); StreamReader dae = File.OpenText(fileName); while (!dae.EndOfStream) { string line = dae.ReadLine(); if (line == " <library_visual_scenes>") { AddControllerLibrary(outScene, test); test.WriteLine(line); test.Flush(); } else if (line.Contains("<node")) { Regex reg = new Regex("^( +)<node id=\"([^\"]+)\" +name=\"[^\"]+\" +type=\"NODE\">$"); Match match = reg.Match(line); if (match.Success) { string indentation = match.Groups[1].Value; string joint_name = match.Groups[2].Value; if (Joints.FlatSkeleton.Exists(x => x.Name == joint_name)) { string jointLine = indentation + $"<node id=\"{joint_name}\" name=\"{joint_name}\" sid=\"{joint_name}\" type=\"JOINT\">"; test.WriteLine(jointLine); } else { test.WriteLine(line); } } else { test.WriteLine(line); } test.Flush(); } else if (line.Contains("<material id=\"")) { Regex reg = new Regex("^ <material id=\"([^\"]+)\" name=\"[^\"]+\">$"); Match match = reg.Match(line); if (match.Success) { string mat_name_sanitized = match.Groups[1].Value; int mat_index = Materials.GetMaterialIndexFromSanitizedMaterialName(mat_name_sanitized); string mat_name = Materials.m_Materials[mat_index].Name; string matLine = $" <material id=\"{mat_name_sanitized}\" name=\"{mat_name}\">"; test.WriteLine(matLine); } else { test.WriteLine(line); } test.Flush(); } else if (line.Contains("</visual_scene>")) { foreach (Mesh mesh in outScene.Meshes) { test.WriteLine($" <node id=\"{ mesh.Name }\" name=\"{ mesh.Name }\" type=\"NODE\">"); test.WriteLine($" <instance_controller url=\"#{ mesh.Name }-skin\">"); test.WriteLine(" <skeleton>#skeleton_root</skeleton>"); test.WriteLine(" <bind_material>"); test.WriteLine(" <technique_common>"); test.WriteLine($" <instance_material symbol=\"{ Materials.m_Materials[mesh.MaterialIndex].Name }\" target=\"#{ Materials.m_Materials[mesh.MaterialIndex].Name.Replace("(", "_").Replace(")", "_") }\" />"); test.WriteLine(" </technique_common>"); test.WriteLine(" </bind_material>"); test.WriteLine(" </instance_controller>"); test.WriteLine(" </node>"); test.Flush(); } test.WriteLine(line); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } test.Close(); dae.Close(); File.Copy(fileName + ".tmp", fileName, true); File.Delete(fileName + ".tmp"); }
public void ExportAssImp(string fileName, string outFilepath, string modelType, ExportSettings settings, bool keepmatnames = true) { string outDir = Path.GetDirectoryName(outFilepath); //string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); fileName = outFilepath;//Path.Combine(outDir, fileNameNoExt + ".dae"); Scene outScene = new Scene(); outScene.RootNode = new Node("RootNode"); Scenegraph.FillScene(outScene, Joints.FlatSkeleton, settings.UseSkeletonRoot); Dictionary <string, int> slots_to_uvindex = Materials.FillScene(outScene, Textures, outDir, keepmatnames); Shapes.FillScene(outScene, VertexData.Attributes, Joints.FlatSkeleton, SkinningEnvelopes.InverseBindMatrices); Scenegraph.CorrectMaterialIndices(outScene, Materials); Textures.DumpTextures(outDir); foreach (Mesh mesh in outScene.Meshes) { Console.WriteLine(String.Format("Texcoord count: {0}", mesh.TextureCoordinateChannelCount)); } if (true) //(SkinningEnvelopes.Weights.Count == 0) { Assimp.Node geomNode = new Node(Path.GetFileNameWithoutExtension(fileName), outScene.RootNode); for (int i = 0; i < Shapes.Shapes.Count; i++) { geomNode.MeshIndices.Add(i); } outScene.RootNode.Children.Add(geomNode); } AssimpContext cont = new AssimpContext(); cont.ExportFile(outScene, fileName, "collada", PostProcessSteps.ValidateDataStructure | PostProcessSteps.JoinIdenticalVertices); //cont.ExportFile(outScene, fileName, "collada"); List <string> a; //if (SkinningEnvelopes.Weights.Count == 0) // return; // There's no skinning information, so we can stop here //return; // adding skinning info is buggy so we won't do it // Now we need to add some skinning info, since AssImp doesn't do it for some bizarre reason bool hasWeights = SkinningEnvelopes.Weights.Count != 0; hasWeights = false; StreamWriter test = new StreamWriter(fileName + ".tmp"); StreamReader dae = File.OpenText(fileName); bool dontWrite = false; while (!dae.EndOfStream) { string line = dae.ReadLine(); //if (SkinningEnvelopes.Weights.Count != 0) { if (hasWeights && line == " <library_visual_scenes>") { AddControllerLibrary(outScene, test); test.WriteLine(line); test.Flush(); } else if (hasWeights && line.Contains("<node")) { string[] testLn = line.Split('\"'); string name = testLn[3]; if (Joints.FlatSkeleton.Exists(x => x.Name == name)) { string jointLine = line.Replace(">", $" sid=\"{ name }\" type=\"JOINT\">"); test.WriteLine(jointLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } else if (hasWeights && line.Contains("</visual_scene>")) { foreach (Mesh mesh in outScene.Meshes) { string matname = "mat"; if (keepmatnames == true) { matname = AssimpMatnameSanitize(mesh.MaterialIndex, outScene.Materials[mesh.MaterialIndex].Name); } else { matname = AssimpMatnameSanitize(mesh.MaterialIndex, matname); } test.WriteLine($" <node id=\"{ mesh.Name }\" name=\"{ mesh.Name }\" type=\"NODE\">"); test.WriteLine($" <instance_controller url=\"#{ mesh.Name }-skin\">"); test.WriteLine(" <skeleton>#skeleton_root</skeleton>"); test.WriteLine(" <bind_material>"); test.WriteLine(" <technique_common>"); test.WriteLine($" <instance_material symbol=\"theresonlyone\" target=\"#{matname}\" />"); test.WriteLine(" </technique_common>"); test.WriteLine(" </bind_material>"); test.WriteLine(" </instance_controller>"); test.WriteLine(" </node>"); test.Flush(); } test.WriteLine(line); test.Flush(); } else if (hasWeights && line.Contains("<matrix")) { string matLine = line.Replace("<matrix>", "<matrix sid=\"matrix\">"); test.WriteLine(matLine); test.Flush(); } else if (line.Contains("<library_images>")) { dontWrite = true; Console.WriteLine("Hello Hallo"); } else if (line.Contains("</library_images>")) { dontWrite = false; Console.WriteLine("Hello Hallo2"); // Add our own images here test.WriteLine(" <library_images>"); WriteTexturesToStream(outScene, test); test.WriteLine(line); test.Flush(); } else if (line.Contains("<library_effects>")) { dontWrite = true; Console.WriteLine("Hello Hallo3"); // We get rid of the existing library effects } else if (line.Contains("</library_effects>")) { dontWrite = false; Console.WriteLine("Hello Hallo4"); // Add our own library_effects here test.WriteLine(" <library_effects>"); WriteMaterialsToStream(outScene, test, slots_to_uvindex); test.WriteLine(line); test.Flush(); } else if (!dontWrite) { test.WriteLine(line); test.Flush(); } } test.Close(); dae.Close(); File.Copy(fileName + ".tmp", fileName, true); File.Delete(fileName + ".tmp"); }
public void ExportAssImp(string fileName, string modelType, ExportSettings settings) { string outDir = Path.GetDirectoryName(fileName); string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); fileName = Path.Combine(outDir, fileNameNoExt + ".dae"); Scene outScene = new Scene(); outScene.RootNode = new Node("RootNode"); Scenegraph.FillScene(outScene, Joints.FlatSkeleton, settings.UseSkeletonRoot); Materials.FillScene(outScene, Textures, outDir); Shapes.FillScene(outScene, VertexData.Attributes, Joints.FlatSkeleton, SkinningEnvelopes.InverseBindMatrices); Scenegraph.CorrectMaterialIndices(outScene, Materials); if (SkinningEnvelopes.Weights.Count == 0) { Assimp.Node geomNode = new Node(Path.GetFileNameWithoutExtension(fileName), outScene.RootNode); for (int i = 0; i < Shapes.Shapes.Count; i++) { geomNode.MeshIndices.Add(i); } outScene.RootNode.Children.Add(geomNode); } AssimpContext cont = new AssimpContext(); cont.ExportFile(outScene, fileName, "collada", PostProcessSteps.ValidateDataStructure); if (SkinningEnvelopes.Weights.Count == 0) { return; // There's no skinning information, so we can stop here } // Now we need to add some skinning info, since AssImp doesn't do it for some bizarre reason StreamWriter test = new StreamWriter(fileName + ".tmp"); StreamReader dae = File.OpenText(fileName); while (!dae.EndOfStream) { string line = dae.ReadLine(); if (line == " <library_visual_scenes>") { AddControllerLibrary(outScene, test); test.WriteLine(line); test.Flush(); } else if (line.Contains("<node")) { string[] testLn = line.Split('\"'); string name = testLn[3]; if (Joints.FlatSkeleton.Exists(x => x.Name == name)) { string jointLine = line.Replace(">", $" sid=\"{ name }\" type=\"JOINT\">"); test.WriteLine(jointLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } else if (line.Contains("</visual_scene>")) { foreach (Mesh mesh in outScene.Meshes) { test.WriteLine($" <node id=\"{ mesh.Name }\" name=\"{ mesh.Name }\" type=\"NODE\">"); test.WriteLine($" <instance_controller url=\"#{ mesh.Name }-skin\">"); test.WriteLine(" <skeleton>#skeleton_root</skeleton>"); test.WriteLine(" <bind_material>"); test.WriteLine(" <technique_common>"); test.WriteLine($" <instance_material symbol=\"theresonlyone\" target=\"#m{ mesh.MaterialIndex }mat\" />"); test.WriteLine(" </technique_common>"); test.WriteLine(" </bind_material>"); test.WriteLine(" </instance_controller>"); test.WriteLine(" </node>"); test.Flush(); } test.WriteLine(line); test.Flush(); } else if (line.Contains("<matrix")) { string matLine = line.Replace("<matrix>", "<matrix sid=\"matrix\">"); test.WriteLine(matLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } test.Close(); dae.Close(); File.Copy(fileName + ".tmp", fileName, true); File.Delete(fileName + ".tmp"); }
public void ExportAssImp(string fileName, string modelType, ExportSettings settings, Arguments cmdargs) { fileName = Path.GetFullPath(fileName); // Get absolute path instead of relative string outDir = Path.GetDirectoryName(fileName); string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); if (modelType == "obj") { fileName = Path.Combine(outDir, fileNameNoExt + ".obj"); } else { fileName = Path.Combine(outDir, fileNameNoExt + ".dae"); } Scene outScene = new Scene { RootNode = new Node("RootNode") }; Console.WriteLine(); Console.WriteLine("Processing Materials ->"); Materials.FillScene(outScene, Textures, outDir); Console.WriteLine(); Console.WriteLine("Processing Meshes ->"); Shapes.FillScene(outScene, VertexData.Attributes, Joints.FlatSkeleton, SkinningEnvelopes.InverseBindMatrices); Console.WriteLine(); Console.Write("Processing Skeleton"); Scenegraph.FillScene(outScene, Joints.FlatSkeleton, settings.UseSkeletonRoot); Scenegraph.CorrectMaterialIndices(outScene, Materials); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Processing Textures ->"); Textures.DumpTextures(outDir, fileNameNoExt + "_tex_headers.json", true, cmdargs.readMipmaps); string infPath = Path.Combine(outDir, fileNameNoExt + "_hierarchy.json"); this.Scenegraph.DumpJson(infPath); Console.WriteLine(); Console.WriteLine("Removing Duplicate Verticies ->"); foreach (Mesh mesh in outScene.Meshes) { Console.Write(mesh.Name.Replace('_', ' ') + ": "); // Assimp has a JoinIdenticalVertices post process step, but we can't use that or the skinning info we manually add won't take it into account. RemoveDuplicateVertices(mesh); Console.Write("✓"); Console.WriteLine(); } AssimpContext cont = new AssimpContext(); if (modelType == "obj") { Console.WriteLine("Writing the OBJ file..."); cont.ExportFile(outScene, fileName, "obj");//, PostProcessSteps.ValidateDataStructure); using (System.IO.StreamWriter file = new System.IO.StreamWriter(fileName)) { string mtllibname = fileName.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries).Last() + ".mtl"; file.WriteLine(String.Format("mtllib {0}", mtllibname)); foreach (Assimp.Mesh mesh in outScene.Meshes) { foreach (Assimp.Vector3D vertex in mesh.Vertices) { file.WriteLine(String.Format("v {0} {1} {2}", vertex.X, vertex.Y, vertex.Z)); } } foreach (Assimp.Mesh mesh in outScene.Meshes) { foreach (Assimp.Vector3D normal in mesh.Normals) { file.WriteLine(String.Format("vn {0} {1} {2}", normal.X, normal.Y, normal.Z)); } } foreach (Assimp.Mesh mesh in outScene.Meshes) { if (mesh.HasTextureCoords(0)) { foreach (Assimp.Vector3D uv in mesh.TextureCoordinateChannels[0]) { file.WriteLine(String.Format("vt {0} {1}", uv.X, uv.Y)); } } } int vertex_offset = 1; foreach (Assimp.Mesh mesh in outScene.Meshes) { string material_name = outScene.Materials[mesh.MaterialIndex].Name; file.WriteLine(String.Format("usemtl {0}", material_name)); foreach (Assimp.Face face in mesh.Faces) { file.Write("f "); foreach (int index in face.Indices) { file.Write(index + vertex_offset); if (mesh.HasTextureCoords(0)) { file.Write("/"); file.Write(index + vertex_offset); } if (!mesh.HasTextureCoords(0) && mesh.HasNormals) { file.Write("//"); file.Write(index + vertex_offset); } else if (mesh.HasNormals) { file.Write("/"); file.Write(index + vertex_offset); } file.Write(" "); } file.Write("\n"); } vertex_offset += mesh.VertexCount; } } return; } else { cont.ExportFile(outScene, fileName, "collada", PostProcessSteps.ValidateDataStructure); } //if (SkinningEnvelopes.Weights.Count == 0) // return; // There's no skinning information, so we can stop here // Now we need to add some skinning info, since AssImp doesn't do it for some bizarre reason StreamWriter test = new StreamWriter(fileName + ".tmp"); StreamReader dae = File.OpenText(fileName); Console.WriteLine(); Console.Write("Finalizing the Mesh"); while (!dae.EndOfStream) { string line = dae.ReadLine(); if (line == " <library_visual_scenes>") { AddControllerLibrary(outScene, test); test.WriteLine(line); test.Flush(); } else if (line.Contains("<node")) { string[] testLn = line.Split('\"'); string name = testLn[3]; if (Joints.FlatSkeleton.Exists(x => x.Name == name)) { string jointLine = line.Replace(">", $" sid=\"{ name }\" type=\"JOINT\">"); test.WriteLine(jointLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } else if (line.Contains("</visual_scene>")) { foreach (Mesh mesh in outScene.Meshes) { string matname = "mat"; bool keepmatnames = false; if (keepmatnames == true) { matname = AssimpMatnameSanitize(mesh.MaterialIndex, outScene.Materials[mesh.MaterialIndex].Name); } else { matname = AssimpMatnameSanitize(mesh.MaterialIndex, Materials.m_Materials[mesh.MaterialIndex].Name); } test.WriteLine($" <node id=\"{ mesh.Name }\" name=\"{ mesh.Name }\" type=\"NODE\">"); test.WriteLine($" <instance_controller url=\"#{ mesh.Name }-skin\">"); test.WriteLine(" <skeleton>#skeleton_root</skeleton>"); test.WriteLine(" <bind_material>"); test.WriteLine(" <technique_common>"); test.WriteLine($" <instance_material symbol=\"m{matname}\" target=\"#{matname}\" />"); test.WriteLine(" </technique_common>"); test.WriteLine(" </bind_material>"); test.WriteLine(" </instance_controller>"); test.WriteLine(" </node>"); test.Flush(); } test.WriteLine(line); test.Flush(); } else if (line.Contains("<matrix")) { string matLine = line.Replace("<matrix>", "<matrix sid=\"matrix\">"); test.WriteLine(matLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } Console.Write("."); } Console.Write("✓"); Console.WriteLine(); test.Close(); dae.Close(); File.Copy(fileName + ".tmp", fileName, true); File.Delete(fileName + ".tmp"); }