feat(render): retain raw camera poses
This commit is contained in:
@@ -22,6 +22,42 @@
|
|||||||
|
|
||||||
use fparkan_world::OriginalObjectId;
|
use fparkan_world::OriginalObjectId;
|
||||||
|
|
||||||
|
/// A 64-byte transform block returned by the original Terrain camera ABI.
|
||||||
|
///
|
||||||
|
/// The original uses two selector-dependent transform pointers. Their exact
|
||||||
|
/// matrix convention is still under recovery, so words are deliberately kept
|
||||||
|
/// losslessly rather than treated as a renderer-ready matrix. The three
|
||||||
|
/// translation words have been confirmed at indices 3, 7, and 11.
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
pub struct RawCameraTransform {
|
||||||
|
/// The exact 16 little-endian dwords returned by the legacy camera.
|
||||||
|
pub words: [u32; 16],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawCameraTransform {
|
||||||
|
/// Indices of the confirmed X, Y, and Z translation floats.
|
||||||
|
pub const TRANSLATION_WORD_INDICES: [usize; 3] = [3, 7, 11];
|
||||||
|
|
||||||
|
/// Returns the confirmed legacy world position (X, Y, Z).
|
||||||
|
#[must_use]
|
||||||
|
pub fn translation(self) -> [f32; 3] {
|
||||||
|
Self::TRANSLATION_WORD_INDICES.map(|index| f32::from_bits(self.words[index]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Raw camera state observed through the original Terrain camera interface.
|
||||||
|
///
|
||||||
|
/// Selector 0 supplies the currently active transform and selector 2 supplies
|
||||||
|
/// its paired transform. Keeping both lets a later compatibility layer derive
|
||||||
|
/// a view/projection convention without re-reading the legacy process.
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
pub struct RawCameraPose {
|
||||||
|
/// Transform returned by selector 0.
|
||||||
|
pub selector0: RawCameraTransform,
|
||||||
|
/// Transform returned by selector 2.
|
||||||
|
pub selector2: RawCameraTransform,
|
||||||
|
}
|
||||||
|
|
||||||
/// Immutable camera data visible to command generation.
|
/// Immutable camera data visible to command generation.
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct CameraSnapshot {
|
pub struct CameraSnapshot {
|
||||||
@@ -29,6 +65,12 @@ pub struct CameraSnapshot {
|
|||||||
pub view: [f32; 16],
|
pub view: [f32; 16],
|
||||||
/// Projection matrix, row-major.
|
/// Projection matrix, row-major.
|
||||||
pub projection: [f32; 16],
|
pub projection: [f32; 16],
|
||||||
|
/// Optional unconverted source-camera state.
|
||||||
|
///
|
||||||
|
/// This does not alter rendering until the original matrix and projection
|
||||||
|
/// conventions have been recovered; it preserves the ABI boundary for the
|
||||||
|
/// runtime adapter and deterministic captures.
|
||||||
|
pub raw_pose: Option<RawCameraPose>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CameraSnapshot {
|
impl Default for CameraSnapshot {
|
||||||
@@ -36,6 +78,7 @@ impl Default for CameraSnapshot {
|
|||||||
Self {
|
Self {
|
||||||
view: identity_transform(),
|
view: identity_transform(),
|
||||||
projection: identity_transform(),
|
projection: identity_transform(),
|
||||||
|
raw_pose: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -702,6 +745,29 @@ fn identity_transform() -> [f32; 16] {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_camera_pose_preserves_words_and_extracts_confirmed_translation() {
|
||||||
|
let mut active = [0_u32; 16];
|
||||||
|
active[0] = 0x7FC0_0001;
|
||||||
|
active[3] = 491.562_5_f32.to_bits();
|
||||||
|
active[7] = 761.550_8_f32.to_bits();
|
||||||
|
active[11] = 7.361_0_f32.to_bits();
|
||||||
|
let paired = [0xA5A5_5A5A; 16];
|
||||||
|
|
||||||
|
let pose = RawCameraPose {
|
||||||
|
selector0: RawCameraTransform { words: active },
|
||||||
|
selector2: RawCameraTransform { words: paired },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(pose.selector0.words, active);
|
||||||
|
assert_eq!(pose.selector2.words, paired);
|
||||||
|
assert_eq!(
|
||||||
|
pose.selector0.translation(),
|
||||||
|
[491.562_5, 761.550_8, 7.361_0]
|
||||||
|
);
|
||||||
|
assert_eq!(CameraSnapshot::default().raw_pose, None);
|
||||||
|
}
|
||||||
|
|
||||||
fn snapshot_draw(
|
fn snapshot_draw(
|
||||||
id: u64,
|
id: u64,
|
||||||
phase: RenderPhase,
|
phase: RenderPhase,
|
||||||
|
|||||||
@@ -1318,6 +1318,16 @@ is a proven orientation-angle path. Field names, angle order and matrix
|
|||||||
handedness remain unassigned, but a backend-neutral camera pose may now retain
|
handedness remain unassigned, but a backend-neutral camera pose may now retain
|
||||||
the raw affine transform and the exact translation triple without guessing them.
|
the raw affine transform and the exact translation triple without guessing them.
|
||||||
|
|
||||||
|
The render contract now represents that boundary directly. `RawCameraTransform`
|
||||||
|
preserves each selector result as sixteen original `u32` words, so diagnostic
|
||||||
|
data is not rounded or silently assigned a row/column convention. Its only
|
||||||
|
typed accessor reinterprets the proven X/Y/Z words `3/7/11` as IEEE-754
|
||||||
|
floats. `RawCameraPose` retains selector `0` and selector `2` together, and
|
||||||
|
`CameraSnapshot::raw_pose` is optional. The present Vulkan renderer continues
|
||||||
|
to use its existing view/projection matrices: raw pose capture is intentionally
|
||||||
|
not converted into a view matrix until the original transform/projection
|
||||||
|
convention has evidence.
|
||||||
|
|
||||||
A fresh no-input launch of the canonical `iron_3d.exe` did create a responsive
|
A fresh no-input launch of the canonical `iron_3d.exe` did create a responsive
|
||||||
window titled `Parkan. Железная Стратегия`. A read-only probe then requested
|
window titled `Parkan. Железная Стратегия`. A read-only probe then requested
|
||||||
`PROCESS_QUERY_INFORMATION | PROCESS_VM_READ` and attempted to read the known
|
`PROCESS_QUERY_INFORMATION | PROCESS_VM_READ` and attempted to read the known
|
||||||
|
|||||||
Reference in New Issue
Block a user