Revamped collision system

This commit is contained in:
Jan Racek
2026-03-27 16:39:42 +01:00
parent d29ef569b3
commit 1c48b8b425
16 changed files with 318 additions and 136 deletions

View File

@@ -39,6 +39,9 @@ namespace SplashEdit.RuntimeCode
// Custom fonts (v13, embedded in UI block)
public PSXFontData[] fonts;
// Trigger boxes (v16)
public PSXTriggerBox[] triggerBoxes;
// Player
public Vector3 playerPos;
public Quaternion playerRot;
@@ -105,32 +108,40 @@ namespace SplashEdit.RuntimeCode
}
if (scene.sceneLuaFile != null && !luaFiles.Contains(scene.sceneLuaFile))
luaFiles.Add(scene.sceneLuaFile);
// Trigger box Lua files
if (scene.triggerBoxes != null)
{
foreach (var tb in scene.triggerBoxes)
{
if (tb.LuaFile != null && !luaFiles.Contains(tb.LuaFile))
luaFiles.Add(tb.LuaFile);
}
}
using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)))
{
int colliderCount = 0;
foreach (var e in scene.exporters)
{
if (e.CollisionType == PSXCollisionType.None || e.StaticCollider)
continue;
Mesh cm = e.CustomCollisionMesh != null
? e.CustomCollisionMesh
: e.GetComponent<MeshFilter>()?.sharedMesh;
if (cm != null)
if (e.CollisionType != PSXCollisionType.Dynamic) continue;
MeshFilter mf = e.GetComponent<MeshFilter>();
if (mf?.sharedMesh != null)
colliderCount++;
}
int triggerBoxCount = scene.triggerBoxes?.Length ?? 0;
// Build exporter index lookup for components
Dictionary<PSXObjectExporter, int> exporterIndex = new Dictionary<PSXObjectExporter, int>();
for (int i = 0; i < scene.exporters.Length; i++)
exporterIndex[scene.exporters[i]] = i;
// ──────────────────────────────────────────────────────
// Header (104 bytes — splashpack v15)
// Header (104 bytes — splashpack v16)
// ──────────────────────────────────────────────────────
writer.Write('S');
writer.Write('P');
writer.Write((ushort)15);
writer.Write((ushort)16);
writer.Write((ushort)luaFiles.Count);
writer.Write((ushort)scene.exporters.Length);
writer.Write((ushort)scene.atlases.Length);
@@ -156,7 +167,7 @@ namespace SplashEdit.RuntimeCode
writer.Write((ushort)scene.bvh.TriangleRefCount);
writer.Write((ushort)scene.sceneType);
writer.Write((ushort)0); // pad0
writer.Write((ushort)triggerBoxCount); // was pad0
writer.Write((ushort)scene.collisionExporter.MeshCount);
writer.Write((ushort)scene.collisionExporter.TriangleCount);
@@ -278,29 +289,50 @@ namespace SplashEdit.RuntimeCode
}
// ──────────────────────────────────────────────────────
// Collider metadata (32 bytes each)
// Collider metadata (32 bytes each) — Dynamic objects only
// ──────────────────────────────────────────────────────
for (int exporterIdx = 0; exporterIdx < scene.exporters.Length; exporterIdx++)
{
PSXObjectExporter exporter = scene.exporters[exporterIdx];
if (exporter.CollisionType == PSXCollisionType.None || exporter.StaticCollider)
continue;
if (exporter.CollisionType != PSXCollisionType.Dynamic) continue;
MeshFilter meshFilter = exporter.GetComponent<MeshFilter>();
Mesh collisionMesh = exporter.CustomCollisionMesh != null
? exporter.CustomCollisionMesh
: meshFilter?.sharedMesh;
Mesh renderMesh = meshFilter?.sharedMesh;
if (renderMesh == null) continue;
if (collisionMesh == null)
continue;
WriteWorldAABB(writer, exporter, renderMesh.bounds, gte);
WriteWorldAABB(writer, exporter, collisionMesh.bounds, gte);
// Collision metadata (8 bytes)
writer.Write((byte)exporter.CollisionType);
writer.Write((byte)(1 << (exporter.CollisionLayer - 1)));
writer.Write((byte)1); // CollisionType::Solid on C++ side
writer.Write((byte)0xFF); // layerMask (all layers)
writer.Write((ushort)exporterIdx);
writer.Write((uint)0); // padding
writer.Write((uint)0);
}
// ──────────────────────────────────────────────────────
// Trigger box metadata (32 bytes each)
// ──────────────────────────────────────────────────────
if (scene.triggerBoxes != null)
{
foreach (var tb in scene.triggerBoxes)
{
Bounds wb = tb.GetWorldBounds();
Vector3 wMin = wb.min;
Vector3 wMax = wb.max;
writer.Write(PSXTrig.ConvertWorldToFixed12(wMin.x / gte));
writer.Write(PSXTrig.ConvertWorldToFixed12(-wMax.y / gte));
writer.Write(PSXTrig.ConvertWorldToFixed12(wMin.z / gte));
writer.Write(PSXTrig.ConvertWorldToFixed12(wMax.x / gte));
writer.Write(PSXTrig.ConvertWorldToFixed12(-wMin.y / gte));
writer.Write(PSXTrig.ConvertWorldToFixed12(wMax.z / gte));
if (tb.LuaFile != null)
writer.Write((short)luaFiles.IndexOf(tb.LuaFile));
else
writer.Write((short)-1);
writer.Write((ushort)0); // padding
writer.Write((uint)0); // padding
}
}
// ──────────────────────────────────────────────────────