using System;
using System.Numerics;
namespace AcDream.App.Rendering;
///
/// Fixed camera for the paperdoll mini-scene — retail-exact, ported from the gmPaperDollUI viewport
/// setup (decomp 0x004a5a39–0x004a5a69). The viewport (element 0x100001d5) is configured by
/// UIElement_Viewport::SetCamera(position, direction) with:
///
/// - position = (0.12, −2.4, 0.88) [hex 0x3df5c28f, 0xc019999a, 0x3f6147ae]
/// - direction = (0, 0, 0) ⇒ CreatureMode::SetCameraDirection resets the view frame to
/// IDENTITY (euler_set_rotate(0,0,0) then rotate(0,0,0)), so the camera looks
/// straight down +Y with +Z up — NO yaw, NO pitch.
///
/// The doll is framed purely by camera POSITION + FOV, NOT by aiming at the body: at distance 2.4 with
/// a π/4 (45°) vertical FOV the visible vertical band is z≈[−0.11, 1.87], which covers the whole ~1.6 m
/// figure even though the model origin sits at the FEET (z=0). FOV π/4 is CreatureMode's default
/// m_fFOVRadians (ctor 0x004543cf, hex 0x3f490fdb); default ambient is (0.3,0.3,0.3); the
/// paperdoll uses UseSharpMode (not SmartboxFOV) so Render::SetFOVRad(m_fFOVRadians) applies.
///
/// An earlier hand-tune aimed the camera at mid-body to "fit the figure", which introduced a
/// spurious yaw (Target.x ≠ Eye.x) that rotated the view and turned the doll's face away from the
/// viewer. This restores retail's zero-yaw frame, where full-body framing comes from the eye height +
/// FOV, not from aiming.
///
/// Uses the same /
/// convention as so the doll's triangle winding + back-face culling match the
/// world render pass. AC up-axis = +Z.
///
public sealed class DollCamera : ICamera
{
// Retail paperdoll camera origin (decomp 0x004a5a51–0x004a5a61).
private static readonly Vector3 Eye = new(0.12f, -2.4f, 0.88f);
// Identity view orientation ⇒ look straight down +Y (no yaw/pitch). Target = Eye + (0,1,0).
private static readonly Vector3 Target = new(0.12f, -1.4f, 0.88f);
private static readonly Vector3 Up = Vector3.UnitZ; // AC up-axis = +Z, same as ChaseCamera
/// Vertical field of view — retail CreatureMode default m_fFOVRadians = π/4 (45°).
public float FovRadians { get; set; } = MathF.PI / 4f;
public float Near { get; set; } = 0.1f; // same near plane as ChaseCamera / retail znear
public float Far { get; set; } = 50f; // doll scene is small; 50 m is ample
public float Aspect { get; set; } = 1f;
///
public Matrix4x4 View =>
Matrix4x4.CreateLookAt(Eye, Target, Up);
///
public Matrix4x4 Projection =>
Matrix4x4.CreatePerspectiveFieldOfView(FovRadians, Aspect <= 0f ? 1f : Aspect, Near, Far);
}