Parse tfrag topology: vertex info, strips, indices and triangles
Turns tfrag positions into drawable geometry. Every unpack in a patch's VIF lists is now classified by format *and* destination VU address, using the VU header at the head of the common list. That table is what tells the strips from the indices from the parent arrays: they are all V4_8 and only the address distinguishes them. Strip indices address the vertex-info array, not the position array. Several vertex-info entries can share a position, so an index resolves through vertex_info[i].vertex / 2 to reach a position. Vertex-info also carries UVs and the LOD parent link. A strip run of n vertices is a GS triangle strip of n - 2 triangles with alternating winding. The vertex count is biased by -128 when negative, and the first record of a list is always biased even when positive -- real patches open with -116 or -124, never a small positive number. tri_count lives in the patch header and cannot be derived from the lists without walking them, so reproducing it is a strong check: all 27 levels, 18,102 patches, 809,879 triangles, every patch matching its header, every triangle index inside its LOD's vertex-info range. Four wrong turns got there, each of which failed quietly rather than loudly: reading the element size from the immediate instead of the command, 2-byte payload padding instead of 4, ignoring the inline payload of STROW/STCOL/STMASK/MPG/DIRECT, and banking strips by arrival order instead of by LOD. Every one produced parseable, plausible geometry. Only the header's own triangle count caught them. Still open: ad-gif texture bindings, per-vertex RGBA and light records, and the LOD switch and morph rules.
This commit is contained in:
+9
-3
@@ -20,7 +20,7 @@ early, while they are still cheap to retire.
|
||||
header, and the `data` extent is parsed as a container of byte ranges. The
|
||||
geometry decompresses: level 0 yields 16,969,296 bytes of level content
|
||||
from a 9.7 MB stream.
|
||||
- [ ] Next: tfrag triangle topology, then the geometry directory's class tables.
|
||||
- [ ] Next: tfrag texture bindings, then the geometry directory's class tables.
|
||||
|
||||
The disc being the exact build the reference projects pin is the single
|
||||
biggest favourable fact so far: no disc conversion, no regional timing work,
|
||||
@@ -122,8 +122,14 @@ Phase 1 hands over the extents; this phase works out what each one contains.
|
||||
command byte and every element size follows from it. Verified on all 27
|
||||
levels: **18,102 patches, 821,439 vertices**, each patch yielding exactly
|
||||
its own `vert_count`. See `plan/level-assets.md` and `gc-formats::tfrag`.
|
||||
- [ ] tfrag topology: strips, triangle indices and the RGBA vertex-info arrays,
|
||||
which is what turns positions into drawable geometry.
|
||||
- [x] **tfrag topology: recovered.** Vertex-info (UVs plus LOD parenting), the
|
||||
strip command lists and the index arrays, classified by unpack format and
|
||||
destination VU address. Strip indices address the vertex-info array
|
||||
rather than positions. Every patch's strips expand to exactly its own
|
||||
`tri_count`: **18,102 patches, 809,879 triangles**, all indices in range.
|
||||
See `plan/level-assets.md` and `gc-formats::tfrag`.
|
||||
- [ ] tfrag shading inputs: the ad-gif texture bindings, per-vertex RGBA and
|
||||
light records, then the LOD switch and morph rules in `TfragProc`.
|
||||
- [ ] `gameplay` — begins `WAD` + a per-level byte, and does *not* decode with
|
||||
the WAD LZ77 decoder. All 27 levels fail identically, so the input is
|
||||
wrong rather than the decoder. Ruled out: bit order, header length, the
|
||||
|
||||
Reference in New Issue
Block a user