-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgravity_cam_ctrl.h
More file actions
116 lines (96 loc) · 2.41 KB
/
gravity_cam_ctrl.h
File metadata and controls
116 lines (96 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#pragma once
#include <memory>
#include "SM64DS_PI.h"
#include "gravity_actor_extension.h"
#include "gravity_field.h"
#include "gravity_math.h"
class CamCtrl
{
public:
enum class Type : u8
{
VANILLA,
PLANET_CAM,
FIRST_PERSON,
CUTSCENE
};
private:
Quaternion rotation = 1;
Quaternion savedQuat = 1;
UnitSmoothInterp interp;
std::unique_ptr<CamCtrl> prev;
Type type;
static std::unique_ptr<CamCtrl> latestCam;
static CamCtrl* activeCam;
struct MinimapInterp
{
s16 angle;
bool vanillaCamActive;
bool targetReached;
bool initialized;
}
static inline constinit minimapInterp = {};
static std::unique_ptr<CamCtrl> Spawn(
std::unique_ptr<CamCtrl> prev,
const GravityField& field,
const Camera& cam,
Player& player);
static void UpdatePaused(Camera& cam, const Player& player);
static void CheckFieldChange(const Camera& cam, Player& player);
static void Prune();
void Activate();
const Quaternion& GetTransformForInterp(Matrix4x3& res, Camera& cam, Player& player);
protected:
const GravityField* field;
// Returns whether the camera is still valid
virtual bool CalculateTransform(Matrix4x3& res, Camera& cam, Player& player)
{
res.Linear() = cam.camMat.Linear().Transpose();
res.c3 = cam.pos;
return true;
}
virtual bool CanChangeField(const Player& player, const GravityField& newField) const
{
return newField.IsTrivial();
}
bool TryChangeField(const Player& player, const GravityField& newField)
{
if (CanChangeField(player, newField))
{
field = &newField;
return true;
}
return false;
}
bool IsActive() const { return this == activeCam; }
public:
virtual void AfterCamBehavior(Camera& cam) const {}
virtual const s16* GetPlanetCamSettings() const { return nullptr; }
[[gnu::target("thumb")]]
CamCtrl(
std::unique_ptr<CamCtrl> prev,
const GravityField& field,
Type type
):
rotation(prev ? prev->savedQuat.Conjugate()*prev->rotation : Quaternion(1)),
prev(std::move(prev)),
type(type),
field(&field)
{}
virtual ~CamCtrl() = default;
static void Update(Camera& cam, Player& player);
static const CamCtrl* GetActiveCam() { return activeCam; }
static bool IsVanillaCamActive();
static s16 GetMinimapAngle(const Camera& cam);
static void Cleanup()
{
minimapInterp.initialized = false;
latestCam.reset();
activeCam = nullptr;
}
static bool IsInterpolating()
{
return latestCam && latestCam->prev;
}
Type GetType() const { return type; }
};