Skip to main content

assign_inverted_counters

Function assign_inverted_counters 

Source
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”.