Skip to content

Prj2 export - #1

Merged
Checkm8Croft merged 8 commits into
masterfrom
prj2-export
Aug 10, 2026
Merged

Prj2 export#1
Checkm8Croft merged 8 commits into
masterfrom
prj2-export

Conversation

@Checkm8Croft

Copy link
Copy Markdown
Owner

No description provided.

Builds a TombLib Level/Room/Sector object graph from the TR4 data already
resolved by TrLevel.ConvertToPrj/MakeDoors (geometry, splits, alternate
rooms, door/portal detection), then serializes it with TombLib's own
Prj2Writer. No manual PRJ2 chunk writing.

- Reference TombLib.dll and its runtime dependencies via HintPath (C:\Tomb Editor)
- Prj2Exporter: sector type/heights/splits, alternate room linking, portals
- Wire up Export PRJ2 menu item in MainWindow
…ne spec

AddX/AddZ were being applied to the wrong corner pair (verified against
TRosettaStone Function 0x02/0x03 semantics). Also removed the fixFdivs
NGLE-only hack from the PRJ2 export path (synthetic split values on
nearly every block). Wall/BorderWall perimeter sectors now use flat
heights instead of leftover per-corner deltas.

Remaining: split/triangulated floors (FloorData 0x07-0x12) still show a
high shared-edge mismatch rate against neighbours (~60%%) -- corner-order
fix attempted and reverted (made it worse; likely needs the currently-
unused per-triangle H1/H2 height offsets, not just a corner-order fix).
FDiv/CDiv -> SetHeight(Floor2/Ceiling2,...) was the wrong TombLib
mechanism entirely (that's an unrelated NGLE 'extra floor level'
feature). The actual mechanism is SectorSurface.SplitDirectionIsXEqualsZ,
which picks which diagonal a sector's 2 collision/render triangles are\nsplit along. Left at its default, a non-coplanar quad still silently\nauto-picks a diagonal (not necessarily TR4's real one), which is likely\nthe dominant source of the widespread illegal-slope warnings even\nthough the 4 corner heights themselves were already correct.

Added Block.FloorSplitXEqualsZ/CeilingSplitXEqualsZ, set from the
TR4 FloorData split-direction function groups (Split1-4/Nocol1-8),
and wired into Prj2Exporter.
PrjDiag now loads the exported PRJ2 back through TombLib's own
Prj2Loader and runs the exact IsIllegalSlope check Tomb Editor uses,
giving an objective count instead of relying on visual inspection.
On alexhub2.tr4: 356/2625 non-wall sectors (13.6%) still flagged,
down from a much higher baseline before the Tilt/split-direction fixes.

Also removed malformed debug code and a Temp-path change that had
been introduced directly in the working tree (outside these commits)
and were breaking the build / silently changing the export location.

Tried an alternative portal-conflict strategy (place each door
individually, largest-area-first, instead of merging same-direction/
target doors into one union rectangle): empirically worse (127 vs 114
conflicts), so kept the union-merge approach.
Applied the same TRosettaStone-verified H = Hbase + (max(dC) - dCn)
formula used for floor splits, mapped by corner NAME to ceiling's
different index convention. Objective measurement (sectors where
ceiling ends up below floor at some corner -- a physically impossible,
concretely checkable bug class): 102/2625 (3.9%) -> 85/2625 (3.2%) on
alexhub2.tr4. Remaining cases are mostly 1-click near-misses.

Note: found ApplyCeilingSplit's prior state (direct assignment, Ceiling\n-= maxCorner) differed from what this session had left it at, consistent\nwith a concurrent editor (Claude Code / VS) touching the same files.
…licate mirrors

Room.AddObject(level, portalInstance) in TombLib auto-creates the
opposite portal in the adjoining room. Prj2Exporter was independently\nprocessing EVERY room's own (TR4-sourced) door list and adding a portal\nfrom each side, so the second side always collided with the mirror\nTombLib had already auto-created when the first side was added.

Fix: only add a room-pair's portal once, from the lower room index;\nrely on TombLib to create the opposite side. Portal conflicts on\nalexhub2.tr4: 114 -> 13. The remaining 13 are all small (1-3 sector)\nwall portals, consistent with TombLib's one-wall-portal-per-sector\nstructural limit (corner sectors bordering two different neighbours),\nnot a bug.

Also re-applied the verified floor split formula (H = Hfloor + max -\ndCn, matching the ceiling fix) for consistency, even though on the\nreliable IsIllegalSlope metric it was a wash (14.0% vs 13.6%).
…positioning

For portal.Normal.X==1 and Normal.Z==1, the door's position along the
perpendicular (into-the-wall) axis was hardcoded to 0 instead of being
computed from the portal's actual vertex coordinates (minx/minz), unlike
the symmetric Normal.X==-1/Z==-1 cases which already computed it
correctly. Since minx==maxx (resp. minz==maxz) for these thin wall
portals, the fix makes the formula for the +1 and -1 cases identical
except for d.Id, which is the expected/correct symmetry.

This places every WallPositiveX/WallPositiveZ portal at the room's
actual edge column instead of always column/row 0 -- likely the room-
misalignment ('stanze spostate di un click') the user was seeing.
Doesn't show up in the IsIllegalSlope or portal-overlap-count metrics
(different failure mode: position, not internal validity/collision),
so needs visual confirmation in Tomb Editor.
@Checkm8Croft
Checkm8Croft merged commit 9156b1c into master Aug 10, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant