/// <summary> /// Exports all currently loaded characters. Probably wont export characters that have not been loaded yet, like characters in a different classroom. /// </summary> public void ExportCharacters() { int counter = 0; var charas = FindObjectsOfType <ChaControl>(); string filenamePrefix = Path.Combine(ExportPath, $"_CharacterExport_{DateTime.Now:yyyy-MM-dd-HH-mm-ss}"); bool openedFile = false; for (; counter < charas.Length; counter++) { string sex = charas[counter].chaFile.parameter.sex == 0 ? "Male" : "Female"; string filename = $"{filenamePrefix}_{counter:00}_{sex}.png"; #if AI || EC || HS2 Traverse.Create(charas[counter].chaFile).Method("SaveFile", filename, 0).GetValue(); #elif KK Traverse.Create(charas[counter].chaFile).Method("SaveFile", filename).GetValue(); #else Logger.LogError($"Exporting not yet implemented"); #endif if (!openedFile) { if (OpenFolderAfterExport.Value) { CC.OpenFileInExplorer(filename); } openedFile = true; } } string s = counter == 1 ? "" : "s"; Logger.Log(BepInEx.Logging.LogLevel.Info | BepInEx.Logging.LogLevel.Message, $"Exported {counter} character{s}."); }
/// <summary> /// Exports the mesh of the SkinnedMeshRenderer or MeshRenderer /// </summary> public static void ExportObj(Renderer rend) { string filename = Path.Combine(ExportPath, $"{rend.NameFormatted()}.obj"); using (StreamWriter sw = new StreamWriter(filename)) { string mesh = MeshToObjString(rend); if (!mesh.IsNullOrEmpty()) { sw.Write(mesh); Logger.LogInfo($"Exported {filename}"); CC.OpenFileInExplorer(filename); } } }
/// <summary> /// Exports the UV map(s) of the SkinnedMeshRenderer or MeshRenderer /// </summary> public static void ExportUVMaps(Renderer rend) { bool openedFile = false; Shader shader = Shader.Find("Hidden/Internal-Colored"); var lineMaterial = new Material(shader); lineMaterial.hideFlags = HideFlags.HideAndDontSave; lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off); lineMaterial.SetInt("_ZWrite", 0); Mesh mr; if (rend is MeshRenderer meshRenderer) { mr = meshRenderer.GetComponent <MeshFilter>().mesh; } else if (rend is SkinnedMeshRenderer skinnedMeshRenderer) { mr = skinnedMeshRenderer.sharedMesh; } else { return; } for (int x = 0; x < mr.subMeshCount; x++) { var tris = mr.GetTriangles(x); var uvs = mr.uv; const int size = 4096; var _renderTexture = RenderTexture.GetTemporary(size, size); var lineColor = Color.black; Graphics.SetRenderTarget(_renderTexture); GL.PushMatrix(); GL.LoadOrtho(); //GL.LoadPixelMatrix(); // * 2 - 1, maps differently. GL.Clear(false, true, Color.clear); lineMaterial.SetPass(0); GL.Begin(GL.LINES); GL.Color(lineColor); for (var i = 0; i < tris.Length; i += 3) { var v = uvs[tris[i]]; var n1 = uvs[tris[i + 1]]; var n2 = uvs[tris[i + 2]]; GL.Vertex(v); GL.Vertex(n1); GL.Vertex(v); GL.Vertex(n2); GL.Vertex(n1); GL.Vertex(n2); } GL.End(); GL.PopMatrix(); Graphics.SetRenderTarget(null); var png = GetT2D(_renderTexture); RenderTexture.ReleaseTemporary(_renderTexture); string filename = Path.Combine(ExportPath, $"{rend.NameFormatted()}_{x}.png"); File.WriteAllBytes(filename, png.EncodeToPNG()); DestroyImmediate(png); Logger.LogInfo($"Exported {filename}"); if (!openedFile) { CC.OpenFileInExplorer(filename); } openedFile = true; } }