public static void GetTarget(out bool success, out ExportFormatDescription format, out string textureExtension) { ChooseTarget c = new ChooseTarget(); DialogResult d = c.ShowDialog(); if (c.OKed || d == DialogResult.OK) { format = c.comboBoxFormat.SelectedIndex == 0 ? null : c.formats[c.comboBoxFormat.SelectedIndex - 1]; textureExtension = "." + c.textBoxExtension.Text; success = true; } else { success = false; format = null; textureExtension = null; } }
public static void ExportAssimp(string fileName, RWSection[] bspFile, bool flipUVs, ExportFormatDescription format, string textureExtension, Matrix worldTransform) { Scene scene = new Scene(); foreach (RWSection rw in bspFile) { if (rw is World_000B w) { WorldToScene(scene, w, textureExtension); } else if (rw is Clump_0010 c) { ClumpToScene(scene, c, textureExtension, worldTransform); } } scene.RootNode = new Node() { Name = "root" }; Node latest = scene.RootNode; for (int i = 0; i < scene.MeshCount; i++) { latest.Children.Add(Newtonsoft.Json.JsonConvert.DeserializeObject <Node>( "{\"Name\":\"" + scene.Meshes[i].Name + "\", \"MeshIndices\": [" + i.ToString() + "]}")); //latest = latest.Children[0]; } new AssimpContext().ExportFile(scene, fileName, format.FormatId, PostProcessSteps.Debone | PostProcessSteps.FindInstances | //PostProcessSteps.GenerateNormals | PostProcessSteps.FindInvalidData | PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.OptimizeGraph | PostProcessSteps.OptimizeMeshes | PostProcessSteps.PreTransformVertices | PostProcessSteps.RemoveRedundantMaterials | PostProcessSteps.Triangulate | PostProcessSteps.ValidateDataStructure | (flipUVs ? PostProcessSteps.FlipUVs : 0)); }
public static void ExportAssimp(string fileName, RenderWareModelFile bspFile, bool flipUVs, ExportFormatDescription format, string textureExtension) { Scene scene = new Scene(); foreach (RWSection rw in bspFile.GetAsRWSectionArray()) { if (rw is World_000B w) { for (int i = 0; i < w.materialList.materialList.Length; i++) { var mat = w.materialList.materialList[i]; scene.Materials.Add(new Material() { ColorDiffuse = new Color4D( mat.materialStruct.color.R / 255f, mat.materialStruct.color.G / 255f, mat.materialStruct.color.B / 255f, mat.materialStruct.color.A / 255f), TextureDiffuse = new TextureSlot() { FilePath = mat.texture.diffuseTextureName.stringString + textureExtension, TextureType = TextureType.Diffuse }, Name = "mat_" + mat.texture.diffuseTextureName.stringString }); scene.Meshes.Add(new Mesh(PrimitiveType.Triangle) { MaterialIndex = i, Name = "mesh_" + mat.texture.diffuseTextureName.stringString }); } if (w.firstWorldChunk.sectionIdentifier == Section.AtomicSector) { GetAtomicTriangleList(scene, (AtomicSector_0009)w.firstWorldChunk, flipUVs); } else if (w.firstWorldChunk.sectionIdentifier == Section.PlaneSector) { GetPlaneTriangleList(scene, (PlaneSector_000A)w.firstWorldChunk, flipUVs); } } } scene.RootNode = new Node() { Name = "root" }; Node latest = scene.RootNode; for (int i = 0; i < scene.MeshCount; i++) { latest.Children.Add(Newtonsoft.Json.JsonConvert.DeserializeObject <Node>( "{\"Name\":\"" + scene.Meshes[i].Name + "\", \"MeshIndices\": [" + i.ToString() + "]}")); //latest = latest.Children[0]; } new AssimpContext().ExportFile(scene, fileName, format.FormatId); }
private static bool PackModels(ProcessorInfo info, BinPacking <int> texturePacker) { using (AssimpContext importer = new AssimpContext()) { ExportFormatDescription[] exportFormatDescriptions = importer.GetSupportedExportFormats(); ExportFormatDescription exportFormat = exportFormatDescriptions.FirstOrDefault(x => x.FormatId == info.modelExportFormatId); if (exportFormat == null) { Log.Line(LogType.Error, "Model export format {0} is not supported!", info.modelExportFormatId); Log.Line(LogType.Info, "Supported formats are:"); foreach (ExportFormatDescription e in exportFormatDescriptions) { Log.Line(LogType.Info, "{0} ({1})", e.FormatId, e.Description); } return(false); } Log.Line(LogType.Info, "Shifting uv(w) positions of {0} models to their new location", info.models.Length); if (info.mergeModels) { Log.Line(LogType.Info, "Going to merge models"); } Scene mergedScene = new Scene { RootNode = new Assimp.Node(), Materials = { new Material() } }; for (int i = 0; i < info.models.Length; i++) { string modelPath = info.models[i]; Scene model = importer.ImportFile(modelPath); if (!model.HasMeshes) { Log.Line(LogType.Warning, "There are no meshes in model file '{0}'", modelPath); continue; } Log.Line(LogType.Info, "Processing {0} meshes from model file '{1}'", model.MeshCount, modelPath); foreach (Mesh mesh in model.Meshes) { Log.Line(LogType.Debug, "Found {0} uv(w) channels in mesh '{1}'", mesh.TextureCoordinateChannelCount, mesh.Name); // TODO: Add support for offsetting uvs per mesh instead of per model file // Thus having 1 texture per mesh instead of having 1 texture per model file Block <int> block = texturePacker.blocks.First(x => x.data == i); Log.Line(LogType.Debug, "Using texture at index {0} for this model", Array.IndexOf(texturePacker.blocks, block)); float scaleX = (block.w - info.padding * 2) / (float)texturePacker.root.w; float scaleY = (block.h - info.padding * 2) / (float)texturePacker.root.h; float offsetX = (block.fit.x + info.padding) / (float)texturePacker.root.w; float offsetY = (block.fit.y + info.padding) / (float)texturePacker.root.h; offsetY = 1 - offsetY - scaleY; // This is because the uv 0,0 is in the bottom left Log.Line(LogType.Debug, "Calculated scaling multipliers: x: {0}; y: {1}", scaleX, scaleY); Log.Line(LogType.Debug, "Calculated offsets: x: {0}; y: {1}", offsetX, offsetY); for (int uvwChannel = 0; uvwChannel < mesh.TextureCoordinateChannelCount; uvwChannel++) { List <Vector3D> uvw = mesh.TextureCoordinateChannels[uvwChannel]; if (uvw == null || uvw.Count == 0) { continue; } for (int n = 0; n < uvw.Count; n++) { uvw[n] = new Vector3D( uvw[n].X * scaleX + offsetX, uvw[n].Y * scaleY + offsetY, uvw[n].Z); } mesh.TextureCoordinateChannels[uvwChannel] = uvw; } if (info.mergeModels) { mergedScene.RootNode.MeshIndices.Add(mergedScene.MeshCount); mesh.MaterialIndex = 0; mergedScene.Meshes.Add(mesh); mergedScene.Animations.AddRange(model.Animations); Log.Line(LogType.Info, "Merged mesh {0} into output model", mesh.Name); } } if (!info.mergeModels) { string savePath; if (!string.IsNullOrEmpty(info.outputFilesPrefix.Trim())) { savePath = Path.Combine(info.outputDir, string.Format("{0}-model-{1}.{2}", info.outputFilesPrefix, Path.GetFileNameWithoutExtension(modelPath), exportFormat.FileExtension)); } else { savePath = Path.Combine(info.outputDir, string.Format("model-{0}.{1}", Path.GetFileNameWithoutExtension(modelPath), exportFormat.FileExtension)); } Log.Line(LogType.Info, "Saving edited model to '{0}'", savePath); importer.ExportFile(model, savePath, exportFormat.FormatId); } } if (info.mergeModels) { string savePath; if (!string.IsNullOrEmpty(info.outputFilesPrefix.Trim())) { savePath = Path.Combine(info.outputDir, string.Format("{0}-models-merged.{1}", info.outputFilesPrefix, exportFormat.FileExtension)); } else { savePath = Path.Combine(info.outputDir, string.Format("models-merged.{0}", exportFormat.FileExtension)); } Log.Line(LogType.Info, "Saving merged model to '{0}'", savePath); importer.ExportFile(mergedScene, savePath, exportFormat.FormatId); } } return(true); }
public static void ExportAssimp(string fileName, RenderWareModelFile bspFile, bool flipUVs, ExportFormatDescription format, string textureExtension) { Scene scene = new Scene(); foreach (RWSection rw in bspFile.GetAsRWSectionArray()) { if (rw is World_000B w) { for (int i = 0; i < w.materialList.materialList.Length; i++) { var mat = w.materialList.materialList[i]; string objName = Path.GetFileNameWithoutExtension(fileName) + "_" + (mat.materialStruct.isTextured != 0 ? mat.texture.diffuseTextureName.stringString : "default"); scene.Materials.Add(new Material() { ColorDiffuse = new Color4D( mat.materialStruct.color.R / 255f, mat.materialStruct.color.G / 255f, mat.materialStruct.color.B / 255f, mat.materialStruct.color.A / 255f), TextureDiffuse = mat.materialStruct.isTextured != 0 ? new TextureSlot() { FilePath = mat.texture.diffuseTextureName.stringString + textureExtension, TextureType = TextureType.Diffuse } : new TextureSlot(), Name = "mat_" + objName }); scene.Meshes.Add(new Mesh(PrimitiveType.Triangle) { MaterialIndex = i, Name = "mesh_" + objName }); } if (w.firstWorldChunk.sectionIdentifier == Section.AtomicSector) { GetAtomicTriangleList(scene, (AtomicSector_0009)w.firstWorldChunk); } else if (w.firstWorldChunk.sectionIdentifier == Section.PlaneSector) { GetPlaneTriangleList(scene, (PlaneSector_000A)w.firstWorldChunk); } } } scene.RootNode = new Node() { Name = "root" }; Node latest = scene.RootNode; for (int i = 0; i < scene.MeshCount; i++) { latest.Children.Add(Newtonsoft.Json.JsonConvert.DeserializeObject <Node>( "{\"Name\":\"" + scene.Meshes[i].Name + "\", \"MeshIndices\": [" + i.ToString() + "]}")); //latest = latest.Children[0]; } new AssimpContext().ExportFile(scene, fileName, format.FormatId, //PostProcessSteps.GenerateNormals | PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.RemoveRedundantMaterials | PostProcessSteps.ValidateDataStructure | PostProcessSteps.Debone | PostProcessSteps.FindInstances | PostProcessSteps.FindInvalidData | PostProcessSteps.OptimizeGraph | PostProcessSteps.OptimizeMeshes | PostProcessSteps.Triangulate | PostProcessSteps.PreTransformVertices | (flipUVs ? PostProcessSteps.FlipUVs : 0)); }
/// <summary> /// Gets all supported export formats. /// </summary> /// <returns>Array of supported export formats.</returns> public static ExportFormatDescription[] GetExportFormatDescriptions() { int count = aiGetExportFormatCount().ToInt32(); if(count == 0) return new ExportFormatDescription[0]; ExportFormatDescription[] descriptions = new ExportFormatDescription[count]; for(int i = 0; i < count; i++) { IntPtr formatDescPtr = aiGetExportFormatDescription(new IntPtr(i)); if(formatDescPtr != null) { AiExportFormatDesc desc = MemoryHelper.MarshalStructure<AiExportFormatDesc>(formatDescPtr); descriptions[i] = new ExportFormatDescription(ref desc); } } return descriptions; }