Close out tfrag on the disc side, and fix two stale "not recovered" claims

Picked tfrag morph targets from the open list and found the premise was wrong.

There are no morph targets in this format. Morphing is a blend toward the midpoint
of the vertex's two PARENT vertices -- g[parent1_position] and
g[parent2_position] -- which are other vertices in the same tfrag. The engine
implements exactly that in resolve_vertex, and it is covered by
morphing_blends_toward_the_parent_midpoint plus
morph_weight_runs_from_zero_to_one_across_its_band and
collapse_distances_are_the_far_edge_of_each_band. So "morph targets unrecovered"
was never a gap; it named a thing that does not exist in the format.

Strip bookkeeping is likewise already there: TfragStrip carries
vertex_count_and_flag, and tfrag_triangles walks the strip command lists and index
arrays to build triangles. That was the other half of the same roadmap entry.

Coverage, all passing: 36 tfrag tests, 9 texture tests, 23 gc-engine tests. The
real-disc texture test decodes all 1595 level textures, with pixels and mip levels,
so the module doc's "not yet recovered: the texel data the texture table points
into" is also stale.

Two stale claims corrected:

1. crates/gc-formats/src/tfrag.rs said "Not yet recovered: the LOD switch and morph
   rules in TfragProc, and the texel data the texture table points into. See
   docs/plan/tfrag.md." The rules are recovered and tested, the texels are
   decoded, and docs/plan/tfrag.md DOES NOT EXIST -- a dangling reference to a
   file that was never written.

2. docs/roadmap.md marked tfrag partial with "Still open: morph targets and the
   strip/chain bookkeeping". Neither is open.

The honest replacement for both is what is genuinely not claimed: the LOD switch
distances, morph weight and collapse edge are DERIVED from the data -- tiers are
classified from the four V4_8 parent arrays, the weight runs zero to one across
each tier's band -- but have not been checked against PCSX2 the way the lighting
pass was. That is a verification gap, not a parsing gap, and it needs a frame
captured at a known view distance rather than more disc-side measurement.
This commit is contained in:
2026-10-13 04:50:28 +02:00
parent d56b439502
commit 6d0c1b6fd1
2 changed files with 19 additions and 5 deletions
+7 -2
View File
@@ -40,8 +40,13 @@
//! minification filter, LOD bias), the per-vertex colours and the per-vertex //! minification filter, LOD bias), the per-vertex colours and the per-vertex
//! light and normal records. //! light and normal records.
//! //!
//! Not yet recovered: the LOD switch and morph rules in `TfragProc`, and the //! What is *not* claimed: that these rules match the original. The LOD switch
//! texel data the texture table points into. See `docs/plan/tfrag.md`. //! distances, the morph weight and the collapse edge are all **derived from the
//! data** -- tiers are classified from the four V4_8 parent arrays, and the
//! weight runs from zero to one across each tier's band -- but they have not
//! been checked against PCSX2 the way the lighting pass was. That check is the
//! outstanding item, and it needs a frame captured at a known view distance
//! rather than more disc-side measurement.
use crate::buf::{Buf, Error, ErrorKind, Result}; use crate::buf::{Buf, Error, ErrorKind, Result};
+12 -3
View File
@@ -238,9 +238,18 @@ Phase 1 hands over the extents; this phase works out what each one contains.
`core_index.bin` and `gs_ram.bin` at fixed `u32` indices 1, 3 and 5 on `core_index.bin` and `gs_ram.bin` at fixed `u32` indices 1, 3 and 5 on
every level checked. What follows the descriptor is still unknown. every level checked. What follows the descriptor is still unknown.
- [~] `tfrag` — vertex format, topology, texture bindings, per-vertex colour - [x] `tfrag` — **complete on the disc side.** Vertex format, topology, strips
and normals, LOD selection and parent indices are all recovered and (`TfragStrip`), texture bindings, per-vertex colour and normals, LOD
verified. **Still open:** morph targets and the strip/chain bookkeeping. selection, parent indices, morphing and collapse. 36 format tests, 9 texture
tests, 23 engine tests. The morphing is a blend toward the **parent
vertices'** midpoint, not toward separate morph targets — there are no
morph targets in this format, which is what the old "morph targets
unrecovered" note wrongly implied.
- [ ] What tfrag is **not** yet verified against is the original: the LOD switch
distances, morph weight and collapse edge are derived from the data (tiers
classified from the four V4_8 parent arrays, weight running zero to one
across each band), but have not been compared against PCSX2 the way the
lighting pass was. That needs a frame at a known view distance.
- [x] `tie` — **fully chained.** `resolve_tie_class` walks both indirections: the - [x] `tie` — **fully chained.** `resolve_tie_class` walks both indirections: the
class table is in `core_index.bin`, and the entry's `offset_in_asset_wad` class table is in `core_index.bin`, and the entry's `offset_in_asset_wad`
addresses `core_data.bin` (not `core_data.wad`). All **1,864** tie classes addresses `core_data.bin` (not `core_data.wad`). All **1,864** tie classes