pub fn assign_inverted_counters(root: &mut MdlNode)Expand description
Assigns the per-mesh sequence value to every mesh node in DFS tree order.
The value is stored at CExoArrayList offset +0xC8. Its shape is a set of
checkpoints at 100 x 2^k, where the value equals the counter, separated
by runs that descend between them.
// c is the 1-based mesh counter
let mut t = 100;
while t < c { t *= 2; }
match c {
_ if c == t => c, // checkpoint
_ if t == 100 => 99 - c, // first run, the special case
_ => t + t / 2 - c,
}Derived from the retail corpus rather than borrowed. It reproduces every
stored value on the deepest unambiguous model and on every model whose
counter is recoverable, it is injective over the range tested, and it
never emits 99 – the first run descends to zero and the first
checkpoint is 100, so that gap is real rather than a rounding artefact.
mdledit’s formula is not this one. It agrees up to counter 299 and is wrong at every counter after, which only shows on models large enough to reach 300.
Saber meshes are skipped entirely. They write none of the three
single-u32 blocks this value belongs to, so they take no counter and
consume no increment.
This is for newly constructed models. Binary-parsed models keep the value
the file carried, which matters because the mapping from mesh ordinal to
counter is not recoverable from the file – see
docs/src/formats/models/mesh_derived_fields.md “1.5 index_buffer_pools /
Inverted Counter”.