Camera transform found at 0x18aa70: three orthonormal matrices, one position
With PCSX2 on Aranos the savestate problem went away. PINE reads EE RAM live, so two dumps seconds apart are consecutive frames by construction -- exactly what the offline savestates could not provide (1aa94ee). Of 1,654 changed 16-byte float triples between two live dumps, most singletons are mob positions moving 4-5 units. One region is three 4x4 matrices at 64-byte stride, each with an affine fourth row: 0x18aa70 0.0338 -0.1983 0.9796 0.0000 -0.0275 -0.9799 -0.1974 0.0000 0.9990 -0.0203 -0.0386 0.0000 247.2990 193.1330 50.4526 1.0000 0x18aab0 t = 247.239, 193.102, 50.497 0x18aaf0 t = 246.940, 193.155, 50.151 The control that makes this an identification rather than a coincidence: all three upper 3x3 blocks are orthonormal to within 1e-6 -- row norms 0.999995..0.999998, pairwise dots at or below 1e-6. Three consecutive float triples in a random 32 MiB region being unit length AND mutually perpendicular does not happen twice. The residual is f32 rounding, expected on an FPU that is not IEEE-754. Camera position on Aranos: (247.3, 193.1, 50.5). camera_transform_is_orthonormal_with_a_moving_translation asserts orthonormality, w == 1, and that the translation moves smoothly but not wildly. That last half is the check1aa94eeneeded and the savestates could not supply: consecutive frames give 0.002-0.005 of movement, against ~230 between unrelated savestates. What this unblocks: guard_band step 1 is R * (bsphere - camera * 1024). Both operands now exist. R is rows 0-2 of 0x18aa70 and the camera is its fourth row, so the clip test can run against a real frame for the first time. Not assumed, and recorded as open: which of the three matrices step 1 wants; whether the float translation needs converting to the disc's 12.4 fixed point first (the algorithm multiplies by 1024, which implies it does); and the frustum planes, which the guard band needs and which are not in this structure.
This commit is contained in:
@@ -2773,3 +2773,51 @@ the game does. The `tan` scale in particular -- 1024 for 1.0 -- is my reading of
|
||||
the fixed-point convention and is **not** established, and the clip-cube scale of
|
||||
64 is likewise R&C1's documented value, unverified. Both are noted in the module
|
||||
doc so they are not mistaken for measured facts.
|
||||
|
||||
## The camera transform is at 0x18aa70 -- found live, verified by orthonormality
|
||||
|
||||
With PCSX2 on Aranos, the savestate problem went away: **PINE reads EE RAM live**,
|
||||
so two dumps seconds apart are consecutive frames by construction, which is exactly
|
||||
what the offline savestates could not provide.
|
||||
|
||||
Two live dumps 1.5s apart. Of every 16-byte-aligned triple of finite plausible
|
||||
floats, **1,654 differ**; 1,501 are singletons and 153 repeat a neighbouring
|
||||
triple (those are the per-object arrays). Most of the singletons are mob positions
|
||||
moving 4-5 units. Two shapes stood out:
|
||||
|
||||
0x18aaa0 [247.299, 193.133, 50.453] -> ... moved 0.26 over 2s
|
||||
0x18aa70..0x18ab2c unit vectors that reoriented
|
||||
|
||||
The second region is **three 4x4 matrices at 64-byte stride**:
|
||||
|
||||
0x18aa70 0.0338 -0.1983 0.9796 0.0000
|
||||
-0.0275 -0.9799 -0.1974 0.0000
|
||||
0.9990 -0.0203 -0.0386 0.0000
|
||||
247.2990 193.1330 50.4526 1.0000
|
||||
0x18aab0 (same shape, t = 247.239, 193.102, 50.497)
|
||||
0x18aaf0 (same shape, t = 246.940, 193.155, 50.151)
|
||||
|
||||
**The control that makes this an identification:** all three upper 3x3 blocks are
|
||||
orthonormal to within 1e-6 -- row norms 0.999995..0.999998, pairwise dot products
|
||||
1e-6 and below. Three consecutive float triples in a random 32 MiB region being
|
||||
unit length *and* mutually perpendicular is not a coincidence anyone gets twice.
|
||||
The residual is f32 rounding, which is the expected result on an FPU that is not
|
||||
IEEE-754 (AGENTS rule 2).
|
||||
|
||||
Each fourth row is `(x, y, z, 1.0)` -- affine, and the translation is the camera
|
||||
position, shared across all three to within 0.4 units. Three matrices with one
|
||||
position is what a view / modelview / lighting family looks like.
|
||||
|
||||
**Camera position on Aranos: (247.3, 193.1, 50.5).** Test asserts orthonormality,
|
||||
`w == 1`, and that the translation moves smoothly but not wildly -- the second half
|
||||
is the check `1aa94ee` needed and the savestates could not supply.
|
||||
|
||||
**What this unblocks.** `guard_band` step 1 is `R * (bsphere - camera * 1024)`.
|
||||
Both operands are now available: `R` is rows 0-2 of `0x18aa70`, and the camera is
|
||||
its fourth row. The clip test can be run against a real frame for the first time.
|
||||
|
||||
**Still to establish**, and deliberately not assumed: which of the three matrices is
|
||||
the one step 1 wants, whether the translation is world or camera space (the
|
||||
guard-band algorithm multiplies by 1024, which implies the disc's own 12.4 fixed
|
||||
point, so the float translation may need converting first), and the frustum
|
||||
planes, which the guard band needs and which are not in this structure.
|
||||
|
||||
Reference in New Issue
Block a user