prime/include/MetroidPrime/Cameras/CBallCamera.hpp

291 lines
9.9 KiB
C++

#ifndef _CBALLCAMERA
#define _CBALLCAMERA
#include "types.h"
#include "MetroidPrime/Cameras/CCameraSpline.hpp"
#include "MetroidPrime/Cameras/CGameCamera.hpp"
#include "Kyoto/Math/CMath.hpp"
class CCameraSpring {
public:
CCameraSpring(f32 k, f32 max, f32 tardis)
: x0_k(k), x4_k2Sqrt(CMath::SqrtF(k) * 2.f), x8_max(max), xc_tardis(tardis), x10_dx(0.f) {}
void Reset();
f32 ApplyDistanceSpringNoMax(f32 targetX, f32 curX, f32 dt);
f32 ApplyDistanceSpring(f32 targetX, f32 curX, f32 dt);
private:
f32 x0_k;
f32 x4_k2Sqrt;
f32 x8_max;
f32 xc_tardis;
f32 x10_dx;
};
class CCameraCollider {
public:
CCameraCollider(f32 radius, CVector3f vec, const CCameraSpring& spring, f32 scale)
: x4_radius(radius)
, x8_lastLocalPos(vec)
, x14_localPos(vec)
, x20_scaledWorldPos(vec)
, x2c_lastWorldPos(vec)
, x38_spring(spring)
, x4c_occlusionCount(0)
, x50_scale(scale) {}
virtual ~CCameraCollider() {}
f32 GetRadius() const { return x4_radius; }
// TODO
const CVector3f& GetRealPosition() const { return x2c_lastWorldPos; }
const CVector3f& GetDesiredPosition() const { return x14_localPos; }
const CVector3f& GetLookAtPosition() const { return x20_scaledWorldPos; }
const CVector3f& GetLineOfSight() const;
const CVector3f& GetPosition() const { return x8_lastLocalPos; }
int GetOcclusionCount() const { return x4c_occlusionCount; }
f32 GetScale() const { return x50_scale; }
void SetRadius(f32 radius) { this->x4_radius = radius; }
// TODO
void SetPosition(CVector3f vec) { x8_lastLocalPos = vec; }
void SetRealPosition(CVector3f vec) { x2c_lastWorldPos = vec; }
void SetDesiredPosition(CVector3f vec) { x14_localPos = vec; }
void SetLookAtPosition(CVector3f vec) { x20_scaledWorldPos = vec; }
void SetLineOfSight();
void SetOcclusionCount(int val) { x4c_occlusionCount = val; }
void SetScale(f32 val) { x50_scale = val; }
private:
f32 x4_radius;
CVector3f x8_lastLocalPos; // position
CVector3f x14_localPos; // desired position
CVector3f x20_scaledWorldPos; // look at position
CVector3f x2c_lastWorldPos; // real position
CCameraSpring x38_spring;
int x4c_occlusionCount;
f32 x50_scale;
};
class CBallCamera : public CGameCamera {
public:
enum EBallCameraState {
kBCS_Default,
kBCS_One,
kBCS_Chase,
kBCS_Boost,
kBCS_ToBall,
kBCS_FromBall,
};
enum EBallCameraBehaviour {
kBCB_Default,
kBCB_FreezeLookPosition, // Unused
kBCB_HintBallToCam,
kBCB_HintInitializePosition,
kBCB_HintFixedPosition,
kBCB_HintFixedTransform,
kBCB_PathCameraDesiredPos, // Unused
kBCB_PathCamera,
kBCB_SpindleCamera,
};
enum ESplineState {
kBSS_Invalid,
kBSS_Nav,
kBSS_Arc,
};
CBallCamera(TUniqueId uid, TUniqueId watchedId, const CTransform4f& xf, f32 fovY, f32 nearZ,
f32 farZ, f32 aspect);
// CEntity
~CBallCamera() override;
void Accept(IVisitor& visitor) override;
void Think(f32 dt, CStateManager& mgr) override;
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override;
// CActor
void Render(const CStateManager&) const override;
// CGameCamera
void ProcessInput(const CFinalInput&, CStateManager& mgr) override;
void Reset(const CTransform4f&, CStateManager& mgr) override;
// CBallCamera
void SetupColliders(rstl::vector< CCameraCollider >& out, f32 xMag, f32 zMag, f32 radius,
int count, f32 k, f32 max, f32 startAngle);
void TeleportColliders(rstl::vector< CCameraCollider >& colliderList, CVector3f pos);
void TeleportCamera(const CVector3f& pos, CStateManager& mgr);
void TeleportCamera(const CTransform4f& xf, CStateManager& mgr);
void ResetPosition(CStateManager& mgr);
void ResetToTweaks(CStateManager& mgr);
CVector3f FindDesiredPosition(f32 distance, f32 elevation, CVector3f dir, CStateManager& mgr,
bool fullTest);
void UpdateCollidersDistances(rstl::vector< CCameraCollider >& colliderList, f32 xMag, f32 zMag,
f32 angOffset);
void UpdateColliders(const CTransform4f& xf, rstl::vector< CCameraCollider >& colliderList,
int& idx, int count, float tolerance, const TEntityList& nearList, f32 dt,
CStateManager& mgr);
CVector3f CalculateCollidersCentroid(const rstl::vector< CCameraCollider >& colliderList,
int numObscured) const;
CVector3f ApplyColliders();
int CountObscuredColliders(const rstl::vector< CCameraCollider >& colliderList) const;
CAABox CalculateCollidersBoundingBox(const rstl::vector< CCameraCollider >& colliderList,
const CStateManager&) const;
CVector3f AvoidGeometryFull(const CTransform4f& xf, const TEntityList& nearList, f32 dt,
CStateManager& mgr);
CVector3f AvoidGeometry(const CTransform4f& xf, const TEntityList& nearList, f32 dt,
CStateManager& mgr);
bool DetectCollision(const CVector3f& from, const CVector3f& to, f32 radius, f32& d,
CStateManager& mgr);
const CVector3f& GetLookAtPosition() const { return x1d8_lookPos; }
f32 GetDistance() const { return x190_curMinDistance; }
f32 GetElevation() const { return x1a0_elevation; }
void SetBehaviourType(EBallCameraBehaviour type) { x188_behaviour = type; }
void SetAllowChaseCamera(bool v) { x18c_25_chaseAllowed = v; }
void SetAllowBoostCamera(bool v) { x18c_26_boostAllowed = v; }
// void SetLineOfSightCheck(bool v);
void SetGeometryAvoidance(bool v) { x18c_27_obscureAvoidance = true; }
void SetMinDistance(f32 v) { x194_targetMinDistance = v; }
void SetMaxDistance(f32 v) { x198_maxDistance = v; }
void SetBackwardsDistance(f32 v) { x19c_backwardsDistance = v; }
void SetDistanceSpring(const CCameraSpring& spring) { x214_ballCameraSpring = spring; }
void SetCentroidDistanceSpring(const CCameraSpring& spring) {
x250_ballCameraCentroidDistanceSpring = spring;
}
void SetElevation(f32 v) { x1a0_elevation = v; }
void SetLookAtOffset(CVector3f vec) { x1b4_lookAtOffset = vec; }
void SetChaseLookAtOffset(CVector3f vec) { x410_chaseLookAtOffset = vec; }
void SetWorldOffset(CVector3f vec); // TODO
private:
struct SFailsafeState {
CTransform4f x0_playerXf;
CTransform4f x30_camXf;
CVector3f x60_lookPos;
CVector3f x6c_behindPos;
CVector3f x78_;
CVector3f x84_playerPos;
rstl::vector< CVector3f > x90_splinePoints;
SFailsafeState();
};
struct SUnknown {
SUnknown();
};
EBallCameraBehaviour x188_behaviour;
bool x18c_24_ : 1;
bool x18c_25_chaseAllowed : 1;
bool x18c_26_boostAllowed : 1;
bool x18c_27_obscureAvoidance : 1;
bool x18c_28_volumeCollider : 1;
bool x18c_29_clampAttitude : 1;
bool x18c_30_clampAzimuth : 1;
bool x18c_31_clearLOS : 1;
bool x18d_24_prevClearLOS : 1;
bool x18d_25_avoidGeometryFull : 1;
bool x18d_26_lookAtBall : 1;
bool x18d_27_forceProcessing : 1;
bool x18d_28_obtuseDirection : 1;
bool x18d_29_noElevationInterp : 1;
bool x18d_30_directElevation : 1;
bool x18d_31_overrideLookDir : 1;
bool x18e_24_noElevationVelClamp : 1;
bool x18e_25_noSpline : 1;
bool x18e_26_ : 1;
bool x18e_27_nearbyDoorClosed : 1;
bool x18e_28_nearbyDoorClosing : 1;
f32 x190_curMinDistance;
f32 x194_targetMinDistance;
f32 x198_maxDistance;
f32 x19c_backwardsDistance;
f32 x1a0_elevation;
f32 x1a4_curAnglePerSecond;
f32 x1a8_targetAnglePerSecond;
f32 x1ac_attitudeRange;
f32 x1b0_azimuthRange;
CVector3f x1b4_lookAtOffset;
CVector3f x1c0_lookPosAhead;
CVector3f x1cc_fixedLookPos;
CVector3f x1d8_lookPos;
CTransform4f x1e4_nextLookXf;
CCameraSpring x214_ballCameraSpring;
CCameraSpring x228_ballCameraCentroidSpring;
CCameraSpring x23c_ballCameraLookAtSpring;
CCameraSpring x250_ballCameraCentroidDistanceSpring;
rstl::vector< CCameraCollider > x264_smallColliders;
rstl::vector< CCameraCollider > x274_mediumColliders;
rstl::vector< CCameraCollider > x284_largeColliders;
CVector3f x294_dampedPos;
CVector3f x2a0_smallCentroid;
CVector3f x2ac_mediumCentroid;
CVector3f x2b8_largeCentroid;
int x2c4_smallCollidersObsCount;
int x2c8_mediumCollidersObsCount;
int x2cc_largeCollidersObsCount;
int x2d0_smallColliderIt;
int x2d4_mediumColliderIt;
int x2d8_largeColliderIt;
CVector3f x2dc_prevBallPos;
f32 x2e8_ballVelFlat;
f32 x2ec_maxBallVel;
CVector3f x2f0_ballDelta;
CVector3f x2fc_ballDeltaFlat;
f32 x308_speedFactor;
f32 x30c_speedingTime;
CVector3f x310_idealLookVec;
CVector3f x31c_predictedLookPos;
int x328_avoidGeomCycle;
f32 x32c_colliderMag;
f32 x330_clearColliderThreshold;
CAABox x334_collidersAABB;
f32 x34c_obscuredTime;
CMaterialList x350_obscuringMaterial;
f32 x358_unobscureMag;
CVector3f x35c_splineIntermediatePos;
TUniqueId x368_obscuringObjectId;
ESplineState x36c_splineState;
bool x370_24_reevalSplineEnd : 1;
f32 x374_splineCtrl;
f32 x378_splineCtrlRange;
CCameraSpline x37c_camSpline;
CMaterialList x3c8_collisionExcludeList;
bool x3d0_24_camBehindFloorOrWall : 1;
f32 x3d4_elevInterpTimer;
f32 x3d8_elevInterpStart;
TUniqueId x3dc_tooCloseActorId;
f32 x3e0_tooCloseActorDist;
bool x3e4_pendingFailsafe;
f32 x3e8_;
f32 x3ec_;
f32 x3f0_;
f32 x3f4_;
f32 x3f8_;
f32 x3fc_;
EBallCameraState x400_state;
f32 x404_chaseElevation;
f32 x408_chaseDistance;
f32 x40c_chaseAnglePerSecond;
CVector3f x410_chaseLookAtOffset;
CCameraSpring x41c_ballCameraChaseSpring;
f32 x430_boostElevation;
f32 x434_boostDistance;
f32 x438_boostAnglePerSecond;
CVector3f x43c_boostLookAtOffset;
CCameraSpring x448_ballCameraBoostSpring;
CVector3f x45c_overrideBallToCam;
f32 x468_conservativeDoorCamDistance;
TUniqueId x46c_collisionActorId;
f32 x470_clampVelTimer;
f32 x474_clampVelRange;
uint x478_shortMoveCount;
rstl::single_ptr< SFailsafeState > x47c_failsafeState;
rstl::single_ptr< SUnknown > x480_;
};
CHECK_SIZEOF(CBallCamera, 0x488)
#endif // _CBALLCAMERA