From 9037937d3c342e5116cfabdd306bfbebc6175c7e Mon Sep 17 00:00:00 2001 From: jracek Date: Thu, 3 Apr 2025 21:42:26 +0200 Subject: [PATCH] Added navmesh exporting --- Runtime/PSXNavMesh.cs | 62 +++++++++++++++ Runtime/PSXNavMesh.cs.meta | 2 + Runtime/PSXSceneExporter.cs | 72 ++++++++++++++++-- Runtime/Utils.cs | 2 - .../net.psxsplash.splashedit.Runtime.asmdef | 4 +- package.json | 14 ++-- tools/imhex.hexproj | Bin 18944 -> 19456 bytes 7 files changed, 142 insertions(+), 14 deletions(-) create mode 100644 Runtime/PSXNavMesh.cs create mode 100644 Runtime/PSXNavMesh.cs.meta diff --git a/Runtime/PSXNavMesh.cs b/Runtime/PSXNavMesh.cs new file mode 100644 index 0000000..a8c9e5f --- /dev/null +++ b/Runtime/PSXNavMesh.cs @@ -0,0 +1,62 @@ +using UnityEngine; +using Unity.AI.Navigation; +using UnityEngine.AI; +using System.Collections.Generic; + + +namespace SplashEdit.RuntimeCode +{ + public struct PSXNavMeshTri + { + public PSXNavmeshVertex v0, v1, v2; + } + + public struct PSXNavmeshVertex + { + public short vx, vy, vz; + } + + [RequireComponent(typeof(NavMeshSurface))] + public class PSXNavMesh : MonoBehaviour + { + + [HideInInspector] + public List Navmesh { get; set; } + + public void CreateNavmesh(float GTEScaling) + { + Navmesh = new List(); + NavMeshSurface navMeshSurface = GetComponent(); + navMeshSurface.BuildNavMesh(); + NavMeshTriangulation triangulation = NavMesh.CalculateTriangulation(); + + int[] triangles = triangulation.indices; + Vector3[] vertices = triangulation.vertices; + + for (int i = 0; i < triangles.Length; i += 3) + { + + + int vid0 = triangles[i]; + int vid1 = triangles[i + 1]; + int vid2 = triangles[i + 2]; + + PSXNavMeshTri tri = new PSXNavMeshTri(); + + tri.v0.vx = PSXTrig.ConvertCoordinateToPSX(vertices[vid0].x, GTEScaling); + tri.v0.vy = PSXTrig.ConvertCoordinateToPSX(-vertices[vid0].y, GTEScaling); + tri.v0.vz = PSXTrig.ConvertCoordinateToPSX(vertices[vid0].z, GTEScaling); + + tri.v1.vx = PSXTrig.ConvertCoordinateToPSX(vertices[vid1].x, GTEScaling); + tri.v1.vy = PSXTrig.ConvertCoordinateToPSX(-vertices[vid1].y, GTEScaling); + tri.v1.vz = PSXTrig.ConvertCoordinateToPSX(vertices[vid1].z, GTEScaling); + + tri.v2.vx = PSXTrig.ConvertCoordinateToPSX(vertices[vid2].x, GTEScaling); + tri.v2.vy = PSXTrig.ConvertCoordinateToPSX(-vertices[vid2].y, GTEScaling); + tri.v2.vz = PSXTrig.ConvertCoordinateToPSX(vertices[vid2].z, GTEScaling); + + Navmesh.Add(tri); + } + } + } +} \ No newline at end of file diff --git a/Runtime/PSXNavMesh.cs.meta b/Runtime/PSXNavMesh.cs.meta new file mode 100644 index 0000000..142f03a --- /dev/null +++ b/Runtime/PSXNavMesh.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6a2f8d45e1591de1e945b3b7bdfb123b \ No newline at end of file diff --git a/Runtime/PSXSceneExporter.cs b/Runtime/PSXSceneExporter.cs index b9ebfa9..a42e9d6 100644 --- a/Runtime/PSXSceneExporter.cs +++ b/Runtime/PSXSceneExporter.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using UnityEditor; using UnityEngine; +using UnityEngine.AI; namespace SplashEdit.RuntimeCode { @@ -16,6 +17,7 @@ namespace SplashEdit.RuntimeCode private PSXObjectExporter[] _exporters; private TextureAtlas[] _atlases; + private PSXNavMesh[] _navmeshes; private PSXData _psxData; @@ -34,6 +36,13 @@ namespace SplashEdit.RuntimeCode exp.CreatePSXTextures2D(); exp.CreatePSXMesh(GTEScaling); } + + _navmeshes = FindObjectsByType(FindObjectsSortMode.None); + foreach (PSXNavMesh navmesh in _navmeshes) + { + navmesh.CreateNavmesh(GTEScaling); + } + PackTextures(); ExportFile(); } @@ -73,6 +82,10 @@ namespace SplashEdit.RuntimeCode List clutOffsetPlaceholderPositions = new List(); List clutDataOffsets = new List(); + // Lists for navmesh data offsets. + List navmeshOffsetPlaceholderPositions = new List(); + List navmeshDataOffsets = new List(); + int clutCount = 0; // Cluts @@ -94,9 +107,10 @@ namespace SplashEdit.RuntimeCode writer.Write('P'); // 1 byte writer.Write((ushort)1); // 2 bytes - version writer.Write((ushort)_exporters.Length); // 2 bytes + writer.Write((ushort)_navmeshes.Length); writer.Write((ushort)_atlases.Length); // 2 bytes writer.Write((ushort)clutCount); // 2 bytes - for (int i = 0; i < 3; i++) writer.Write((ushort)0); + for (int i = 0; i < 2; i++) writer.Write((ushort)0); // GameObject section (exporters) foreach (PSXObjectExporter exporter in _exporters) @@ -122,7 +136,18 @@ namespace SplashEdit.RuntimeCode writer.Write((int)rotationMatrix[2, 2]); writer.Write((ushort)exporter.Mesh.Triangles.Count); - writer.Write((ushort) 0); + writer.Write((ushort)0); + } + + // Navmesh metadata section + foreach (PSXNavMesh navmesh in _navmeshes) + { + // Write placeholder for navmesh raw data offset. + navmeshOffsetPlaceholderPositions.Add(writer.BaseStream.Position); + writer.Write((int)0); // 4-byte placeholder for navmesh data offset. + + writer.Write((ushort)navmesh.Navmesh.Count); + writer.Write((ushort)0); } // Atlas metadata section @@ -150,7 +175,7 @@ namespace SplashEdit.RuntimeCode writer.Write((ushort)texture.ClutPackingX); // 2 bytes writer.Write((ushort)texture.ClutPackingY); // 2 bytes writer.Write((ushort)texture.ColorPalette.Count); // 2 bytes - writer.Write((ushort) 0); // 2 bytes + writer.Write((ushort)0); // 2 bytes } } } @@ -228,6 +253,27 @@ namespace SplashEdit.RuntimeCode } } + foreach (PSXNavMesh navmesh in _navmeshes) { + AlignToFourBytes(writer); + long navmeshDataOffset = writer.BaseStream.Position; + navmeshDataOffsets.Add(navmeshDataOffset); + + foreach(PSXNavMeshTri tri in navmesh.Navmesh) { + writer.Write((ushort) tri.v0.vx); + writer.Write((ushort) tri.v0.vy); + writer.Write((ushort) tri.v0.vz); + + writer.Write((ushort) tri.v1.vx); + writer.Write((ushort) tri.v1.vy); + writer.Write((ushort) tri.v1.vz); + + writer.Write((ushort) tri.v2.vx); + writer.Write((ushort) tri.v2.vy); + writer.Write((ushort) tri.v2.vz); + } + + } + // Atlas data section: Write raw texture data for each atlas. foreach (TextureAtlas atlas in _atlases) { @@ -257,8 +303,9 @@ namespace SplashEdit.RuntimeCode long clutDataOffset = writer.BaseStream.Position; clutDataOffsets.Add(clutDataOffset); - foreach(VRAMPixel color in texture.ColorPalette) { - writer.Write((ushort) color.Pack()); + foreach (VRAMPixel color in texture.ColorPalette) + { + writer.Write((ushort)color.Pack()); } } } @@ -279,6 +326,21 @@ namespace SplashEdit.RuntimeCode Debug.LogError("Mismatch between metadata mesh offset placeholders and mesh data blocks!"); } + // Backfill the navmesh offsets into the metadata section. + if (navmeshOffsetPlaceholderPositions.Count == navmeshDataOffsets.Count) + { + for (int i = 0; i < navmeshOffsetPlaceholderPositions.Count; i++) + { + writer.Seek((int)navmeshOffsetPlaceholderPositions[i], SeekOrigin.Begin); + writer.Write((int)navmeshDataOffsets[i]); + } + } + else + { + Debug.LogError("Mismatch between metadata mesh offset placeholders and mesh data blocks!"); + } + + // Backfill the atlas data offsets into the metadata section. if (atlasOffsetPlaceholderPositions.Count == atlasDataOffsets.Count) { diff --git a/Runtime/Utils.cs b/Runtime/Utils.cs index c78c88e..bbe32e2 100644 --- a/Runtime/Utils.cs +++ b/Runtime/Utils.cs @@ -1,7 +1,5 @@ -using System.Runtime.InteropServices; using UnityEditor; using System.Collections.Generic; -using UnityEditor; using UnityEngine; namespace SplashEdit.RuntimeCode diff --git a/Runtime/net.psxsplash.splashedit.Runtime.asmdef b/Runtime/net.psxsplash.splashedit.Runtime.asmdef index 453360d..d825807 100644 --- a/Runtime/net.psxsplash.splashedit.Runtime.asmdef +++ b/Runtime/net.psxsplash.splashedit.Runtime.asmdef @@ -1,7 +1,9 @@ { "name": "net.psxsplash.splashedit.Runtime", "rootNamespace": "", - "references": [], + "references": [ + "GUID:8c4dd21966739024fbd72155091d199e" + ], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, diff --git a/package.json b/package.json index 32f2624..3443c9a 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,10 @@ { - "name": "net.psxsplash.splashedit", - "version": "1.0.0", - "displayName": "Splashedit", - "description": "A toolkit for PSX asset management within Unity", - "unity": "6000.0" + "name": "net.psxsplash.splashedit", + "version": "1.0.0", + "displayName": "Splashedit", + "description": "A toolkit for PSX asset management within Unity", + "unity": "6000.0", + "dependencies": { + "com.unity.ai.navigation": "2.0.6" } - \ No newline at end of file +} \ No newline at end of file diff --git a/tools/imhex.hexproj b/tools/imhex.hexproj index b57631c16288f7dabee6dadb63e17351efa91c6c..6710dffaeabce39ad60aa8c90a6114c86af6d948 100644 GIT binary patch delta 271 zcmZpe!q_l_aYKy=i?NZB$>atR306}R1_gu7hFr;vlf(+y^AgK)Q;RbuCyBW+8f{)F zCcsqBRa{b3np~pb2ayUX%2cT4QUHRm)S{Bq3WYKQoian6G9zoQT5B#e#U81NDXB$J z^`*u}3Q+T15=#>O)6$AlORT|06&soAqh{emEdHD+C8~VLY^6D x#O9?E{~5KQf>1l4CZ`rhr)B1(W`Hf$g9=VAlv3e delta 56 zcmV-80LTA;m;r#40kC`&1Tr-