public string GetMaterialListExport() { var materialsExport = new StringBuilder(); foreach (Material material in Materials) { if (material.IsInvisible) { continue; } List <string> bitmapNames = material.GetAllBitmapNames(); if (bitmapNames == null || bitmapNames.Count == 0) { continue; } string pngName = ImageWriter.GetExportedImageName(bitmapNames[0], material.ShaderType); pngName = pngName.Substring(0, pngName.Length - 4); materialsExport.AppendLine("newmtl " + pngName); materialsExport.AppendLine("Ka 1.000 1.000 1.000"); materialsExport.AppendLine("Kd 1.000 1.000 1.000"); materialsExport.AppendLine("Ks 0.000 0.000 0.000"); materialsExport.AppendLine("d 1.0 "); materialsExport.AppendLine("illum 2"); materialsExport.AppendLine("map_Kd " + pngName + ".png"); } return(materialsExport.ToString()); }
/// <summary> /// Returns a string containing an OBJ export for this mesh /// </summary> /// <param name="forceMaterialList">Forces the export to use a specific material list - e.g. model head</param> /// <returns>The OBJ export</returns> public string GetSkeletonMeshExport(string forceMaterialList = null) { var export = new StringBuilder(); export.AppendLine(LanternStrings.ObjMaterialHeader + (string.IsNullOrEmpty(forceMaterialList) ? FixCharacterMeshName(Name, true) : FixCharacterMeshName(forceMaterialList, true)) + LanternStrings.FormatMtlExtension); for (var i = 0; i < Vertices.Count; i++) { vec3 vertex = Vertices[i]; vec2 uvs = TextureUvCoordinates[i]; export.AppendLine("v " + (vertex.x + Center.x) + " " + (vertex.y + Center.y) + " " + (vertex.z + Center.z)); export.AppendLine("vt " + uvs.x + " " + uvs.y); } int currentPolygon = 0; foreach (RenderGroup group in RenderGroups) { string bitmapName = MaterialList.Materials[group.TextureIndex].TextureInfoReference.TextureInfo .BitmapNames[0].Filename; if (bitmapName.ToLower().StartsWith("chain")) { } string slotName = string.Empty; slotName = MaterialList.Materials[group.TextureIndex].ExportName; string pngName = bitmapName.Substring(0, bitmapName.Length - 4); string materialName = ImageWriter.GetExportedImageName(pngName, MaterialList.Materials[group.TextureIndex].ShaderType); export.AppendLine(LanternStrings.ObjUseMtlPrefix + slotName); for (int i = 0; i < group.PolygonCount; ++i) { int vertex1 = Polygons[currentPolygon].Vertex1 + 1; int vertex2 = Polygons[currentPolygon].Vertex2 + 1; int vertex3 = Polygons[currentPolygon].Vertex3 + 1; export.AppendLine("f " + vertex3 + "/" + vertex3 + " " + vertex2 + "/" + vertex2 + " " + +vertex1 + "/" + vertex1); currentPolygon++; } } // Ensure that output use the decimal point rather than the comma (as in Germany) string exportString = export.ToString().Replace(',', '.'); return(exportString); }
/// <summary> /// Exports the list of material and their associated shader types /// This is not the same as the material definition files associated with each model /// </summary> private void ExportMaterialList() { var materialListExport = new StringBuilder(); materialListExport.AppendLine(LanternStrings.ExportHeaderTitle + "Material List Information"); materialListExport.AppendLine(LanternStrings.ExportHeaderFormat + "BitmapName, BitmapCount, FrameDelay (optional)"); for (int i = 0; i < _fragmentTypeDictionary[0x31].Count; ++i) { if (!(_fragmentTypeDictionary[0x31][i] is MaterialList materialList)) { continue; } foreach (Material material in materialList.Materials) { if (material.IsInvisible) { continue; } string textureName = material.TextureInfoReference.TextureInfo.BitmapNames[0] .Filename; textureName = ImageWriter.GetExportedImageName(textureName, material.ShaderType); textureName = textureName.Substring(0, textureName.Length - 4); materialListExport.Append(textureName); materialListExport.Append(","); materialListExport.Append(material.TextureInfoReference.TextureInfo.BitmapNames.Count); if (material.TextureInfoReference.TextureInfo.IsAnimated) { materialListExport.Append("," + material.TextureInfoReference.TextureInfo.AnimationDelayMs); } materialListExport.AppendLine(); } } string fileName; if (_wldType == WldType.Zone) { string exportFolder = _zoneName + "/" + LanternStrings.ExportZoneFolder; Directory.CreateDirectory(exportFolder); fileName = exportFolder + "/" + _zoneName; } else if (_wldType == WldType.Objects) { string exportFolder = _zoneName + "/" + LanternStrings.ExportObjectsFolder; Directory.CreateDirectory(exportFolder); fileName = exportFolder + "/" + _zoneName; fileName += "_objects"; } else { string exportFolder = _zoneName + "/" + LanternStrings.ExportCharactersFolder; Directory.CreateDirectory(exportFolder); fileName = exportFolder + "/" + _zoneName; fileName += "_characters"; } fileName += "_materials.txt"; File.WriteAllText(fileName, materialListExport.ToString()); }
/// <summary> /// Gathers material lists for each skin variant to be output to .MTL files /// </summary> /// <returns>The list of material file content strings</returns> public List <string> GetMaterialSkinExports() { if (Name.ToLower().StartsWith("baf")) { } var materialExports = new List <string>(); var baseSkinMaterials = new List <string>(); for (int i = 0; i < Skins.Count; ++i) { var materialsExport = new StringBuilder(); var currentUsedSlots = new List <string>(); foreach (KeyValuePair <int, Material> materialMapping in Skins[i]) { Material material = materialMapping.Value; if (material == null) { continue; } if (material.IsInvisible) { continue; } List <string> bitmapNames = material.GetAllBitmapNames(); if (bitmapNames == null || bitmapNames.Count == 0) { continue; } string pngName = bitmapNames[0]; pngName = pngName.Substring(0, pngName.Length - 4); string textureName = ImageWriter.GetExportedImageName(pngName + ".png", material.ShaderType); if (Name.ToLower().Contains("baf") && material.Name.ToLower().Contains("bam")) { } var headerName = material.ExportName; if (textureName == "d_brnch0201.png") { } materialsExport.AppendLine(GetMaterialExportChunk(headerName, textureName)); if (i == 0) { if (material.Name.ToLower().Contains("chain")) { } baseSkinMaterials.Add(material.SlotKey); } else { currentUsedSlots.Add(material.SlotKey); } } // If this is a skin variant, we need to ensure that all base slots are included. // If the skin variant does not have a matching entry for the base slot, we add the base slot material. if (i != 0) { foreach (var baseMaterials in baseSkinMaterials) { if (currentUsedSlots.Contains(baseMaterials)) { continue; } int slotIndex = IndexSlotMapping[baseMaterials]; Material materialToAdd = Skins[0][slotIndex]; string pngName = materialToAdd.GetAllBitmapNames()[0]; pngName = pngName.Substring(0, pngName.Length - 4); string textureName = ImageWriter.GetExportedImageName(pngName + ".png", materialToAdd.ShaderType); var headerName = materialToAdd.ExportName; if (headerName == "") { } materialsExport.AppendLine(GetMaterialExportChunk(headerName, textureName)); } } foreach (var general in GeneralTextures) { Material materialToAdd = general; string pngName = materialToAdd.GetAllBitmapNames()[0]; pngName = pngName.Substring(0, pngName.Length - 4); string textureName = ImageWriter.GetExportedImageName(pngName + ".png", materialToAdd.ShaderType); var headerName = materialToAdd.ExportName; materialsExport.AppendLine(GetMaterialExportChunk(headerName, textureName)); } materialExports.Add(materialsExport.ToString()); } return(materialExports); }
/// <summary> /// Exports the model to an .obj file /// </summary> /// <param name="baseVertex">The number of vertices we have processed so far in the model</param> /// <param name="objExportType"></param> /// <param name="vertexCount">The number of vertices in this model</param> /// <param name="activeTexture"></param> /// <param name="lastUsedTexture"></param> /// <returns></returns> public List <string> GetMeshExport(int baseVertex, string activeTexture, ObjExportType objExportType, out int vertexCount, out string lastUsedTexture) { var frames = new List <string>(); var usedVertices = new List <int>(); var unusedVertices = new List <int>(); int currentPolygon = 0; var faceOutput = new StringBuilder(); // First assemble the faces that are needed foreach (RenderGroup group in RenderGroups) { int textureIndex = group.TextureIndex; int polygonCount = group.PolygonCount; List <int> activeArray = null; bool bitmapValid = false; // Figure out the correct export array if (objExportType == ObjExportType.Textured) { activeArray = MaterialList.Materials[textureIndex].IsInvisible ? unusedVertices : usedVertices; bitmapValid = true; } else if (objExportType == ObjExportType.Collision) { activeArray = usedVertices; bitmapValid = false; } else if (objExportType == ObjExportType.Water) { if (MaterialList.Materials[textureIndex].IsInvisible) { activeArray = unusedVertices; bitmapValid = false; } else { string bitmapName = MaterialList.Materials[textureIndex].TextureInfoReference.TextureInfo .BitmapNames[0].Filename; activeArray = SpecialTextures.IsWater(bitmapName) ? usedVertices : unusedVertices; bitmapValid = SpecialTextures.IsWater(bitmapName); } } else if (objExportType == ObjExportType.Lava) { if (MaterialList.Materials[textureIndex].IsInvisible) { activeArray = unusedVertices; bitmapValid = false; } else { string bitmapName = MaterialList.Materials[textureIndex].TextureInfoReference.TextureInfo .BitmapNames[0].Filename; activeArray = SpecialTextures.IsLava(bitmapName) ? usedVertices : unusedVertices; bitmapValid = SpecialTextures.IsLava(bitmapName); } } else if (objExportType == ObjExportType.NoSpecialZones) { if (MaterialList.Materials[textureIndex].IsInvisible) { activeArray = unusedVertices; bitmapValid = false; } else { string bitmapName = MaterialList.Materials[textureIndex].TextureInfoReference.TextureInfo .BitmapNames[0].Filename; if (SpecialTextures.IsWater(bitmapName) || SpecialTextures.IsLava(bitmapName)) { activeArray = unusedVertices; bitmapValid = false; } else { activeArray = usedVertices; bitmapValid = true; } } } if (!MaterialList.Materials[textureIndex].IsInvisible && objExportType != ObjExportType.Collision) { string bitmapName = MaterialList.Materials[textureIndex].TextureInfoReference.TextureInfo .BitmapNames[0].Filename; string pngName = bitmapName.Substring(0, bitmapName.Length - 4); string materialName = ImageWriter.GetExportedImageName(pngName, MaterialList.Materials[textureIndex].ShaderType); if (materialName != activeTexture && bitmapValid) { faceOutput.AppendLine(LanternStrings.ObjUseMtlPrefix + materialName); activeTexture = materialName; } } for (int j = 0; j < polygonCount; ++j) { int vertex1 = Polygons[currentPolygon].Vertex1 + baseVertex + 1; int vertex2 = Polygons[currentPolygon].Vertex2 + baseVertex + 1; int vertex3 = Polygons[currentPolygon].Vertex3 + baseVertex + 1; if (!Polygons[currentPolygon].Solid && objExportType == ObjExportType.Collision) { continue; } if (activeArray == usedVertices) { int index1 = vertex1 - unusedVertices.Count; int index2 = vertex2 - unusedVertices.Count; int index3 = vertex3 - unusedVertices.Count; // Vertex + UV if (objExportType != ObjExportType.Collision) { faceOutput.AppendLine("f " + index3 + "/" + index3 + " " + index2 + "/" + index2 + " " + +index1 + "/" + index1); } else { faceOutput.AppendLine("f " + index3 + " " + index2 + " " + +index1); } } AddIfNotContained(activeArray, Polygons[currentPolygon].Vertex1); AddIfNotContained(activeArray, Polygons[currentPolygon].Vertex2); AddIfNotContained(activeArray, Polygons[currentPolygon].Vertex3); currentPolygon++; } } var vertexOutput = new StringBuilder(); usedVertices.Sort(); int frameCount = 1; if (AnimatedVertices != null) { frameCount += AnimatedVertices.Frames.Count; } for (int i = 0; i < frameCount; ++i) { // Add each vertex foreach (var usedVertex in usedVertices) { vec3 vertex; if (i == 0) { vertex = Vertices[usedVertex]; } else { if (AnimatedVertices == null) { continue; } vertex = AnimatedVertices.Frames[i - 1][usedVertex]; } vertexOutput.AppendLine("v " + (vertex.x + Center.x) + " " + (vertex.y + Center.y) + " " + (vertex.z + Center.z)); if (objExportType == ObjExportType.Collision) { continue; } vec2 vertexUvs = TextureUvCoordinates[usedVertex]; vertexOutput.AppendLine("vt " + vertexUvs.x + " " + vertexUvs.y); } frames.Add(vertexOutput.ToString() + faceOutput); vertexOutput.Clear(); } vertexCount = usedVertices.Count; lastUsedTexture = activeTexture; // Ensure that output use the decimal point rather than the comma (as in Germany) for (var i = 0; i < frames.Count; i++) { frames[i] = frames[i].Replace(',', '.'); } return(frames); }