#ifndef NW4R_G3D_CAMERA_H #define NW4R_G3D_CAMERA_H #include #include "nw4r/g3d/res/g3d_rescommon.h" #include "nw4r/math.h" // IWYU pragma: export #include "rvl/MTX.h" // IWYU pragma: export namespace nw4r { namespace g3d { struct CameraData { enum Flag { FLAG_CAM_LOOKAT = (1 << 0), FLAG_CAM_ROTATE = (1 << 1), FLAG_CAM_AIM = (1 << 2), FLAG_CAM_MTX_READY = (1 << 3), FLAG_PROJ_FRUSTUM = (1 << 4), FLAG_PROJ_PERSP = (1 << 5), FLAG_PROJ_ORTHO = (1 << 6), FLAG_PROJ_MTX_READY = (1 << 7), FLAG_VI_ODD_FIELD = (1 << 8), }; math::MTX34 cameraMtx; // at 0x0 math::MTX44 projMtx; // at 0x30 u32 flags; // at 0x70 math::VEC3 cameraPos; // at 0x74 math::VEC3 cameraUp; // at 0x80 math::VEC3 cameraTarget; // at 0x8C math::VEC3 cameraRotate; // at 0x98 f32 cameraTwist; // at 0xA4 GXProjectionType projType; // at 0xA8 f32 projFovy; // at 0xAC f32 projAspect; // at 0xB0 f32 projNear; // at 0xB4 f32 projFar; // at 0xB8 f32 projTop; // at 0xBC f32 projBottom; // at 0xC0 f32 projLeft; // at 0xC4 f32 projRight; // at 0xC8 f32 lightScaleS; // at 0xCC f32 lightScaleT; // at 0xD0 f32 lightTransS; // at 0xD4 f32 lightTransT; // at 0xD8 math::VEC2 viewportOrigin; // at 0xDC math::VEC2 viewportSize; // at 0xE4 f32 viewportNear; // at 0xEC f32 viewportFar; // at 0xF0 u32 scissorX; // at 0xF4 u32 scissorY; // at 0xF8 u32 scissorWidth; // at 0xFC u32 scissorHeight; // at 0x100 s32 scissorOffsetX; // at 0x104 s32 scissorOffsetY; // at 0x108 }; class Camera : public ResCommon { public: enum PostureType { POSTURE_LOOKAT, POSTURE_ROTATE, POSTURE_AIM }; struct PostureInfo { PostureType tp; // at 0x0 math::VEC3 cameraUp; // at 0x4 math::VEC3 cameraTarget; // at 0x10 math::VEC3 cameraRotate; // at 0x1C f32 cameraTwist; // at 0x28 }; public: explicit Camera(CameraData *pData); void Init(); void Init(u16 efbWidth, u16 efbHeight, u16 xfbWidth, u16 xfbHeight, u16 viWidth, u16 viHeight); void SetPosition(f32 x, f32 y, f32 z); void SetPosition(const math::VEC3 &rPos); void SetPosture(const PostureInfo &rInfo); void SetCameraMtxDirectly(const math::MTX34 &rMtx); void SetPerspective(f32 fovy, f32 aspect, f32 near, f32 far); void SetOrtho(f32 top, f32 bottom, f32 left, f32 right, f32 near, f32 far); void SetProjectionMtxDirectly(const math::MTX44 *pMtx); void SetTexMtxParam(f32 lightScaleS, f32 lightScaleT, f32 lightTransS, f32 lightTransT); void SetScissor(u32 x, u32 y, u32 width, u32 height); void SetScissorBoxOffset(s32 ox, s32 oy); void SetViewport(f32 x, f32 y, f32 width, f32 height); void SetViewportZRange(f32 near, f32 far); void GetViewport(f32 *pX, f32 *pY, f32 *pWidth, f32 *pHeight, f32 *pNear, f32 *pFar) const; void Project(math::VEC3 *pSrcPos, const math::VEC3 &worldPos) const; void GetCameraMtx(math::MTX34 *pMtx) const; void GetProjectionMtx(math::MTX44 *pMtx) const; void GetProjectionTexMtx(math::MTX34 *pMtx) const; void GetEnvironmentTexMtx(math::MTX34 *pMtx) const; void GXSetViewport() const; void GXSetProjection() const; void GXSetScissor() const; void GXSetScissorBoxOffset() const; GXProjectionType GetProjectionType() const { return ref().projType; } private: void UpdateCameraMtx() const; void UpdateProjectionMtx() const; }; } // namespace g3d } // namespace nw4r #endif