File: Camera.h

package info (click to toggle)
spring 104.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 47,512 kB
  • sloc: cpp: 391,093; ansic: 79,943; python: 12,356; java: 12,201; awk: 5,889; sh: 1,826; xml: 655; makefile: 486; perl: 405; php: 211; objc: 194; sed: 2
file content (253 lines) | stat: -rw-r--r-- 7,942 bytes parent folder | download
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef _CAMERA_H
#define _CAMERA_H

#include <vector>

#include "Rendering/GL/myGL.h"
#include "System/float3.h"
#include "System/Matrix44f.h"


class CCamera
{
public:
	struct FrustumLine {
		float base;
		float dir;
		int sign;
		float minz;
		float maxz;
	};

	enum {
		CAMTYPE_PLAYER = 0, // main camera
		CAMTYPE_UWREFL = 1, // used for underwater reflections
		CAMTYPE_SHADOW = 2, // used for shadowmap generation
		CAMTYPE_ENVMAP = 3, // used for cubemap generation
		CAMTYPE_VISCUL = 4, // used for frustum culling
		CAMTYPE_ACTIVE = 5, // pointer to currently active camera
		CAMTYPE_COUNT  = 6,
	};

	enum {
		PROJTYPE_PERSP = 0,
		PROJTYPE_ORTHO = 1,
		PROJTYPE_COUNT = 2,
	};

	enum {
		FRUSTUM_PLANE_LFT = 0,
		FRUSTUM_PLANE_RGT = 1,
		FRUSTUM_PLANE_TOP = 2,
		FRUSTUM_PLANE_BOT = 3,
		FRUSTUM_PLANE_FRN = 4, // near
		FRUSTUM_PLANE_BCK = 5, // far
		FRUSTUM_PLANE_CNT = 6,
	};
	enum {
		FRUSTUM_SIDE_POS = 0,
		FRUSTUM_SIDE_NEG = 1,
	};

	enum {
		MOVE_STATE_FWD = 0, // forward
		MOVE_STATE_BCK = 1, // back
		MOVE_STATE_LFT = 2, // left
		MOVE_STATE_RGT = 3, // right
		MOVE_STATE_UP  = 4, // up
		MOVE_STATE_DWN = 5, // down
		MOVE_STATE_FST = 6, // fast
		MOVE_STATE_SLW = 7, // slow
	};

public:
	CCamera(unsigned int cameraType = CAMTYPE_PLAYER, unsigned int projectionType = PROJTYPE_PERSP);

	void CopyState(const CCamera*);
	void CopyStateReflect(const CCamera*);
	void Update(bool updateDirs = true, bool updateMats = true, bool updatePort = true);

	/// @param fov in degree
	void SetPos(const float3& p) { pos = p; }
	void SetDir(const float3 dir);

	const float3& GetPos() const { return pos; }
	const float3& GetDir() const { return forward; }

	const float3& GetForward() const { return forward; }
	const float3& GetRight() const   { return right; }
	const float3& GetUp() const      { return up; }
	const float3& GetRot() const     { return rot; }

	void SetRot(const float3 r) { UpdateDirsFromRot(rot = r); }
	void SetRotX(const float x) { SetRot(float3(    x, rot.y, rot.z)); }
	void SetRotY(const float y) { SetRot(float3(rot.x,     y, rot.z)); }
	void SetRotZ(const float z) { SetRot(float3(rot.x, rot.y,     z)); }

	float3 CalcPixelDir(int x,int y) const;
	float3 CalcWindowCoordinates(const float3& objPos) const;

	bool InView(const float3& p, float radius = 0) const;
	bool InView(const float3& mins, const float3& maxs) const;

	void GetFrustumSides(float miny, float maxy, float scale, bool negOnly = false);
	void GetFrustumSide(
		const float3& normal,
		const float3& offset,
		float miny,
		float maxy,
		float scale,
		unsigned int side
	);

	void ClipFrustumLines(bool left, const float zmin, const float zmax);
	void SetFrustumScales(const float4 scales) { frustumScales = scales; }

	const std::vector<FrustumLine>& GetPosFrustumSides() const { return frustumLines[FRUSTUM_SIDE_POS]; }
	const std::vector<FrustumLine>& GetNegFrustumSides() const { return frustumLines[FRUSTUM_SIDE_NEG]; }

	void SetClipCtrlMatrix(const CMatrix44f& mat) { clipControlMatrix = mat; }
	void SetProjMatrix(const CMatrix44f& mat) { projectionMatrix = mat; }
	void SetViewMatrix(const CMatrix44f& mat) {
		viewMatrix = mat;

		// FIXME: roll-angle might not be 0
		pos = viewMatrix.GetPos();
		rot = GetRotFromDir(viewMatrix.GetZ());

		forward = viewMatrix.GetZ();
		right   = viewMatrix.GetX();
		up      = viewMatrix.GetY();
	}

	const CMatrix44f& GetViewMatrix() const { return viewMatrix; }
	const CMatrix44f& GetViewMatrixInverse() const { return viewMatrixInverse; }
	const CMatrix44f& GetProjectionMatrix() const { return projectionMatrix; }
	const CMatrix44f& GetProjectionMatrixInverse() const { return projectionMatrixInverse; }
	const CMatrix44f& GetViewProjectionMatrix() const { return viewProjectionMatrix; }
	const CMatrix44f& GetViewProjectionMatrixInverse() const { return viewProjectionMatrixInverse; }
	const CMatrix44f& GetBillBoardMatrix() const { return billboardMatrix; }
	const CMatrix44f& GetClipControlMatrix() const { return clipControlMatrix; }

	void LoadMatrices() const;
	void LoadViewPort() const;
	void UpdateLoadViewPort(int px, int py, int sx, int sy);

	void SetVFOV(const float angle);

	float GetVFOV() const { return fov; }
	float GetHFOV() const;
	float GetHalfFov() const { return halfFov; }
	float GetTanHalfFov() const { return tanHalfFov; }
	float GetLPPScale() const { return lppScale; }

	float3 GetMoveVectorFromState(bool fromKeyState) const;

	void SetMovState(int idx, bool b) { movState[idx] = b; }
	void SetRotState(int idx, bool b) { rotState[idx] = b; }
	const bool* GetMovState() const { return movState; }
	const bool* GetRotState() const { return rotState; }

	static float3 GetRotFromDir(float3 fwd);
	static float3 GetFwdFromRot(const float3 r);
	static float3 GetRgtFromRot(const float3 r);

	float ProjectedDistance(const float3 objPos) const {
		const float3 diff = objPos - GetPos();
		const float dist = diff.dot(GetDir());
		return dist;
	}

	/*
	float ProjectedDistanceShadow(const float3 objPos, const float3 sunDir) const {
		// FIXME: fix it, cap it for shallow shadows?
		const float3 diff = (GetPos() - objPos);
		const float  dot  = diff.dot(sunDir);
		const float3 gap  = diff - (sunDir * dot);
		return (gap.Length());
	}
	*/

	unsigned int GetCamType() const { return camType; }
	unsigned int GetProjType() const { return projType; }
	unsigned int SetCamType(unsigned int ct) { return (camType = ct); }
	unsigned int SetProjType(unsigned int pt) { return (projType = pt); }


	static void InitializeStatic();
	static void SetActiveCamera(unsigned int camType);

	static CCamera* GetCamera(unsigned int camType);
	static CCamera* GetActiveCamera();

	// sets the current active camera, returns the previous
	static CCamera* GetSetActiveCamera(unsigned int camType) {
		CCamera* cam = GetActiveCamera(); SetActiveCamera(camType); return cam;
	}

public:
	void UpdateViewRange();
	void UpdateFrustum();
	void UpdateMatrices(unsigned int vsx, unsigned int vsy, float var);
	void UpdateViewPort(int px, int py, int sx, int sy);

private:
	void gluPerspectiveSpring(const float aspect, const float zn, const float zf);
	void glFrustumSpring(const float l, const float r,  const float b, const float t,  const float zn, const float zf);
	void glOrthoScaledSpring(const float sx, const float sy, const float zn, const float zf);
	void glOrthoSpring(const float l, const float r,  const float b, const float t,  const float zn, const float zf);
	void gluLookAtSpring(const float3&, const float3&, const float3&);

	void UpdateDirsFromRot(const float3 r);

public:
	float3 pos;
	float3 rot;        ///< x = inclination, y = azimuth (to the -z axis!), z = roll
	float3 forward;    ///< local z-axis
	float3 right;      ///< local x-axis
	float3 up;         ///< local y-axis

	float fov;         ///< vertical viewing angle, in degrees
	float halfFov;     ///< half the fov in radians
	float tanHalfFov;  ///< math::tan(halfFov)
	float lppScale;    ///< length-per-pixel scale

public:
	// frustum-volume planes (infinite)
	float3 frustumPlanes[FRUSTUM_PLANE_CNT];
	// xy-scales (for orthographic cameras only), .z := znear, .w := zfar
	float4 frustumScales;

	// Lua-controlled parameters, player-camera only
	float3 posOffset;
	float3 tiltOffset;

	GLint viewport[4];

private:
	CMatrix44f projectionMatrix;
	CMatrix44f projectionMatrixInverse;
	CMatrix44f viewMatrix;
	CMatrix44f viewMatrixInverse;
	CMatrix44f viewProjectionMatrix;
	CMatrix44f viewProjectionMatrixInverse;
	CMatrix44f billboardMatrix;
	CMatrix44f clipControlMatrix;

	// positive sides [0], negative sides [1]
	std::vector<FrustumLine> frustumLines[2];

	// CAMTYPE_*
	unsigned int camType;
	// PROJTYPE_*
	unsigned int projType;

	bool movState[8]; // fwd, back, left, right, up, down, fast, slow
	bool rotState[4]; // unused
};

#define camera (CCamera::GetActiveCamera())
#endif // _CAMERA_H