alandtse / alandtse/devbench

Exact camera-rotation replay: capture forward vector instead of Euler

Đang mở
#2 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
C++
Star
10
Fork
4
Merge trung bình
1 ngày 10 giờ
Pull request đã merge (30 ngày)
17

Mô tả

Follow-up to the camera free-cam replay work (commits bee4716, 89b0800). **Position** driving is exact; **rotation** capture via Euler is not reliable.

## What works now
- `camera freecam {on}` + `camera drive {x,y,z,pitch,yaw}` set the FreeCameraState transform.
- `camera get` reports `camX/Y/Z`, `camPitch/camYaw`, `freeCam`.
- **Position drive is exact at any distance** (verified: drove `(28022,-585,-932)` → read back delta `(0,0,0)`).
- For **A/B benchmarking** the drive is already useful: it's deterministic, so both A and B runs render the identical viewpoint even before absolute rotation is perfect.

## The rotation problem
Driving a pitch/yaw and reading back the camera's world Euler (via `NiMatrix3::ToEulerAnglesXYZ`):

| drove pitch | read | drove yaw | read |
|---|---|---|---|
| -0.4 | +0.400 | -1.0 | -1.000 |
| -0.2 | +0.200 | -0.5 | **+0.500** |
| 0.0 | -0.000 | 0.0 | -0.000 |
| +0.2 | -0.200 | +0.5 | **-0.500** |
| +0.4 | -0.400 | +1.0 | +1.000 |
| +0.6 | -0.600 | +2.0 | +2.000 |

- **Pitch**: exact magnitude, **sign-flipped** — `freecam pitch = -worldEuler.x`. Easy.
- **Yaw**: flips sign at ±0.5 but not ±1/±2 — `ToEulerAnglesXYZ` is **multivalued** (a rotation matrix has several XYZ decompositions; the extractor jumps branches). Capturing yaw this way is unstable and would make the replayed camera **jitter** between samples.

## Plan
1. **Capture the camera forward vector** (unambiguous) from `cameraRoot->world.rotate` instead of Euler angles, per sample.
2. At replay, convert forward → free-cam pitch/yaw: `yaw = atan2(fwd.x, fwd.y)` (confirm Skyrim convention), `pitch = -asin(fwd.z)` (sign per the table above). Nail the convention with a drive→read sweep.
3. Then wire per-sample `camera drive` into BuildScenario/BuildReplaySteps under a `driveCamera` replay flag (the `drive` tool already no-ops when not in free cam, so steps are inert on a normal replay; `driveCamera` prepends `freecam on`, skips `setPov`, appends `freecam off`).
4. Optional: RE `FreeCameraState::GetRotation` (Ghidra) to confirm the exact rotation/`zUpDown` convention rather than fitting empirically.

Until then: position-exact drive is landed; replay does not auto-drive the camera (POV mode + body pose remain the replay path; first-person is exact).

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.