public unsafe static void importBR2(string sourceFilename, string outputFilename, GrannyContext grannyContext) { IGrannyFile file = CivNexusSixApplicationForm.form.OpenFileAsTempFileCopy(CivNexusSixApplicationForm.form.modelTemplateFilename, "tempimport"); GrannyFileWrapper fileWrapper = new GrannyFileWrapper(file); fileWrapper.setNumMeshes(0); fileWrapper.setNumVertexDatas(0); fileWrapper.setNumSkeletons(0); fileWrapper.setNumTriTopologies(0); GrannyModelInfo modelInfo = loadModelInfo(sourceFilename); doBoneBindings(modelInfo); List <IGrannyFile> meshFileList = new List <IGrannyFile>(); foreach (GrannyMeshInfo meshInfo in modelInfo.meshBindings) { meshFileList.Add(writeMesh(meshInfo)); } IGrannyModel model = file.Models[0]; GrannyModelWrapper modelWrapper = new GrannyModelWrapper(model); modelWrapper.setNumMeshBindings(0); model.MeshBindings.Clear(); foreach (IGrannyFile meshFile in meshFileList) { doAppendMeshBinding(file, meshFile, 0); } fileWrapper.setNumMeshes(0); file.Meshes.Clear(); foreach (IGrannyMesh mesh in file.Models[0].MeshBindings) { file.AddMeshReference(mesh); } GrannySkeletonWrapper skeletonWrapper = new GrannySkeletonWrapper(file.Models[0].Skeleton); skeletonWrapper.writeSkeletonInfo(modelInfo.skeleton); string worldBoneName = modelInfo.skeleton.bones[0].name; modelWrapper.setName(worldBoneName); skeletonWrapper.setName(worldBoneName); fileWrapper.setFromArtToolInfo("Blender", 2, 0); float[] matrix = { 1f, 0f, 0f, 0f, 0f, 1f, 0f, -1f, 0f }; fileWrapper.setMatrix(matrix); CivNexusSixApplicationForm.SetExporterInfo(fileWrapper); fileWrapper.setFromFileName(sourceFilename); fileWrapper.addSkeletonPointer((int)skeletonWrapper.m_pkSkeleton); CivNexusSixApplicationForm.form.SaveAsAction(file, outputFilename, false); }
public static void exportAllModelsToNB2(IGrannyFile grannyFile) { for (int i = 0; i < grannyFile.Models.Count; i++) { exportNB2Model(grannyFile, i); } }
public unsafe static IGrannyFile writeMesh(GrannyMeshInfo meshInfo) { bool useLeaderTemplate = NexusBuddyApplicationForm.form.useLeaderTemplate(); bool useSceneTemplate = NexusBuddyApplicationForm.form.useSceneTemplate(); string templateFilename; if (useLeaderTemplate) { templateFilename = NexusBuddyApplicationForm.form.leaderTemplateFilename; } else if (useSceneTemplate) { templateFilename = NexusBuddyApplicationForm.form.sceneTemplateFilename; } else { templateFilename = NexusBuddyApplicationForm.form.modelTemplateFilename; } IGrannyFile appendFile = NexusBuddyApplicationForm.form.openFileAsTempFileCopy(templateFilename, "tempappend"); appendFile.Meshes.RemoveRange(1, appendFile.Meshes.Count - 1); IGrannyMesh mesh = appendFile.Models[0].MeshBindings[0]; GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(mesh); meshWrapper.writeMeshInfo(meshInfo, useLeaderTemplate, useSceneTemplate); return(appendFile); }
public static void exportAllModelsToCN6(IGrannyFile grannyFile) { for (int i = 0; i < grannyFile.Models.Count; i++) { cn6Export(grannyFile, i); } }
public unsafe static void doAppendMeshBinding(IGrannyFile inputFile, IGrannyFile appendFile, Int32 currentModelIndex) { // Get wrappers IGrannyModel inputModel = inputFile.Models[currentModelIndex]; GrannyModelWrapper inputModelWrapper = new GrannyModelWrapper(inputModel); IGrannyModel appendModel = appendFile.Models[0]; GrannyModelWrapper appendModelWrapper = new GrannyModelWrapper(appendModel); // Update model inputModel.MeshBindings.Add(appendFile.Meshes[0]); int meshCountInput = inputModelWrapper.getNumMeshBindings(); int newMeshBindingsCount = meshCountInput + 1; inputModelWrapper.setNumMeshBindings(newMeshBindingsCount); // Update model mesh bindings int oldMeshBindingsPtr = *(int *)inputModelWrapper.getMeshBindingsPtr(); *(int *)inputModelWrapper.getMeshBindingsPtr() = (int)Marshal.AllocHGlobal(newMeshBindingsCount * 8); int newMeshBindingsPtr = *(int *)inputModelWrapper.getMeshBindingsPtr(); int modelMeshBindingsPtrAppend = *(int *)appendModelWrapper.getMeshBindingsPtr(); if (meshCountInput > 0) { MemoryUtil.MemCpy((void *)newMeshBindingsPtr, (void *)oldMeshBindingsPtr, (uint)(meshCountInput * 8)); } MemoryUtil.MemCpy((void *)(newMeshBindingsPtr + meshCountInput * 8), (void *)modelMeshBindingsPtrAppend, 8); }
public static void overwriteMeshes(IGrannyFile file, string sourceFilename, GrannyContext grannyContext, int currentModelIndex, int vertexFormat) { string filename = file.Filename; GrannyModelInfo modelInfo = loadModelInfos(sourceFilename, vertexFormat)[0]; doBoneBindings(modelInfo); GrannyFileWrapper fileWrapper = new GrannyFileWrapper(file); List <IGrannyFile> meshFileList = new List <IGrannyFile>(); foreach (GrannyMeshInfo meshInfo in modelInfo.meshBindings) { meshFileList.Add(writeMesh(meshInfo, getTemplateFilename(vertexFormat))); } IGrannyModel model = file.Models[currentModelIndex]; GrannyModelWrapper modelWrapper = new GrannyModelWrapper(model); modelWrapper.setNumMeshBindings(0); model.MeshBindings.Clear(); foreach (IGrannyFile meshFile in meshFileList) { doAppendMeshBinding(file, meshFile, currentModelIndex); } fileWrapper.setNumMeshes(0); fileWrapper.setNumTriTopologies(0); fileWrapper.setNumVertexDatas(0); file.Meshes.Clear(); int meshesCount = 0; foreach (IGrannyModel loopModel in file.Models) { foreach (IGrannyMesh mesh in loopModel.MeshBindings) { file.AddMeshReference(mesh); meshesCount++; } } fileWrapper.setFromArtToolInfo("Blender", 2, 0); //fileWrapper.setUnitsPerMeter(10.7f); CivNexusSixApplicationForm.SetExporterInfo(fileWrapper); fileWrapper.setFromFileName(sourceFilename); fileWrapper.setNumMeshes(meshesCount); CivNexusSixApplicationForm.form.SaveAsAction(file, filename, false); List <GrannyModelInfo> modelInfos = new List <GrannyModelInfo>(); modelInfos.Add(modelInfo); createAndBindMaterials(filename, file, modelInfos); }
public GrannyFileWrapper(IGrannyFile inputFile) { wrappedFile = inputFile; Type myType = inputFile.GetType(); FieldInfo fm_info = myType.GetField("m_info", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); Pointer pm_info = (Pointer)fm_info.GetValue(inputFile); m_info = Pointer.Unbox(pm_info); }
public static List <string> exportAllModelsToCN6(IGrannyFile grannyFile, bool isBatch) { List <string> fileTextureMaps = new List <string>(); for (int i = 0; i < grannyFile.Models.Count; i++) { List <string> textureMaps = cn6Export(grannyFile, i, isBatch); fileTextureMaps.AddRange(textureMaps); } return(fileTextureMaps); }
public unsafe static void overwriteMeshes(IGrannyFile file, string sourceFilename, GrannyContext grannyContext, Int32 currentModelIndex) { string filename = file.Filename; GrannyModelInfo modelInfo = loadModelInfo(sourceFilename); doBoneBindings(modelInfo); GrannyFileWrapper fileWrapper = new GrannyFileWrapper(file); List <IGrannyFile> meshFileList = new List <IGrannyFile>(); foreach (GrannyMeshInfo meshInfo in modelInfo.meshBindings) { meshFileList.Add(writeMesh(meshInfo)); } IGrannyModel model = file.Models[currentModelIndex]; GrannyModelWrapper modelWrapper = new GrannyModelWrapper(model); modelWrapper.setNumMeshBindings(0); model.MeshBindings.Clear(); foreach (IGrannyFile meshFile in meshFileList) { doAppendMeshBinding(grannyContext, file, meshFile, currentModelIndex); } fileWrapper.setNumMeshes(0); fileWrapper.setNumTriTopologies(0); fileWrapper.setNumVertexDatas(0); file.Meshes.Clear(); int meshesCount = 0; foreach (IGrannyModel loopModel in file.Models) { foreach (IGrannyMesh mesh in loopModel.MeshBindings) { file.AddMeshReference(mesh); meshesCount++; } } fileWrapper.setFromArtToolInfo("Blender", 2, 0); fileWrapper.setUnitsPerMeter(10.7f); NexusBuddyApplicationForm.setExporterInfo(fileWrapper); fileWrapper.setFromFileName(sourceFilename); fileWrapper.setNumMeshes(meshesCount); NexusBuddyApplicationForm.form.saveAsAction(file, filename, false); }
public static List <string> cn6Export(IGrannyFile grannyFile, int currentModelIndex, bool isBatch) { IGrannyModel model = grannyFile.Models[currentModelIndex]; WriteModelToCN6Response response = WriteModelToCN6(grannyFile, isBatch, model, null); foreach (string decalMeshName in response.decalMeshNames) { WriteModelToCN6(grannyFile, isBatch, model, decalMeshName); } return(response.textureMaps); }
public static IGrannyFile writeMesh(GrannyMeshInfo meshInfo, string templateFilename) { IGrannyFile appendFile = CivNexusSixApplicationForm.form.OpenFileAsTempFileCopy(templateFilename, "tempappend"); appendFile.Meshes.RemoveRange(1, appendFile.Meshes.Count - 1); IGrannyMesh mesh = appendFile.Models[0].MeshBindings[0]; GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(mesh); meshWrapper.writeMeshInfo(meshInfo, false, false); return(appendFile); }
public static void WriteGeometrySet(IGrannyFile file, string assetClassName) { string filenameNoExt = Path.GetFileNameWithoutExtension(file.Filename); string directory = Path.GetDirectoryName(file.Filename); string fileExtension = "_GeometrySet.xml"; string geoFilename = filenameNoExt + fileExtension; StreamWriter outputWriter = new StreamWriter(new FileStream(directory + "\\" + geoFilename, FileMode.Create)); List <IGrannyFile> files = new List <IGrannyFile>() { file }; WriteGeometrySetMetadataToStream(files, outputWriter, null, assetClassName); outputWriter.Close(); }
public static void batchExport(GrannyContext grannyContext, string unitListFile) { StreamReader streamReader = new StreamReader(unitListFile); string directory = Path.GetDirectoryName(unitListFile); string regexString = "(.+);(.*);(.*);(.*)"; string outFilename = unitListFile.Replace(".dat", "_new.dat"); StreamWriter outputWriter = new StreamWriter(new FileStream(outFilename, FileMode.Create)); while (!streamReader.EndOfStream) { string currentLine = streamReader.ReadLine(); Regex regex = new Regex(regexString); MatchCollection mc = regex.Matches(currentLine); foreach (Match m in mc) { string gr2Filename = m.Groups[1].Value.Trim().ToLower(); IGrannyFile grannyFile = grannyContext.LoadGrannyFile(directory + "\\" + gr2Filename); NexusBuddyApplicationForm.loadedFile = grannyFile; NexusBuddyApplicationForm.form.refreshAppData(); List <string> fileTextureMaps = exportAllModelsToCN6(grannyFile, true); string animationFilenames = m.Groups[2].Value.Trim(); string textureFilenames = m.Groups[3].Value.Trim(); string prettyName = m.Groups[4].Value.Trim(); var fileTextureSet = new HashSet <string>(fileTextureMaps); if (String.IsNullOrEmpty(textureFilenames)) { textureFilenames = string.Join(",", fileTextureSet); } string newline = gr2Filename + ";" + animationFilenames + ";" + textureFilenames + ";" + prettyName; outputWriter.WriteLine(newline); } } streamReader.Close(); outputWriter.Close(); File.Delete(unitListFile); File.Move(outFilename, unitListFile); }
//// todo - update to create new memory areas //public unsafe static void doAppendMeshBinding(GrannyContext grannyContext, IGrannyFile inputFile, IGrannyFile appendFile) //{ // // UNPACK CURRENT MODEL // IGrannyModel inputModel = inputFile.Models[0]; // GrannyModelWrapper inputModelWrapper = new GrannyModelWrapper(inputModel); // void* m_pkModel_input = inputModelWrapper.m_pkModel; // // UNPACK APPEND MODEL // IGrannyModel appendModel = appendFile.Models[0]; // GrannyModelWrapper appendModelWrapper = new GrannyModelWrapper(appendModel); // void* m_pkModel_app = appendModelWrapper.m_pkModel; // // UNPACK NEW MODEL // IGrannyFile newModelFile = inputFile; // IGrannyModel newModel = newModelFile.Models[0]; // GrannyModelWrapper newModelWrapper = new GrannyModelWrapper(newModel); // void* m_pkModel_new = newModelWrapper.m_pkModel; // // UPDATE NEW MODEL // int meshCountInput = *(int*)((IntPtr)m_pkModel_input + 76); // newModel.MeshBindings.Add(appendFile.Meshes[0]); // // update Mesh Count // *(int*)((IntPtr)m_pkModel_new + 76) = meshCountInput + 1; // //update model mesh bindings // int size = meshCountInput; // void* modelMeshBindingsPtrInput = (void*)*(int*)((IntPtr)m_pkModel_input + 80); // MemoryUtil.MemCpy((void*)*(int*)((IntPtr)m_pkModel_new + 80), (void*)modelMeshBindingsPtrInput, (uint)(size * 4)); // int writeOffset = meshCountInput; // void* modelMeshBindingsPtrAppend = (void*)*(int*)((IntPtr)m_pkModel_app + 80); // MemoryUtil.MemCpy((void*)(*(int*)((IntPtr)m_pkModel_new + 80) + writeOffset * 4), (void*)modelMeshBindingsPtrAppend, (uint)(1 * 4)); // GrannyFileWrapper newModelFileWrapper = new GrannyFileWrapper(newModelFile); // void* m_info = newModelFileWrapper.m_info; // void** grannyMeshPtr = (void**)*(int*)((IntPtr)m_info + 56); // // Add all meshes from input file // *(int*)((IntPtr)m_info + 52) = 0; // Reset Mesh Count to 0 // for (int index = 0; index < inputFile.Meshes.Count; index++) // { // IGrannyMesh mesh = inputFile.Meshes[index]; // GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(mesh); // void* m_pkMesh = meshWrapper.m_pkMesh; // MemoryUtil.MemCpy((void*)*(int*)((IntPtr)m_info + 56), (void*)grannyMeshPtr, (uint)(*(int*)((IntPtr)m_info + 52) * 4)); // *(int*)(*(int*)((IntPtr)m_info + 56) + *(int*)((IntPtr)m_info + 52) * 4) = (int)m_pkMesh; // *(int*)((IntPtr)m_info + 52) = *(int*)((IntPtr)m_info + 52) + 1; // } // // Add mesh from append file // IGrannyMesh appendMesh = appendFile.Meshes[0]; // GrannyMeshWrapper appendMeshWrapper = new GrannyMeshWrapper(appendMesh); // void* m_pkAppendMesh = appendMeshWrapper.m_pkMesh; // MemoryUtil.MemCpy((void*)*(int*)((IntPtr)m_info + 56), (void*)grannyMeshPtr, (uint)(*(int*)((IntPtr)m_info + 52) * 4)); // *(int*)(*(int*)((IntPtr)m_info + 56) + *(int*)((IntPtr)m_info + 52) * 4) = (int)m_pkAppendMesh; // *(int*)((IntPtr)m_info + 52) = *(int*)((IntPtr)m_info + 52) + 1; //} public static IGrannyFile cleardownTemplate(GrannyContext grannyContext) { //string filename = sourceTemplatePath + "model_template.gr2"; IGrannyFile file = NexusBuddyApplicationForm.form.openFileAsTempFileCopy(NexusBuddyApplicationForm.form.modelTemplateFilename, "tempimport"); GrannyFileWrapper fileWrapper = new GrannyFileWrapper(file); //GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(file.Meshes[0]); //meshWrapper.setName("BLANK_MESH"); //meshWrapper.setNumVertices(0); //meshWrapper.setNumBoneBindings(0); //meshWrapper.setNumIndices(0); //meshWrapper.setNumIndices16(0); //meshWrapper.setGroup0TriCount(0); ////memProbe(meshWrapper.getBoneBindingsPtr()); //GrannyModelWrapper modelWrapper = new GrannyModelWrapper(file.Models[0]); //modelWrapper.setNumMeshBindings(1); //modelWrapper.setName("BLANK_MODEL"); //GrannySkeletonWrapper skeletonWrapper = new GrannySkeletonWrapper(modelWrapper.wrappedModel.Skeleton); //skeletonWrapper.setNumBones(0); //skeletonWrapper.setName("BLANK_SKELETON"); fileWrapper.setNumMeshes(0); //fileWrapper.setNumModels(0); fileWrapper.setNumVertexDatas(0); fileWrapper.setNumSkeletons(0); fileWrapper.setNumTriTopologies(0); fileWrapper.setNumMaterials(0); file.Meshes.Clear(); //fileWrapper.setFromFileName("My lovely lovely filename"); //fileWrapper.setFromArtToolName("Blender 2.49"); //fileWrapper.setExporterName("Nexus Buddy 2.0 beta 6"); return(file); }
public static void WriteAssetFile(IGrannyFile file, Dictionary <string, string> civ6ShortNameToLongNameLookup, string className, string dsgName, string prettyAssetFilename, List <Dictionary <string, string> > materialBindingToMtlDicts) { string filenameNoExt = Path.GetFileNameWithoutExtension(file.Filename); if (prettyAssetFilename != null && prettyAssetFilename.Length > 0) { filenameNoExt = prettyAssetFilename; } string directory = Path.GetDirectoryName(file.Filename); TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; string assetFilename = textInfo.ToTitleCase(filenameNoExt) + ".ast"; string instanceName = "Asset"; StreamWriter outputWriter = new StreamWriter(new FileStream(directory + "\\" + assetFilename, FileMode.Create)); WriteAssetHeader(instanceName, outputWriter); WriteBehaviorMetadataToStream(civ6ShortNameToLongNameLookup, dsgName, outputWriter); WriteGeometrySetMetadataToStream(new List <IGrannyFile> { file }, outputWriter, materialBindingToMtlDicts, className); WriteBlankCookParams(outputWriter); WriteVersion(outputWriter); outputWriter.WriteLine("<m_ParticleEffects/>"); outputWriter.WriteLine("<m_Geometries/>"); outputWriter.WriteLine("<m_Animations/>"); outputWriter.WriteLine("<m_Materials/>"); WriteClassName(className, outputWriter); outputWriter.WriteLine("<m_DataFiles/>"); WriteFooter(className, textInfo.ToTitleCase(filenameNoExt), instanceName, outputWriter); outputWriter.Close(); }
public static void batchExport(GrannyContext grannyContext, string unitListFile) { StreamReader streamReader = new StreamReader(unitListFile); string directory = Path.GetDirectoryName(unitListFile); string regexString = "(.*);(.*);(.*);(.*)"; while (!streamReader.EndOfStream) { string currentLine = streamReader.ReadLine(); Regex regex = new Regex(regexString); MatchCollection mc = regex.Matches(currentLine); foreach (Match m in mc) { string gr2Filename = m.Groups[1].Value.Trim().ToLower(); IGrannyFile grannyFile = grannyContext.LoadGrannyFile(directory + "\\" + gr2Filename); NexusBuddyApplicationForm.loadedFile = grannyFile; NexusBuddyApplicationForm.form.refreshAppData(); exportAllModelsToNB2(grannyFile); } } }
private static unsafe void createAndBindMaterials(string outputFilename, IGrannyFile file, List <GrannyModelInfo> modelInfos) { GrannyFileWrapper fileWrapper2 = new GrannyFileWrapper(CivNexusSixApplicationForm.form.SaveAsAction(file, outputFilename, false)); CivNexusSixApplicationForm.form.RefreshAppData(); for (int modelIndex = 0; modelIndex < modelInfos.Count; modelIndex++) { var modelInfo = modelInfos[modelIndex]; for (int meshIndex = 0; meshIndex < modelInfo.meshBindings.Count; meshIndex++) { GrannyMeshInfo meshInfo = modelInfo.meshBindings[meshIndex]; fileWrapper2.createMaterials(modelIndex, meshIndex, meshInfo); } } GrannyFileWrapper fileWrapper3 = new GrannyFileWrapper(CivNexusSixApplicationForm.form.SaveAsAction(fileWrapper2.wrappedFile, outputFilename, false)); fileWrapper3.pruneMaterials(); CivNexusSixApplicationForm.form.SaveAsAction(fileWrapper3.wrappedFile, outputFilename, false); CivNexusSixApplicationForm.form.RefreshAppData(); }
private static WriteModelToCN6Response WriteModelToCN6(IGrannyFile grannyFile, bool isBatch, IGrannyModel model, string filterMeshName) { List <string> textureMaps = new List <string>(); string fileExtension = ".cn6"; string outputFilename = ""; string numberFormat = "f8"; List <string> decalMeshNames = new List <string>(); IGrannySkeleton skeleton = model.Skeleton; string decalMeshName = ""; if (filterMeshName != null) { decalMeshName = "_DCL_" + GetSafeFilename(filterMeshName); } if (grannyFile.Models.Count > 1) { string modelFilename = "__" + model.Name + decalMeshName + fileExtension; outputFilename = grannyFile.Filename.Replace(".gr2", modelFilename); outputFilename = outputFilename.Replace(".GR2", modelFilename); } else { outputFilename = grannyFile.Filename.Replace(".gr2", fileExtension); outputFilename = outputFilename.Replace(".GR2", fileExtension); } if (isBatch) { outputFilename = outputFilename.Replace(fileExtension, "_batch" + fileExtension); } string directory = Path.GetDirectoryName(outputFilename); string filename = Path.GetFileName(outputFilename); outputFilename = directory + "\\" + GetSafeFilename(filename); StreamWriter outputWriter = new StreamWriter(new FileStream(outputFilename, FileMode.Create)); // Lookup so we can identify the meshes belonging the current model in the list of file meshes Dictionary <int, int> meshBindingToMesh = new Dictionary <int, int>(); HashSet <string> distinctMeshNames = new HashSet <string>(); for (int i = 0; i < model.MeshBindings.Count; i++) { for (int j = 0; j < grannyFile.Meshes.Count; j++) { GrannyMeshWrapper modelMesh = new GrannyMeshWrapper(model.MeshBindings[i]); IGrannyMesh fileMesh = grannyFile.Meshes[j]; if (modelMesh.meshEqual(fileMesh)) { meshBindingToMesh.Add(i, j); } } distinctMeshNames.Add(model.MeshBindings[i].Name); } // Used to give meshes distinct names where we have multiple meshes with the same name in our source gr2 Dictionary <string, int> meshNameCount = new Dictionary <string, int>(); foreach (string meshName in distinctMeshNames) { meshNameCount.Add(meshName, 0); } List <GrannyMeshInfo> grannyMeshInfos = new List <GrannyMeshInfo>(); for (int i = 0; i < model.MeshBindings.Count; i++) { GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(model.MeshBindings[i]); grannyMeshInfos.Add(meshWrapper.getMeshInfo()); } BiLookup <int, string> boneLookup = new BiLookup <int, string>(); for (int i = 0; i < skeleton.Bones.Count; i++) { boneLookup.Add(i, skeleton.Bones[i].Name); } Dictionary <string, double[]> boneNameToPositionMap = new Dictionary <string, double[]>(); foreach (IGrannyBone bone in skeleton.Bones) { if (!boneNameToPositionMap.ContainsKey(bone.Name)) { double[] bonePosition = NB2Exporter.getBoneWorldPosition(bone); boneNameToPositionMap.Add(bone.Name, bonePosition); } } string headerLine = "// CivNexus6 CN6 - Exported from Nexus Buddy " + NexusBuddyApplicationForm.getVersionString(); outputWriter.WriteLine(headerLine); outputWriter.WriteLine("skeleton"); // Write Bones for (int boneIndex = 0; boneIndex < skeleton.Bones.Count; boneIndex++) { IGrannyBone bone = skeleton.Bones[boneIndex]; string boneName = bone.Name; IGrannyTransform transform = bone.LocalTransform; float[] orientation = transform.Orientation; float[] position = transform.Position; float[] invWorldTransform = bone.InverseWorldTransform; StringBuilder boneStringBuilder = new StringBuilder(boneIndex + " \"" + boneName + "\" " + bone.ParentIndex + " " + position[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + position[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + position[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[3].ToString(numberFormat, CultureInfo.InvariantCulture)); foreach (float j in invWorldTransform) { boneStringBuilder.Append(" " + j.ToString(numberFormat, CultureInfo.InvariantCulture)); } outputWriter.WriteLine(boneStringBuilder); } List <IndieMaterial> modelMaterials = new List <IndieMaterial>(); foreach (IGrannyMesh mesh in model.MeshBindings) { IGrannyMaterial material = mesh.MaterialBindings[0]; foreach (ListViewItem materialListItem in NexusBuddyApplicationForm.form.materialList.Items) { IndieMaterial shader = (IndieMaterial)materialListItem.Tag; GrannyMaterialWrapper matWrap1 = new GrannyMaterialWrapper(shader.GetMaterial()); GrannyMaterialWrapper matWrap2 = new GrannyMaterialWrapper(material); if (matWrap1.getName().Equals(matWrap2.getName()) && !modelMaterials.Contains(shader)) { modelMaterials.Add(shader); } } } int meshCount = 0; for (int mi = 0; mi < grannyMeshInfos.Count; mi++) { IGrannyMesh mesh = model.MeshBindings[mi]; string meshName = model.MeshBindings[mi].Name; GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(mesh); GrannyMeshInfo meshInfo = meshWrapper.getMeshInfo(); bool isFlatMesh = true; foreach (GrannyVertexInfo vertexInfo in meshInfo.vertices) { float zPos = vertexInfo.position[2]; bool isZero = NumberUtils.almostEquals(zPos, 0.0f, 4); if (!isZero) { isFlatMesh = false; break; } } if (filterMeshName == null) { if (isFlatMesh) { decalMeshNames.Add(meshName); } else { meshCount++; } } else { meshCount = 1; } } if (meshCount == 0) { outputWriter.Close(); File.Delete(outputFilename); return(new WriteModelToCN6Response(decalMeshNames, textureMaps)); } // Write Meshes outputWriter.WriteLine("meshes:" + meshCount); for (int mi = 0; mi < grannyMeshInfos.Count; mi++) { GrannyMeshInfo grannyMeshInfo = grannyMeshInfos[mi]; string meshName = model.MeshBindings[mi].Name; if ((filterMeshName == null && !decalMeshNames.Contains(meshName)) || meshName.Equals(filterMeshName)) { meshNameCount[meshName]++; if (meshNameCount[meshName] > 1) { meshName += meshNameCount[meshName]; } outputWriter.WriteLine("mesh:\"" + meshName + "\""); // Write Materials outputWriter.WriteLine("materials"); foreach (IGrannyMaterial material in model.MeshBindings[mi].MaterialBindings) { IndieMaterial shader = NexusBuddyApplicationForm.GetIndieMaterialFromMaterial(material); string baseMap; if (shader.GetType() == typeof(IndieLeaderGlassShader)) { baseMap = "Leader_cornea"; } else if (shader.GetType() == typeof(IndieBuildingShader)) { baseMap = shader.Diffuse; } else if (shader.GetType().Name.StartsWith("IndieLeaderFur")) { baseMap = shader.Fur_BaseMap; } else if (shader.GetType().Name.StartsWith("IndieLeader")) { baseMap = shader.DiffuseMap; } else if (shader.GetType() == typeof(IndieLandmarkStencilShader)) { baseMap = shader.BaseTextureMap; } else { baseMap = shader.BaseTextureMap; } if (!String.IsNullOrEmpty(baseMap)) { outputWriter.WriteLine("\"" + baseMap + "\""); textureMaps.Add(baseMap); } else { outputWriter.WriteLine("\"" + material.Name + "\""); } } // Write Vertices outputWriter.WriteLine("vertices"); for (int vi = 0; vi < grannyMeshInfo.vertices.Count; vi++) { GrannyVertexInfo vertex = grannyMeshInfo.vertices[vi]; string[] boneNames = new string[8]; float[] boneWeights = new float[8]; int[] boneIds = new int[8]; for (int z = 0; z < 8; z++) { if (z > 3) { //boneNames[z] = grannyMeshInfo.boneBindings[vertex.boneIndices[z]]; boneWeights[z] = 0f; boneIds[z] = 0; } else { boneNames[z] = grannyMeshInfo.boneBindings[vertex.boneIndices[z]]; boneWeights[z] = (float)vertex.boneWeights[z] / 255; boneIds[z] = NB2Exporter.getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneNames[z], boneWeights[z], vertex.position); } } float[] tangents = new float[3]; if (vertex.tangent == null) { tangents[0] = vertex.normal[0]; tangents[1] = vertex.normal[1]; tangents[2] = vertex.normal[2]; } else { tangents[0] = vertex.tangent[0]; tangents[1] = vertex.tangent[1]; tangents[2] = vertex.tangent[2]; } float[] binormals = new float[3]; if (vertex.binormal == null) { binormals[0] = vertex.normal[0]; binormals[1] = vertex.normal[1]; binormals[2] = vertex.normal[2]; } else { binormals[0] = vertex.binormal[0]; binormals[1] = vertex.binormal[1]; binormals[2] = vertex.binormal[2]; } outputWriter.WriteLine(vertex.position[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.position[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.position[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + tangents[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + tangents[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + tangents[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + binormals[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + binormals[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + binormals[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.uv[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.uv[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + 0.00000000f.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + 0.00000000f.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + 0.00000000f.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + 0.00000000f.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneIds[0] + " " + boneIds[1] + " " + boneIds[2] + " " + boneIds[3] + " 0 0 0 0 " + vertex.boneWeights[0] + " " + vertex.boneWeights[1] + " " + vertex.boneWeights[2] + " " + vertex.boneWeights[3] + " 0 0 0 0 " ); } // Write Triangles outputWriter.WriteLine("triangles"); for (int ti = 0; ti < grannyMeshInfo.triangles.Count; ti++) { int[] triangle = grannyMeshInfo.triangles[ti]; outputWriter.WriteLine(triangle[0] + " " + triangle[1] + " " + triangle[2] + " 0"); } } } outputWriter.WriteLine("end"); outputWriter.Close(); WriteModelToCN6Response response = new WriteModelToCN6Response(decalMeshNames, textureMaps); return(response); }
public static void WriteGeoAnimFile(IGrannyFile file, int currentModelIndex, string className) { string fgxFilename = Path.GetFileName(file.Filename); string filenameNoExt = Path.GetFileNameWithoutExtension(file.Filename); string directory = Path.GetDirectoryName(file.Filename); string numberFormat = "f6"; bool isAnimation = false; string instanceName = "Geometry"; string fileExtension = ".geo"; if (file.Animations.Count > 0 && file.Models.Count == 0) { isAnimation = true; instanceName = "Animation"; fileExtension = ".anm"; } string geoFilename = filenameNoExt + fileExtension; string wigFilename = ""; if (className.Equals("Leader") && instanceName.Equals("Geometry")) { wigFilename = filenameNoExt + ".wig"; string wigFullPath = directory + "\\" + wigFilename; File.Copy(CivNexusSixApplicationForm.form.dummyWigFilename, wigFullPath, true); } StreamWriter outputWriter = new StreamWriter(new FileStream(directory + "\\" + geoFilename, FileMode.Create)); WriteAssetHeader(instanceName, outputWriter); WriteBlankCookParams(outputWriter); WriteVersion(outputWriter); if (isAnimation) { outputWriter.WriteLine("<m_fDuration>" + file.Animations[0].Duration.ToString(numberFormat, CultureInfo.InvariantCulture) + "</m_fDuration>"); } else { outputWriter.WriteLine("<m_Meshes>"); foreach (IGrannyMesh mesh in file.Meshes) { GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(mesh); outputWriter.WriteLine("<Element>"); outputWriter.WriteLine("<m_Name text=\"" + mesh.Name + "\"/>"); outputWriter.WriteLine("<m_Groups>"); int totalTriangles = 0; foreach (IGrannyTriMaterialGroup triMaterialGroup in mesh.TriangleMaterialGroups) { outputWriter.WriteLine("<Element>"); outputWriter.WriteLine("<m_Name text=\"" + mesh.MaterialBindings[triMaterialGroup.MaterialIndex].Name + "\"/>"); outputWriter.WriteLine("<m_nFirstPrim>" + triMaterialGroup.TriFirst + "</m_nFirstPrim>"); outputWriter.WriteLine("<m_nPrims>" + triMaterialGroup.TriCount + "</m_nPrims>"); outputWriter.WriteLine("</Element>"); totalTriangles += triMaterialGroup.TriCount; } outputWriter.WriteLine("</m_Groups>"); outputWriter.WriteLine("<m_nBoundBoneCount>" + mesh.BoneBindings.Count + "</m_nBoundBoneCount>"); outputWriter.WriteLine("<m_nPrimitiveCount>" + totalTriangles + "</m_nPrimitiveCount>"); outputWriter.WriteLine("<m_nVertexCount>" + mesh.VertexCount + "</m_nVertexCount>"); outputWriter.WriteLine("</Element>"); } outputWriter.WriteLine("</m_Meshes>"); outputWriter.WriteLine("<m_Bones>"); foreach (IGrannyBone bone in file.Models[currentModelIndex].Skeleton.Bones) { outputWriter.WriteLine("<Element text=\"" + bone.Name + "\"/>"); } outputWriter.WriteLine("</m_Bones>"); outputWriter.WriteLine("<m_ModelName text=\"" + file.Models[currentModelIndex].Name + "\"/>"); } WriteSourcePathAndTimes(outputWriter); WriteClassName(className, outputWriter); outputWriter.WriteLine("<m_DataFiles>"); outputWriter.WriteLine("<Element>"); outputWriter.WriteLine("<m_ID text=\"GR2\"/>"); outputWriter.WriteLine("<m_RelativePath text=\"" + fgxFilename + "\"/>"); outputWriter.WriteLine("</Element>"); if (className.Equals("Leader") && instanceName.Equals("Geometry")) { outputWriter.WriteLine("<Element>"); outputWriter.WriteLine("<m_ID text=\"WIG\"/>"); outputWriter.WriteLine("<m_RelativePath text=\"" + wigFilename + "\"/>"); outputWriter.WriteLine("</Element>"); } outputWriter.WriteLine("</m_DataFiles>"); WriteFooter(className, filenameNoExt, instanceName, outputWriter); outputWriter.Close(); }
private static void WriteGeometrySetMetadataToStream(List <IGrannyFile> files, StreamWriter outputWriter, List <Dictionary <string, string> > materialBindingToMtlDicts, string assetClassName) { List <string> stateNames = null; if (assetClassName.Equals("TileBase")) { stateNames = new List <string> { "Unworked", "Worked", "Pillaged", "Unbuilt", "Construction" }; } else { stateNames = new List <string> { "Default" }; } outputWriter.WriteLine("<m_GeometrySet>"); outputWriter.WriteLine("<m_ModelInstances>"); for (int i = 0; i < files.Count; i++) { IGrannyFile file = files[i]; foreach (IGrannyModel model in file.Models) { string filenameNoExt = Path.GetFileNameWithoutExtension(file.Filename); string upperModelName = model.Name.ToUpper(); bool isTreeCut = upperModelName.Contains("TREE") && upperModelName.Contains("CUT"); //First pass - check if any valid mesh bindings bool modelHasValidMeshBinding = false; foreach (IGrannyMesh mesh in model.MeshBindings) { string upperMeshName = mesh.Name.ToUpper(); bool isTreeCutMesh = upperMeshName.Contains("TREE") && upperMeshName.Contains("CUT"); bool isShadowMesh = upperMeshName.Contains("SHADOW"); if (!upperMeshName.Contains("DMG") && !isTreeCutMesh && !isShadowMesh) { modelHasValidMeshBinding = true; break; } } if (!isTreeCut && modelHasValidMeshBinding) { outputWriter.WriteLine("<Element>"); outputWriter.WriteLine("<m_Name text=\"" + model.Name + "\"/>"); outputWriter.WriteLine("<m_GeoName text=\"" + filenameNoExt + "\"/>"); outputWriter.WriteLine("<m_GroupStates>"); foreach (IGrannyMesh mesh in model.MeshBindings) { string upperMeshName = mesh.Name.ToUpper(); bool isTreeCutMesh = upperMeshName.Contains("TREE") && upperMeshName.Contains("CUT"); bool isShadowMesh = upperMeshName.Contains("SHADOW"); if (!upperMeshName.Contains("DMG") && !isTreeCutMesh && !isShadowMesh) { foreach (IGrannyTriMaterialGroup triMaterialGroup in mesh.TriangleMaterialGroups) { string materialBindingName = mesh.MaterialBindings[triMaterialGroup.MaterialIndex].Name; foreach (string stateName in stateNames) { if (!materialBindingName.Contains("ColorMap") && !materialBindingName.Contains("Generic_Grey_8") && !materialBindingName.Contains("04 - Default")) { string mtlFilename = mesh.MaterialBindings[triMaterialGroup.MaterialIndex].Name; if (mtlFilename.Contains(".")) { string[] parts = mtlFilename.Split('.'); mtlFilename = parts[0]; } outputWriter.WriteLine("<Element>"); outputWriter.WriteLine("<m_Values>"); outputWriter.WriteLine("<m_Values>"); outputWriter.WriteLine("<Element class=\"AssetObjects:ObjectValue\">"); string mtlFilenameToSet = mtlFilename; if (materialBindingToMtlDicts != null) { Dictionary <string, string> materialBindingToMtlDict = materialBindingToMtlDicts[i]; if (materialBindingToMtlDict != null) { if (materialBindingToMtlDict.ContainsKey(materialBindingName)) { mtlFilenameToSet = materialBindingToMtlDict[materialBindingName]; } } } outputWriter.WriteLine("<m_ObjectName text=\"" + mtlFilenameToSet + "\"/>"); outputWriter.WriteLine("<m_eObjectType>MATERIAL</m_eObjectType>"); outputWriter.WriteLine("<m_ParamName text=\"Material\"/>"); outputWriter.WriteLine("</Element>"); if (assetClassName.Equals("TileBase")) { outputWriter.WriteLine("<Element class=\"AssetObjects..BoolValue\">"); outputWriter.WriteLine("<m_bValue>true</m_bValue>"); outputWriter.WriteLine("<m_ParamName text=\"Visible\"/>"); outputWriter.WriteLine("</Element>"); } outputWriter.WriteLine("</m_Values>"); outputWriter.WriteLine("</m_Values>"); outputWriter.WriteLine("<m_GroupName text=\"" + materialBindingName + "\"/>"); outputWriter.WriteLine("<m_MeshName text=\"" + mesh.Name + "\"/>"); outputWriter.WriteLine("<m_StateName text=\"" + stateName + "\"/>"); outputWriter.WriteLine("</Element>"); } } } } } outputWriter.WriteLine("</m_GroupStates>"); outputWriter.WriteLine("</Element>"); } } } outputWriter.WriteLine("</m_ModelInstances>"); outputWriter.WriteLine("</m_GeometrySet>"); }
public unsafe static void importCN6(string sourceFilename, string outputFilename, GrannyContext grannyContext, int vertexFormat) { string templateFilename = getTemplateFilename(vertexFormat); IGrannyFile file = CivNexusSixApplicationForm.form.OpenFileAsTempFileCopy(templateFilename, "tempimport"); GrannyFileWrapper fileWrapper = new GrannyFileWrapper(file); fileWrapper.setNumMeshes(0); fileWrapper.setNumVertexDatas(0); fileWrapper.setNumSkeletons(0); fileWrapper.setNumTriTopologies(0); List <GrannyModelInfo> modelInfos = loadModelInfos(sourceFilename, vertexFormat); fileWrapper.setNumMeshes(0); fileWrapper.setNumModels(0); foreach (GrannyModelInfo modelInfo in modelInfos) { doBoneBindings(modelInfo); List <IGrannyFile> meshFileList = new List <IGrannyFile>(); foreach (GrannyMeshInfo meshInfo in modelInfo.meshBindings) { meshFileList.Add(writeMesh(meshInfo, templateFilename)); } IGrannyFile modelFile = CivNexusSixApplicationForm.form.OpenFileAsTempFileCopy(templateFilename, "tempimport"); IGrannyModel model = modelFile.Models[0]; GrannyModelWrapper modelWrapper = new GrannyModelWrapper(model); modelWrapper.setNumMeshBindings(0); model.MeshBindings.Clear(); GrannySkeletonWrapper skeletonWrapper = new GrannySkeletonWrapper(modelFile.Models[0].Skeleton); skeletonWrapper.writeSkeletonInfo(modelInfo.skeleton); string worldBoneName = modelInfo.skeleton.bones[0].name; string modelName = worldBoneName; foreach (GrannyBoneInfo bone in modelInfo.skeleton.bones) { if (!bone.name.Contains("ADJUSTMENT_BONE")) { modelName = bone.name; break; } } modelWrapper.setName(modelName); skeletonWrapper.setName(modelName); foreach (IGrannyFile meshFile in meshFileList) { doAppendMeshBinding(modelFile, meshFile, 0); } foreach (IGrannyMesh mesh in model.MeshBindings) { file.AddMeshReference(mesh); } file.AddModelReference(model); CivNexusSixApplicationForm.form.RefreshAppData(); } fileWrapper.setNumModels(modelInfos.Count()); fileWrapper.setFromArtToolInfo("Blender", 2, 0); float[] matrix = { 1f, 0f, 0f, 0f, 0f, 1f, 0f, -1f, 0f }; fileWrapper.setMatrix(matrix); CivNexusSixApplicationForm.SetExporterInfo(fileWrapper); fileWrapper.setFromFileName(sourceFilename); createAndBindMaterials(outputFilename, file, modelInfos); }
public static void exportNB2(IGrannyFile grannyFile, Int32 currentModelIndex) { exportNB2Model(grannyFile, currentModelIndex); }
public static void exportNB2Model(IGrannyFile grannyFile, int modelId) { string fileExtension = ".nb2"; string outputFilename = ""; string numberFormat = "f6"; if (grannyFile.Models.Count > 1) { string modelFilename = "__" + grannyFile.Models[modelId].Name + fileExtension; outputFilename = grannyFile.Filename.Replace(".gr2", modelFilename); outputFilename = outputFilename.Replace(".GR2", modelFilename); } else { outputFilename = grannyFile.Filename.Replace(".gr2", fileExtension); outputFilename = outputFilename.Replace(".GR2", fileExtension); } StreamWriter outputWriter = new StreamWriter(new FileStream(outputFilename.ToLower(), FileMode.Create)); IGrannyModel model = grannyFile.Models[modelId]; IGrannySkeleton skeleton = model.Skeleton; // Lookup so we can identify the meshes belonging the current model in the list of file meshes Dictionary <int, int> meshBindingToMesh = new Dictionary <int, int>(); HashSet <string> distinctMeshNames = new HashSet <string>(); for (int i = 0; i < model.MeshBindings.Count; i++) { for (int j = 0; j < grannyFile.Meshes.Count; j++) { GrannyMeshWrapper modelMesh = new GrannyMeshWrapper(model.MeshBindings[i]); IGrannyMesh fileMesh = grannyFile.Meshes[j]; if (modelMesh.meshEqual(fileMesh)) { meshBindingToMesh.Add(i, j); } } distinctMeshNames.Add(model.MeshBindings[i].Name); } // Used to give meshes distinct names where we have multiple meshes with the same name in our source gr2 Dictionary <string, int> meshNameCount = new Dictionary <string, int>(); foreach (string meshName in distinctMeshNames) { meshNameCount.Add(meshName, 0); } List <GrannyMeshInfo> grannyMeshInfos = new List <GrannyMeshInfo>(); for (int i = 0; i < model.MeshBindings.Count; i++) { GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(model.MeshBindings[i]); grannyMeshInfos.Add(meshWrapper.getMeshInfo()); } BiLookup <int, string> boneLookup = new BiLookup <int, string>(); for (int i = 0; i < skeleton.Bones.Count; i++) { boneLookup.Add(i, skeleton.Bones[i].Name); } Dictionary <string, double[]> boneNameToPositionMap = new Dictionary <string, double[]>(); double[] bonePosition; foreach (IGrannyBone bone in skeleton.Bones) { try { bonePosition = getBoneWorldPosition(bone); boneNameToPositionMap.Add(bone.Name, bonePosition); } catch (ArgumentException) { } } outputWriter.WriteLine("// Nexus Buddy NB2 - Exported from Nexus Buddy 2"); outputWriter.WriteLine("Frames: 30"); outputWriter.WriteLine("Frame: 1"); List <IndieMaterial> modelMaterials = new List <IndieMaterial>(); foreach (IGrannyMesh mesh in model.MeshBindings) { IGrannyMaterial material = mesh.MaterialBindings[0]; foreach (ListViewItem materialListItem in NexusBuddyApplicationForm.form.materialList.Items) { IndieMaterial shader = (IndieMaterial)materialListItem.Tag; GrannyMaterialWrapper matWrap1 = new GrannyMaterialWrapper(shader.GetMaterial()); GrannyMaterialWrapper matWrap2 = new GrannyMaterialWrapper(material); if (matWrap1.getName().Equals(matWrap2.getName()) && !modelMaterials.Contains(shader)) { modelMaterials.Add(shader); } } } // Write Meshes outputWriter.WriteLine("Meshes: " + model.MeshBindings.Count); for (int mi = 0; mi < grannyMeshInfos.Count; mi++) { GrannyMeshInfo grannyMeshInfo = grannyMeshInfos[mi]; string meshName = model.MeshBindings[mi].Name; meshNameCount[meshName]++; if (meshNameCount[meshName] > 1) { meshName += meshNameCount[meshName]; } var materialBindingName = model.MeshBindings[mi].MaterialBindings[0].Name; var materialIndex = 0; foreach (IndieMaterial material in modelMaterials) { if (materialBindingName.Equals(material.GetMaterial().Name)) { break; } materialIndex++; } outputWriter.WriteLine("\"" + meshName + "\" 0 " + materialIndex); // Write Vertices outputWriter.WriteLine(grannyMeshInfo.vertices.Count); for (int vi = 0; vi < grannyMeshInfo.vertices.Count; vi++) { GrannyVertexInfo vertex = grannyMeshInfo.vertices[vi]; string boneName0 = grannyMeshInfo.boneBindings[vertex.boneIndices[0]]; float boneWeight0 = (float)vertex.boneWeights[0] / 255; int boneId0 = getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName0, boneWeight0, vertex.position); string boneName1 = grannyMeshInfo.boneBindings[vertex.boneIndices[1]]; float boneWeight1 = (float)vertex.boneWeights[1] / 255; int boneId1 = getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName1, boneWeight1, vertex.position); string boneName2 = grannyMeshInfo.boneBindings[vertex.boneIndices[2]]; float boneWeight2 = (float)vertex.boneWeights[2] / 255; int boneId2 = getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName2, boneWeight2, vertex.position); string boneName3 = grannyMeshInfo.boneBindings[vertex.boneIndices[3]]; float boneWeight3 = (float)vertex.boneWeights[3] / 255; int boneId3 = getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName3, boneWeight3, vertex.position); outputWriter.WriteLine("0 " + vertex.position[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.position[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.position[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.uv[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.uv[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId0 + " " + boneWeight0.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId1 + " " + boneWeight1.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId2 + " " + boneWeight2.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId3 + " " + boneWeight3.ToString(numberFormat, CultureInfo.InvariantCulture) ); } // Write Normals outputWriter.WriteLine(grannyMeshInfo.vertices.Count); for (int ni = 0; ni < grannyMeshInfo.vertices.Count; ni++) { GrannyVertexInfo vertex = grannyMeshInfo.vertices[ni]; outputWriter.WriteLine(vertex.normal[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[2].ToString(numberFormat, CultureInfo.InvariantCulture)); } // Write Triangles outputWriter.WriteLine(grannyMeshInfo.triangles.Count); for (int ti = 0; ti < grannyMeshInfo.triangles.Count; ti++) { int[] triangle = grannyMeshInfo.triangles[ti]; outputWriter.WriteLine("0 " + triangle[0] + " " + triangle[1] + " " + triangle[2] + " " + triangle[0] + " " + triangle[1] + " " + triangle[2] + " 1"); } } // Write Materials outputWriter.WriteLine("Materials: " + modelMaterials.Count); for (int i = 0; i < modelMaterials.Count; i++) { outputWriter.WriteLine("\"" + modelMaterials[i].GetMaterial().Name + "\""); outputWriter.WriteLine("0.200000 0.200000 0.200000 1.000000"); outputWriter.WriteLine("0.800000 0.800000 0.800000 1.000000"); outputWriter.WriteLine("0.000000 0.000000 0.000000 1.000000"); outputWriter.WriteLine("0.000000 0.000000 0.000000 1.000000"); outputWriter.WriteLine("0.000000"); outputWriter.WriteLine("1.000000"); string map1 = "ColorMap_" + i; string map2 = "AlphaMap_" + i; string baseMap; string srefmap; IndieMaterial shader = modelMaterials[i]; if (shader.GetType() == typeof(IndieBuildingShader)) { baseMap = shader.Diffuse; srefmap = shader.BuildingSREF; } else if (shader.GetType() == typeof(IndieLandmarkStencilShader)) { baseMap = shader.BaseTextureMap; srefmap = shader.SpecTextureMap; } else { baseMap = shader.BaseTextureMap; srefmap = shader.SREFMap; } if (!String.IsNullOrEmpty(baseMap)) { map1 = baseMap; } if (!String.IsNullOrEmpty(srefmap)) { map2 = srefmap; } outputWriter.WriteLine("\"" + map1 + "\""); outputWriter.WriteLine("\"" + map2 + "\""); } // Write Bones outputWriter.WriteLine("Bones: " + skeleton.Bones.Count); for (int bi = 0; bi < skeleton.Bones.Count; bi++) { IGrannyBone bone = skeleton.Bones[bi]; string boneName = bone.Name; outputWriter.WriteLine("\"" + boneName + "\""); if (bone.ParentIndex == -1) { outputWriter.WriteLine("\"\""); } else { string parentBoneName = skeleton.Bones[bone.ParentIndex].Name; outputWriter.WriteLine("\"" + parentBoneName + "\""); } IGrannyTransform transform = bone.LocalTransform; float[] orientation = transform.Orientation; float[] position = transform.Position; //Matrix3D boneWorldMatrix = getBoneWorldMatrix(bone); //ETransformFlags transformFlags = transform.Flags; //bool hasPosition = transformFlags.HasFlag(ETransformFlags.GrannyHasPosition); //bool hasOrientation = transformFlags.HasFlag(ETransformFlags.GrannyHasOrientation); // bone: flags, posx, posy, posz, quatx, quaty, quatz, quatw outputWriter.WriteLine("0 " + position[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + position[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + position[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[3].ToString(numberFormat, CultureInfo.InvariantCulture)); // number of position keys outputWriter.WriteLine("0"); // number of rotation keys outputWriter.WriteLine("0"); } outputWriter.Close(); }
public static void br2Export(IGrannyFile grannyFile, int currentModelIndex) { string fileExtension = ".br2"; string outputFilename = ""; string numberFormat = "f8"; if (grannyFile.Models.Count > 1) { outputFilename = grannyFile.Filename.Replace(".fgx", "_model" + currentModelIndex + fileExtension); outputFilename = outputFilename.Replace(".FGX", "_model" + currentModelIndex + fileExtension); } else { outputFilename = grannyFile.Filename.Replace(".fgx", fileExtension); outputFilename = outputFilename.Replace(".FGX", fileExtension); } StreamWriter outputWriter = new StreamWriter(new FileStream(outputFilename, FileMode.Create)); IGrannyModel model = grannyFile.Models[currentModelIndex]; IGrannySkeleton skeleton = model.Skeleton; // Lookup so we can identify the meshes belonging the current model in the list of file meshes Dictionary <int, int> meshBindingToMesh = new Dictionary <int, int>(); HashSet <string> distinctMeshNames = new HashSet <string>(); for (int i = 0; i < model.MeshBindings.Count; i++) { for (int j = 0; j < grannyFile.Meshes.Count; j++) { GrannyMeshWrapper modelMesh = new GrannyMeshWrapper(model.MeshBindings[i]); IGrannyMesh fileMesh = grannyFile.Meshes[j]; if (modelMesh.meshEqual(fileMesh)) { meshBindingToMesh.Add(i, j); } } distinctMeshNames.Add(model.MeshBindings[i].Name); } // Used to give meshes distinct names where we have multiple meshes with the same name in our source gr2 Dictionary <string, int> meshNameCount = new Dictionary <string, int>(); foreach (string meshName in distinctMeshNames) { meshNameCount.Add(meshName, 0); } List <GrannyMeshInfo> grannyMeshInfos = new List <GrannyMeshInfo>(); for (int i = 0; i < model.MeshBindings.Count; i++) { GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(model.MeshBindings[i]); grannyMeshInfos.Add(meshWrapper.getMeshInfo()); } BiLookup <int, string> boneLookup = new BiLookup <int, string>(); for (int i = 0; i < skeleton.Bones.Count; i++) { boneLookup.Add(i, skeleton.Bones[i].Name); } Dictionary <string, double[]> boneNameToPositionMap = new Dictionary <string, double[]>(); foreach (IGrannyBone bone in skeleton.Bones) { double[] bonePosition = NB2NA2FileOps.getBoneWorldPosition(bone); boneNameToPositionMap.Add(bone.Name, bonePosition); //MemoryUtil.memLogLine("boneName: " + bone.Name + " bone position:" + bonePosition[0] + " " + bonePosition[1] + " " + bonePosition[2]); } outputWriter.WriteLine("// Nexus Buddy BR2 - Exported from Nexus Buddy 2"); outputWriter.WriteLine("skeleton"); // Write Bones //outputWriter.WriteLine("Bones: " + skeleton.Bones.Count); for (int boneIndex = 0; boneIndex < skeleton.Bones.Count; boneIndex++) { IGrannyBone bone = skeleton.Bones[boneIndex]; string boneName = bone.Name; IGrannyTransform transform = bone.LocalTransform; float[] orientation = transform.Orientation; float[] position = transform.Position; float[] invWorldTransform = bone.InverseWorldTransform; StringBuilder boneStringBuilder = new StringBuilder(boneIndex + " \"" + boneName + "\" " + bone.ParentIndex + " " + position[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + position[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + position[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[3].ToString(numberFormat, CultureInfo.InvariantCulture)); foreach (float j in invWorldTransform) { boneStringBuilder.Append(" " + j.ToString(numberFormat, CultureInfo.InvariantCulture)); } outputWriter.WriteLine(boneStringBuilder); } // Write Meshes outputWriter.WriteLine("meshes: " + model.MeshBindings.Count); for (int mi = 0; mi < grannyMeshInfos.Count; mi++) { GrannyMeshInfo grannyMeshInfo = grannyMeshInfos[mi]; string meshName = model.MeshBindings[mi].Name; meshNameCount[meshName]++; if (meshNameCount[meshName] > 1) { meshName += meshNameCount[meshName]; } //StringBuilder boneStringBuilder = new StringBuilder(); outputWriter.WriteLine("mesh:\"" + meshName + "\""); // Write Vertices outputWriter.WriteLine("vertices"); for (int vi = 0; vi < grannyMeshInfo.vertices.Count; vi++) { GrannyVertexInfo vertex = grannyMeshInfo.vertices[vi]; string boneName0 = grannyMeshInfo.boneBindings[vertex.boneIndices[0]]; float boneWeight0 = (float)vertex.boneWeights[0] / 255; int boneId0 = NB2NA2FileOps.getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName0, boneWeight0, vertex.position); string boneName1 = grannyMeshInfo.boneBindings[vertex.boneIndices[1]]; float boneWeight1 = (float)vertex.boneWeights[1] / 255; int boneId1 = NB2NA2FileOps.getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName1, boneWeight1, vertex.position); string boneName2 = grannyMeshInfo.boneBindings[vertex.boneIndices[2]]; float boneWeight2 = (float)vertex.boneWeights[2] / 255; int boneId2 = NB2NA2FileOps.getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName2, boneWeight2, vertex.position); string boneName3 = grannyMeshInfo.boneBindings[vertex.boneIndices[3]]; float boneWeight3 = (float)vertex.boneWeights[3] / 255; int boneId3 = NB2NA2FileOps.getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName3, boneWeight3, vertex.position); float[] tangents = new float[3]; if (vertex.tangent == null) { tangents[0] = vertex.normal[0]; tangents[1] = vertex.normal[1]; tangents[2] = vertex.normal[2]; } else { tangents[0] = vertex.tangent[0]; tangents[1] = vertex.tangent[1]; tangents[2] = vertex.tangent[2]; } float[] binormals = new float[3]; if (vertex.binormal == null) { binormals[0] = vertex.normal[0]; binormals[1] = vertex.normal[1]; binormals[2] = vertex.normal[2]; } else { binormals[0] = vertex.binormal[0]; binormals[1] = vertex.binormal[1]; binormals[2] = vertex.binormal[2]; } outputWriter.WriteLine(vertex.position[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.position[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.position[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.uv[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.uv[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId0 + " " + boneId1 + " " + boneId2 + " " + boneId3 + " " + vertex.boneWeights[0] + " " + vertex.boneWeights[1] + " " + vertex.boneWeights[2] + " " + vertex.boneWeights[3] + " " + tangents[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + tangents[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + tangents[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + binormals[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + binormals[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + binormals[2].ToString(numberFormat, CultureInfo.InvariantCulture) ); } // Write Triangles outputWriter.WriteLine("triangles"); for (int ti = 0; ti < grannyMeshInfo.triangles.Count; ti++) { int[] triangle = grannyMeshInfo.triangles[ti]; outputWriter.WriteLine(triangle[0] + " " + triangle[1] + " " + triangle[2]); } } outputWriter.WriteLine("end"); outputWriter.Close(); }
public static void exportNB2Model(IGrannyFile grannyFile, int modelId) { string fileExtension = ".nb2"; string outputFilename = ""; string numberFormat = "f6"; if (grannyFile.Models.Count > 1) { outputFilename = grannyFile.Filename.Replace(".fgx", "_model" + modelId + fileExtension); outputFilename = outputFilename.Replace(".FGX", "_model" + modelId + fileExtension); } else { outputFilename = grannyFile.Filename.Replace(".fgx", fileExtension); outputFilename = outputFilename.Replace(".FGX", fileExtension); } StreamWriter outputWriter = new StreamWriter(new FileStream(outputFilename, FileMode.Create)); IGrannyModel model = grannyFile.Models[modelId]; IGrannySkeleton skeleton = model.Skeleton; GrannySkeletonWrapper skeletonWrapper = new GrannySkeletonWrapper(skeleton); skeletonWrapper.readSkeletonInfo(); // Lookup so we can identify the meshes belonging the current model in the list of file meshes Dictionary <int, int> meshBindingToMesh = new Dictionary <int, int>(); HashSet <string> distinctMeshNames = new HashSet <string>(); for (int i = 0; i < model.MeshBindings.Count; i++) { for (int j = 0; j < grannyFile.Meshes.Count; j++) { GrannyMeshWrapper modelMesh = new GrannyMeshWrapper(model.MeshBindings[i]); IGrannyMesh fileMesh = grannyFile.Meshes[j]; if (modelMesh.meshEqual(fileMesh)) { meshBindingToMesh.Add(i, j); } } distinctMeshNames.Add(model.MeshBindings[i].Name); } // Used to give meshes distinct names where we have multiple meshes with the same name in our source gr2 Dictionary <string, int> meshNameCount = new Dictionary <string, int>(); foreach (string meshName in distinctMeshNames) { meshNameCount.Add(meshName, 0); } List <GrannyMeshInfo> grannyMeshInfos = new List <GrannyMeshInfo>(); for (int i = 0; i < model.MeshBindings.Count; i++) { GrannyMeshWrapper meshWrapper = new GrannyMeshWrapper(model.MeshBindings[i]); grannyMeshInfos.Add(meshWrapper.getMeshInfo()); } BiLookup <int, string> boneLookup = new BiLookup <int, string>(); for (int i = 0; i < skeleton.Bones.Count; i++) { boneLookup.Add(i, skeleton.Bones[i].Name); } Dictionary <string, double[]> boneNameToPositionMap = new Dictionary <string, double[]>(); foreach (IGrannyBone bone in skeleton.Bones) { double[] bonePosition = getBoneWorldPosition(bone); boneNameToPositionMap.Add(bone.Name, bonePosition); } outputWriter.WriteLine("// Nexus Buddy NB2 - Exported from Nexus Buddy 2"); outputWriter.WriteLine("Frames: 30"); outputWriter.WriteLine("Frame: 1"); // Write Meshes outputWriter.WriteLine("Meshes: " + model.MeshBindings.Count); for (int mi = 0; mi < grannyMeshInfos.Count; mi++) { GrannyMeshInfo grannyMeshInfo = grannyMeshInfos[mi]; string meshName = model.MeshBindings[mi].Name; meshNameCount[meshName]++; if (meshNameCount[meshName] > 1) { meshName += meshNameCount[meshName]; } outputWriter.WriteLine("\"" + meshName + "\" 0 0"); // Write Vertices outputWriter.WriteLine(grannyMeshInfo.vertices.Count); for (int vi = 0; vi < grannyMeshInfo.vertices.Count; vi++) { GrannyVertexInfo vertex = grannyMeshInfo.vertices[vi]; string boneName0 = grannyMeshInfo.boneBindings[vertex.boneIndices[0]]; float boneWeight0 = (float)vertex.boneWeights[0] / 255; int boneId0 = getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName0, boneWeight0, vertex.position); string boneName1 = grannyMeshInfo.boneBindings[vertex.boneIndices[1]]; float boneWeight1 = (float)vertex.boneWeights[1] / 255; int boneId1 = getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName1, boneWeight1, vertex.position); string boneName2 = grannyMeshInfo.boneBindings[vertex.boneIndices[2]]; float boneWeight2 = (float)vertex.boneWeights[2] / 255; int boneId2 = getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName2, boneWeight2, vertex.position); string boneName3 = grannyMeshInfo.boneBindings[vertex.boneIndices[3]]; float boneWeight3 = (float)vertex.boneWeights[3] / 255; int boneId3 = getBoneIdForBoneName(boneLookup, boneNameToPositionMap, boneName3, boneWeight3, vertex.position); outputWriter.WriteLine("0 " + vertex.position[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.position[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.position[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.uv[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.uv[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId0 + " " + boneWeight0.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId1 + " " + boneWeight1.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId2 + " " + boneWeight2.ToString(numberFormat, CultureInfo.InvariantCulture) + " " + boneId3 + " " + boneWeight3.ToString(numberFormat, CultureInfo.InvariantCulture) ); } // Write Normals outputWriter.WriteLine(grannyMeshInfo.vertices.Count); for (int ni = 0; ni < grannyMeshInfo.vertices.Count; ni++) { GrannyVertexInfo vertex = grannyMeshInfo.vertices[ni]; outputWriter.WriteLine(vertex.normal[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + vertex.normal[2].ToString(numberFormat, CultureInfo.InvariantCulture)); } // Write Triangles outputWriter.WriteLine(grannyMeshInfo.triangles.Count); for (int ti = 0; ti < grannyMeshInfo.triangles.Count; ti++) { int[] triangle = grannyMeshInfo.triangles[ti]; outputWriter.WriteLine("0 " + triangle[0] + " " + triangle[1] + " " + triangle[2] + " " + triangle[0] + " " + triangle[1] + " " + triangle[2] + " 1"); } } // Write Material outputWriter.WriteLine("Materials: 1"); outputWriter.WriteLine("\"Material_0\""); outputWriter.WriteLine("0.200000 0.200000 0.200000 1.000000"); outputWriter.WriteLine("0.800000 0.800000 0.800000 1.000000"); outputWriter.WriteLine("0.000000 0.000000 0.000000 1.000000"); outputWriter.WriteLine("0.000000 0.000000 0.000000 1.000000"); outputWriter.WriteLine("0.000000"); outputWriter.WriteLine("1.000000"); outputWriter.WriteLine("\"Material_0\""); outputWriter.WriteLine("\"\""); // Write Bones outputWriter.WriteLine("Bones: " + skeleton.Bones.Count); for (int bi = 0; bi < skeleton.Bones.Count; bi++) { IGrannyBone bone = skeleton.Bones[bi]; string boneName = bone.Name; outputWriter.WriteLine("\"" + boneName + "\""); if (bone.ParentIndex == -1) { outputWriter.WriteLine("\"\""); } else { string parentBoneName = skeleton.Bones[bone.ParentIndex].Name; outputWriter.WriteLine("\"" + parentBoneName + "\""); } IGrannyTransform transform = bone.LocalTransform; float[] orientation = transform.Orientation; float[] position = transform.Position; outputWriter.WriteLine("0 " + position[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + position[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + position[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[0].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[1].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[2].ToString(numberFormat, CultureInfo.InvariantCulture) + " " + orientation[3].ToString(numberFormat, CultureInfo.InvariantCulture)); // number of position keys outputWriter.WriteLine("0"); // number of rotation keys outputWriter.WriteLine("0"); } outputWriter.Close(); }