# Original galaxy camera evidence This is offline evidence from pinned image SHA256 `6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93`, with no game process access, game calls or network requests. All native RVA labels below refer to that image. The ordinary lens and smoothing are recovered; physical input calibration, cadence and the independent catalogue/query boundary retain the explicitly identified application choices below. ## Configuration binding Run `research/Extract-OriginalGalaxyCameraConfig.py --verify` with the local analysis Python environment. It checks the source hashes, frozen references, owning entity, exact float fields and hashes of the relevant decompilations. The resulting `artifacts/galaxy-query-research/constellations/original-camera-config.json` retains the source offsets. Native registration `3C12700` supplies the name `GalaxyMapCamera` at `5538428`. Its hash routine `3BA0610` lowercases ASCII letters and uses DJB2 seed5381, multiplier33. This yields `EC6A0092`. The original FRES record at file `1E5B40` is `[EC6A0092,10,1490,423,14672]`: root ordinal1490 is the actual named `galaxymap` entity `(B9B564A9,7C9C6DAE,466,8480)`. Its component vector has17 entries, and entry9 references the exact configuration `(423,14672)`. A second same-type record belongs to `galaxymapforcapture` and is not used for the ordinary map. Allocator pool numbers alone were not treated as type identities. The original constructor `3AC7C50` installs the camera orbit subobject at component+70, whose configuration pointer is subobject-20. Its configuration reader `3B40630` proves these assignments: | Configuration field | Original use | Exact float value | | --- | --- | --- | | 10 /14 | Pitch/yaw input gains | 1.2999999523162842 | | 18 | Zoom exponent gain | 3.5999999046325684 | | 1C | Translation gain | 8 | | 20 /24 | Pitch limits in degrees | -80 /80 | | 28 /44 | Fallback pitch/yaw in degrees | 45 /30 | | 30 /34 | Minimum/maximum distance | 6 /25000 | | 38 | Fallback distance | 17.75 | | 3C | Both pitch and log-distance smoothing | 0.20000000298023224 | | 40 | Yaw smoothing | 0.20000000298023224 | | 48 | Focus smoothing | 0.30000001192092896 | Degree metadata is converted with the original float at `4E32730`, `0.01745329238474369`. The unused-looking float at configuration2C is not substituted for the actual pitch coefficient: the consumer explicitly reads3C for both channels. `3B3E8C0` selects each optional saved camera value when its flag is present. Only missing saved values fall back to the values above. This proves a fallback pose; it does not prove that a Reset button should discard the original saved pose. The application's Reset remains an explicit application choice because original saved pose import and each recenter action's transition source are not implemented. ## Units, pose and ordinary update `3B3E8C0` unpacks the compact catalogue coordinates and multiplies each raw coordinate by the original float at `5192F68`, exactly `0.03125`, before writing component150, which is orbit-subobjectE0, the target focus. `3A3B630` builds the eye from that same focus minus distance times Forward with no further unit conversion. Thus both the focus and the6..25000 distance range are in light years. Ordinary pose fields relative to the orbit subobject are actual pitch70, yaw80, distance90 and focusA0, with targets B0/C0/D0/E0 respectively. `3A32B70` dispatches the update `3A2B800`; the event thunk `130B590` subtracts10 from its registered listener pointer to recover this subobject. Native call-site registers before the matrix call at `3A2BC12` supply the actual pose at subobject70, even though the decompiler omits that third argument. In the ordinary phase, `3A2B800` applies these factors once per update, without multiplying them by delta time: * Focus uses `actual += (target-actual)*config48` independently on XYZ. * Pitch and yaw use the direct unwrapped target difference with config3C and40. * Distance uses `actual *= 2^((log2(target)-log2(actual))*config3C)`. * If arithmetic cannot change the current value, the original settles to the target. Additional residual tests use runtime BSS globals `5FD85A0` and `5FD8620`; their initialized values are not available in the offline image. The application ports the algorithm using double coordinates. It does not claim SIMD float bit identity. Its explicit stop tolerances are `.0001ly` for focus/distance and `.000001rad` for angles, so the UI timer can stop. They are application tolerances, not recovered original epsilon values. Cinematic recenter has another phase with quadratic ease-in/out and linear distance interpolation; it is not silently substituted for ordinary input smoothing. The normal, non-alternate-axis basis from `3A3B630` is: ``` Right = (cos(yaw), 0, -sin(yaw)) Forward = (sin(yaw)*cos(pitch), -sin(pitch), cos(yaw)*cos(pitch)) Up = (sin(yaw)*sin(pitch), cos(pitch), cos(yaw)*sin(pitch)) Eye = Focus - Distance*Forward ``` Focus is an independent camera value. Ordinary orbit does not rebase to a selected star's physical Y. The explicit `3A598D0` reset/recenter method is a separate operation and cannot be used to infer ordinary drag behavior. ## Input graph, gains and Home Run `research/Trace-OriginalGalaxyInputScaling.py --verify`. Its independent output `artifacts/galaxy-query-research/constellations/original-input-scaling.json` recovers52 relevant typed nodes from the100-node original `galaxymapcontrols` graph and fingerprints23 native functions. FRES records bind each node to its actual type; the node-local serialized enum and pool number are not treated as a global type enum. The original lowercase DJB2 type hashes, frozen source hashes, camera configuration and callback vtables are verified. `ScaleValue` initializer914680 binds definition10 to its output,18 to its source and event5F31840 to the actual callback8D6420 (descriptor5F33408, vtable512C1C8). Its exact algorithm is `(source+definition20)*definition24`, multiplied by the event float only when definition28 is nonzero, optionally clamped to[-1,1] by definition2C. It contributes only when its absolute value exceeds the output's current absolute value. `TwoInputAxis`9150B0/8D6080 computes positive-minus-negative with optional independent input inversions, using the same max-absolute contribution rule. Default `CopyValue`9129A0/8D74E0 also keeps the larger absolute value and merges button flags/counts; its explicit replace flag is a separate branch. Simultaneous keyboard/mouse sources therefore do not simply sum. The original graph supplies these factors: | Input path | Scale before camera consumer | Multiply input-event float | | --- | --- | --- | | Keyboard/axis pitch and yaw |1 | Yes | | Keyboard/axis XZ translation and crane |0.699999988079071 | Yes | | Keyboard/axis zoom |1 | Yes | | Physical mouse X/Y |0.0020000000949949026 | No | | Wheel |0.0005000000237487257, then invert | No | Camera consumer3B507D0 adds pitch/yaw times config10/14 (1.3), multiplies target distance by `2^(CamDolly*config18)` (3.6), and adds yaw-rotated translation times `(actualDistance+1)*float(.1)*config1C` (8). Translation uses actual yaw/distance, not target yaw/distance. Thus, **conditional on the upstream event float being elapsed seconds**, ordinary keyboard translation is approximately`.56*(actualDistance+1)ly/s`, pitch/yaw1.3rad/s, and log2 distance3.6/s. Frame entry1EB9C0 stores its incoming float unchanged atowner8494. Main phase1EB050 explicitly obtains5F05BC0 and calls virtual18 with8494; its other scaled frame phases do not change this input argument. The event float then passes through input component8F0C00's incoming XMM1, unchanged event publication5F31840, and dispatcher8F53A0/8ECE20 to the callback's XMM2. Its ultimate upstream clock unit, clamps and update cadence are not yet proved. This is intentionally not renamed a verified per-second rate. The graph also does not prove that a PhysicalValue unit equals one WinUI physical pixel or one wheel detent. Production `GalaxyOriginalCameraInput` now ports the graph and camera gains with double arithmetic. Main's independent actual/target camera consumes it for keyboard, physical mouse chords and wheel. The host supplies Stopwatch elapsed seconds with explicit application stall bounds; the16ms motion/input timers remain application scheduling choices. `MouseRawUnitsPerDip` and `MouseRawUnitsPerWheelDelta`, currently1, expose the unverified physical-unit calibration. T applies negative pitch and E positive yaw, and diagonal input is not normalized. The pure helper implements max-absolute source arbitration; the host's separate mouse events and keyboard timer are not claimed to reproduce the original event graph's simultaneous-source scheduling. Button-driven anchored `Zoom(factor)` and the explicit application Reset remain separate tool operations. The local read-only `Custom.4.2.binds` camera section maps T/G, Q/E, W/S, A/D, R/F, Z/X and Home to the named graph actions; all six configured camera axes have no device and zero deadzone. This verifies that local binding file, not universal factory defaults or which preset a future runtime uses. Its non-camera contents were not copied into the evidence artifact. Home is not the missing-saved-pose fallback. The graph's configurable action `GalaxyMapHome` produces `HomeButton`;3B51FE0 binds that signal at input owner110. Owner168 is `UI_Back`, which was independently excluded. With no competing UI-navigation action,3AF5D70 calls5F05DD4 interface552A9E8 virtual80,3B34F40. This reads the valid catalogue compact object from interface2B0 (=componentbase308), decodes real XYZ/32 and invokes camera virtual30:3B55710→3A632C0 with both flags true. It floors only target world Y, sets `targetDistance=min(existingTargetDistance,17.75)`, leaves pitch/yaw targets unchanged and snapshots actual pose for the separate recenter phase. It does not restore saved angles or force a closer camera back out to17.75ly. The navigation-centre shared-pointer writer3B3FD40 also updates dependent slots when they still reference the previous object. Constructor3AC6B00 seeds it from the original initial address, optionally overridden by active-entity3's5F05D3C position component. Activation3B3A450 may replace it from saved selection when raw selection mode9C is3. These original sources do **not** yet prove that the cached centre always equals the player's current system throughout runtime. Production `ReturnCameraHome` accepts an optional actual original-centre snapshot; until supplied, it uses a known current-system catalogue position as an explicit application fallback. It never fabricates missing coordinates. Its target rule is original, but it uses ordinary smoothing until the cinematic timing flags are ported. The application therefore does not claim complete Home-source/transition parity. `3B45BE0` additionally proves the original floor attraction is not an unconditional snap: component2E0/2F0 equal orbit270/280 and configuration50/4C, respectively1ly and.15. With the original mode gates and a real compact candidate, XZ distance below1ly adds `(candidateXZ-targetXZ)*min(1,.15/max(length(inputDelta)*100,.01))`; Y is masked out. Highlight amount is`sqrt(1-XZdistance)`. Native constants100 and.01 and all parameter offsets are retained in the evidence JSON. Constructor3AC7C50 binds the candidate interface440 through global5F05DD4: standard interface552A9E8+B0 isF846B0, returninginterface260=componentbase2B8, distinct fromHome'sbase308 centre. Mode interface458 isglobal5FDB21C, the original3AC8790 input component'sbase58/552B4E0. Its48 getter3B36530 requiresactiveShowGrid(option4) andactualdistance strictlybelowcomponent1A4, initialized30ly. Its20/28 getters3B46AC0/3B424F0 readcomponent19A/19B:3AF5D70 latches these fromPadControlInputActive,MouseControlInputActive,capturestate198 andpreviousinputstate19C. They are not interchangeable witha raw currentpointer-active flag. The exactremaining latch/reset andcandidate-publisher lifetime requireclosure beforeclaimingthehost'spixelcapture/releasepolicyasoriginal. This is an implementation/evidence gap, not an authorization requirement. ## Floor rounding and application integration `3B507D0` writes input into the target pose. When neither camera-craning mode nor crane-axis input is active, it calls `3A437C0` on target focus plus half a world-Y unit. Mask constants `4E327D0` and `4E32830` preserve XZ and floor only Y, yielding `targetY=floor(targetY+.5)`. Actual focus is independently smoothed and is never hard-rounded each frame. Negative half values therefore differ from banker's rounding. `GalaxyOriginalCameraControls` and its focused numerical tests preserve these four-channel rules, distance/pitch clamps, direct yaw delta and target-only height settling. `GalaxyMapView.CameraMotion.cs` accumulates input targets and advances a distinct actual pose. All GPU rendering, hit tests and viewport notifications read that actual pose. External focus changes, explicit reset/recenter, pointer capture loss, lost focus and page unloading cancel old pending motion so it cannot overwrite a new search target. The actual viewport keeps the existing200ms leading/trailing query throttle throughout motion and flushes at convergence. ## Root lens, final matrix and independent display range Run `research/Trace-OriginalGalaxyProjection.py --verify`. Its output `artifacts/galaxy-query-research/constellations/original-projection-binding.json` checks the same pinned image/resource hashes, owning root/component references, constants and native function/decompilation fingerprints. The lens is recovered from its actual typed component; matching field offsets in unrelated classes were excluded. The source FRES record at `17DA90` is `[B42E6888,10,647,540,8768]`, `RootCameraStack`. Its owner is the `RootGameObject` root647. The exact configuration `(540,8768)` has name `Galaxy Map Camera Stack` and stack name `GalaxyMapView`; configuration28 is `56.249000549316406` degrees,2C is1,30 is50000 and byte34 is1. Factory `10866E0` converts28 by the original float `50BD228` into CameraParams0 radians, copies2C/30 into CameraParams4/8 and34 into byteC. It links the11 camera layers so each inherits the previous layer's parameters. These are the baseline root settings, not proof that a later runtime source can never override them. The Galaxy activity factory `10838F0` owns CameraParams atbase30. Its activation `109B200` binds the configured stack/level and registers frame event `5F56248`. Callback `1073F90` copies the inherited CameraParams, writes4=`0.10000000149011612`,8=`500000`, byteD=0 and the actual world pose at40. FOV is inherited. `102FE10`, the independent FixedFOV activity callback, also converts definition degrees into exactly CameraParams0, confirming its angular unit. The final graphics path is now proved, rather than inferred from those parameter names: 1. Root graphics binding `284F190` supplies CameraManager to render-view helper7C8. `281D250` performs the actual named-stack lookup and reads its virtual20 CameraParams, then calls `2874350`. 2. `2874350` writes CameraParams4/8 unchanged into engine Camera234/238. ByteC becomes Camera248 and projection mode244=3 when nonzero (mode5, an explicit matrix override, is preserved). It obtains aspect from display interface `52EC150` virtual40. CameraParams0 goes through that same interface's virtual50 (`2843780`), then `2840320`, and becomes Camera260. 3. `2840320`, in the non-HMD branch with view-flagbit6 clear, returns `2*atan(tan(inputFov/2)*max(1,referenceAspect/actualAspect))`. The exact reference float `52F5F44` is `1.7777777910232544` (16/9). Wider viewports preserve vertical FOV; narrower viewports widen it to preserve the minimum horizontal view. HMD or view-flagbit6 bypasses this compensation. The actual display object is constructed at graphics-root11C8 by `27FE600`, passed as argument3 into `27FA700`, and retained at helper68; it is not an unrelated same-offset interface. 4. Engine Camera constructor `4F0250` initializes lens-shift/crop/alternate-matrix fields. Actual matrix builder `4F3150`, in the ordinary zero-shift uncropped path, sets `m00=1/(aspect*tan(verticalFov/2))`, `m11=1/tan(verticalFov/2)`, `m23=1`, `m33=0`. The original root byteC=1 selects mode3: **infinite reverse depth**, `m22=0`, `m32=near`, giving normalized depth `near/z`. The finite mode0 branch instead gives `near*(far/z-1)/(far-near)`. Thus500000 remains a stored parameter available to other original consumers; it is not a finite far cutoff in the original infinite projection. `4F38D0`, the software-frustum consumer, also branches on infinite mode. Neither the stored far scalar nor an infinite matrix proves the intended native catalogue query/LOD coverage. They must not expand application streaming into the entire galaxy. The renderer has a separate range: constructor `3A06740` sets renderer280 to the actual `GalaxyRenderManager` configuration `(295,14000)` field58=50 multiplied by runtime global `5E9C928`, whose image default is1 but whose runtime value was not observed. `3ACA010` forms near/far fade radii `baseRange*((1-1/3)+t/3)` and `baseRange*((1-1/3)+t/3+.1)`. Actual input owner `3AC8790` exposes t atbase1A8; update `3AF5D70` derives its target from actual distance against a Settings-provided threshold:0 below25%, linear from25% to100%, otherwise1 or1.01 depending on its mode getter. Its transition uses a separate delta-time factor3 and directional clamps, including a decreasing-to1 snap branch. This is a proved draw/fade-frame range, not yet proof of complete native catalogue-query radius. `GalaxyOriginalProjection` ports the recovered ordinary lens and reverse-depth formulas independently of streaming. It uses double arithmetic, not native float bit identity. Production `GalaxyCamera` uses that ordinary aspect-compensated lens and the original fixed near plane. `GalaxyMapView.CameraMotion.cs` uses the same actual focal length for both target and actual distance/scale conversion. Projection and catalogue bounds now have independent contracts: `ProjectionFar=+infinity` and finite `QueryFar=max(near,4*distance)`. The4D query policy remains an explicit application choice, not recovered original catalogue LOD; `Far` is a compatibility alias for QueryFar. `ToViewport`, query bounds/service and streaming use QueryFar explicitly and cannot inherit the infinite projection. `Project` and world segment geometry clip only the original near plane. `ProjectForCatalogue` additionally gates QueryFar; Main's actual-star/LOD/hit lists and star markers use this bounded path so cached stars cannot reappear beyond the query view. Independent nebula/region/route world geometry can use infinite projection. GPU world primitives now use clipZ=near,W=positiveDepth, receiving actual focal/near/ProjectionFar independently from QueryFar; the old finite ratio must never consume infinity. Its7 focused tests cover wide/narrow/HMD-bypass lens behavior, viewport pixel scaling, reverse near-plane depth, absence of a finite original-matrix cutoff beyond the stored far scalar, production near-plane clipping, a6ly near view whose bounded query stays below100ly rather than reaching a26000ly distant star, and a distant point that is geometrically visible but cannot be published/selected as a local catalogue star. The5 input tests cover actual-yaw/distance movement, independent diagonal axes, gain/zoom/mouse paths, max-absolute arbitration, Home target behavior and validation. All252 Galaxy tests passed in the isolated `artifacts/galaxy-original-input-tests/projection-results/test-results.json` run. This is numerical/integration evidence, not live rendering acceptance. Remaining boundaries: runtime parent camera-layer overrides, HMD/view flags/lens shift/capture state, exact native catalogue/LOD radius, input calibration/frame cadence, runtime stop epsilon values, and imported saved-pose/reset semantics. The original constellation graph, compact-coordinate transform and group opacity are recovered; see `galaxy-original-constellation-boundary.md`.