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
|