Revamped collision system
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user