diff --git a/docs/re/structures/regn-map-grid.md b/docs/re/structures/regn-map-grid.md index ee8401ff..d426acb3 100644 --- a/docs/re/structures/regn-map-grid.md +++ b/docs/re/structures/regn-map-grid.md @@ -435,12 +435,64 @@ Two things follow, and both are load-bearing: 1. **The fixup base is `chunk + 0x10`, not `chunk + 0`** (`82465198`: `addi r3, r31, 16`). Every stored "offset" in a `REGN` file is relative to - file offset `0x10`. **Everything on this page above was read 16 bytes early.** - That single error is why twenty correlation tests returned chance. + file offset `0x10`, and every **record origin** on this page above is + therefore 16 bytes early. 2. **The `POF0` table is an exact list of which words are pointers.** It is not a heuristic โ€” it is the data the retail loader itself walks. Decoding it gives the pointer graph directly, with no guessing. +### ๐Ÿ”ด A correction to how I first stated point 1 + +The first version of this section said "everything on this page above was read +16 bytes early", which is **too broad and I withdraw it**. For the plane fields +it is *false*: the older reading put the section at `chunk + offset` and the +normal at intra-record `+16`, which addresses **exactly the same bytes** as +`chunk + 0x10 + offset` with the normal at `+0`. Its unit-normal and +`nยทp + d = 0` results were measuring real planes and stand unchanged. On +`3506e972`, both conventions put face record 0's normal at file offset +**`0x1c700` (116 480)** = `0x10 + 0x1c6f0`, where the header word at `0x78` is +`0x1c6f0`. + +What is genuinely wrong is the **record boundary**, and it matters for one +reason: it decides which 48-byte record the four integer words belong to โ€” and +those integer words are the face adjacency, i.e. precisely the thing the +correlation search was hunting for. It also mis-resolves every stored pointer +by 16 bytes, twice over along the cell โ†’ item โ†’ ref โ†’ tetrahedron chain, which +is the mechanical reason that chain never landed on anything. + +### โœ… Which tests actually decide the origin โ€” and which have no power + +Most of the numbers on this page are **content** tests and address the same +bytes under either convention, so they cannot settle the origin. Stated +plainly, because the same trap caught the point-in-bbox test: + +| test | discriminates the base? | +|---|---| +| section-5 targets on 96-byte boundaries; ref-array packing | โŒ no โ€” `target โˆ’ start` cancels the base | +| face passes through 3 of 4 vertices; portal-cost identity | โŒ no โ€” same absolute bytes either way | +| sphere reaches its cell (98.7 % vs 18โ€“28 %) | โŒ no for the base; it discriminates the **axis order** | +| points inside the bbox (the older section) | โŒ no โ€” a denormal reads as โ‰ˆ 0, which is inside a ยฑ250 km box | +| **the loader's own `addi r3, r31, 16`** | โœ… direct | +| **where `POF0` says the header pointers are** | โœ… at `+0x10` the six relocated slots are exactly `0x70`โ€“`0x84`, the six section pointers. At `+0` they would be `0x60`โ€“`0x74`: the loader would relocate the `u16` **counts** and would leave the pointers at `0x78`โ€“`0x84` unrelocated. Not merely wrong โ€” non-functional. | +| **what section-0 record 0 contains** | โœ… at `+0x10` a real vertex (`-250000, 250000, -250000` on `d4c89536`); at `+0` the two remaining header pointer words read as floats โ€” `2.2e-40, 2.7e-40, 0` | +| **the section-2 record boundary** | โœ… see below, 100.000 % against 0.000 % | + +### โœ… The record boundary, settled + +A tetrahedron names face `f`; the plane at record `f` is independently verified +(three of the tet's four vertices lie on it, 100 %). The question is whether the +adjacency block that says *"I am face `f`, my tetrahedra are A and B, at their +face slots i and j"* sits in the **same** 48-byte record as that plane. + +Requiring `own == f` **and** `tet[A].faces[i] == f`: + + adjacency block taken from record f (base + 0x10) : 100.000 % + adjacency block taken from record f + 1 (base + 0) : 0.000 % + +11 of 11 objects, every face, both sides. The plane and the four integer words +that describe it are one record, and that record starts at `chunk + 0x10 + +offset + 48ยทf`. + `sub_82465138` is reached from exactly two callers, `sub_82461018` (vtable slot 9 of the class at `0x820af8bc`, the pak/resource file class) and `sub_82461DE8`; both store `chunk + 16` as the object's data pointer, which @@ -630,6 +682,8 @@ reason, and that is worth having on the page. | "record `+0x1c` is a bounding-sphere radius (ratio 1.001 on one object, 0.13โ€“0.27 on the rest)" | ๐ŸŸก **half right** โ€” `+0x0c` *is* a bounding-sphere radius, of the *tetrahedron*; the 1.001 was a coincidence of that map, where every tet shares the cube's circumsphere | | "`(count, offset)` pairs point at leaf arrays of `count ร— 4` bytes" | ๐ŸŸก **right mechanism, wrong record** โ€” it is the cell *item* at `+0x10`/`+0x14` pointing into section 5, not the cell index | | "slots 8โ€“11 are integers (denormal as float)" | โœ… correct, and they are the four vertex + four face `u16` indices | +| "section 2 records are 48 bytes, unit normal, `nยทp + d = 0` in 133 573/133 573" | โœ… **stands** โ€” the same bytes under either origin convention; only the record boundary moves, see the correction above | +| "section 0 points are inside the bbox, 13 467/13 467" | โš ๏ธ true but **uninformative** โ€” it passes at either origin, because a denormal reads as โ‰ˆ 0 and 0 is inside the box | | "slot 7 is a local scale, ~14ร— smaller than the inter-node distance" | โœ… correct as measured โ€” it is a *tetrahedron's* bounding radius, which is exactly that small | | "the BVH reading is refuted, no node sphere contains another" | โœ… stands, and is now explained: these are sibling tetrahedra, not a tree | | "the cell payload holds section-1 indices" | โœ… stands โ€” it holds a **pointer to an array of pointers**, and no index anywhere |