dungeon_crawler
view prototype/src/camera.cc @ 7:8fb37db44fd8
first person motion
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 17 Aug 2012 14:29:37 +0300 |
parents | 96de911d05d4 |
children | 77c302306206 |
line source
1 #include "opengl.h"
2 #include "camera.h"
4 Camera::Camera()
5 {
6 inval_cache();
7 }
9 Camera::~Camera()
10 {
11 }
13 void Camera::calc_inv_matrix(Matrix4x4 *mat) const
14 {
15 *mat = matrix().inverse();
16 }
18 void Camera::set_glmat(const Matrix4x4 &mat) const
19 {
20 #ifdef SINGLE_PRECISION_MATH
21 if(glLoadTransposeMatrixfARB) {
22 glLoadTransposeMatrixfARB((float*)&mat);
23 } else {
24 Matrix4x4 tmat = mat.transposed();
25 glLoadMatrixf((float*)&tmat);
26 }
27 #else
28 if(glLoadTransposeMatrixdARB) {
29 glLoadTransposeMatrixdARB((double*)&mat);
30 } else {
31 Matrix4x4 tmat = mat.transposed();
32 glLoadMatrixd((double*)&tmat);
33 }
34 #endif
35 }
37 const Matrix4x4 &Camera::matrix() const
38 {
39 if(!mcache.valid) {
40 calc_matrix(&mcache.mat);
41 mcache.valid = true;
42 }
43 return mcache.mat;
44 }
46 const Matrix4x4 &Camera::inv_matrix() const
47 {
48 if(!mcache_inv.valid) {
49 calc_inv_matrix(&mcache_inv.mat);
50 mcache_inv.valid = true;
51 }
52 return mcache_inv.mat;
53 }
55 void Camera::use() const
56 {
57 set_glmat(matrix());
58 }
60 void Camera::use_inverse() const
61 {
62 set_glmat(inv_matrix());
63 }
65 void Camera::input_move(float x, float y, float z)
66 {
67 }
69 void Camera::input_rotate(float x, float y, float z)
70 {
71 }
73 void Camera::input_zoom(float factor)
74 {
75 }
78 // ---- orbit camera ----
80 OrbitCamera::OrbitCamera()
81 {
82 theta = 0.0;
83 phi = 0.0;
84 rad = 10.0;
85 }
87 OrbitCamera::~OrbitCamera()
88 {
89 }
91 void OrbitCamera::calc_matrix(Matrix4x4 *mat) const
92 {
93 mat->reset_identity();
94 mat->translate(Vector3(0, 0, -rad));
95 mat->rotate(Vector3(phi, 0, 0));
96 mat->rotate(Vector3(0, theta, 0));
97 }
99 void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const
100 {
101 mat->reset_identity();
102 mat->rotate(Vector3(0, theta, 0));
103 mat->rotate(Vector3(phi, 0, 0));
104 mat->translate(Vector3(0, 0, -rad));
105 }
107 void OrbitCamera::input_rotate(float x, float y, float z)
108 {
109 theta += y;
110 phi += x;
112 if(phi < -M_PI / 2)
113 phi = -M_PI / 2;
114 if(phi > M_PI)
115 phi = M_PI;
117 inval_cache();
118 }
120 void OrbitCamera::input_zoom(float factor)
121 {
122 rad += factor;
123 if(rad < 0.0)
124 rad = 0.0;
126 inval_cache();
127 }
130 void FpsCamera::calc_matrix(Matrix4x4 *mat) const
131 {
132 mat->reset_identity();
133 /*mat->translate(Vector3(pos.x, pos.y, pos.z));
134 mat->rotate(Vector3(phi, 0, 0));
135 mat->rotate(Vector3(0, theta, 0));*/
136 }
138 void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const
139 {
140 mat->reset_identity();
141 mat->rotate(Vector3(phi, 0, 0));
142 mat->rotate(Vector3(0, theta, 0));
143 mat->translate(Vector3(-pos.x, -pos.y, -pos.z));
144 }
146 void FpsCamera::input_move(float x, float y, float z)
147 {
148 pos.x += x * cos(theta) - z * sin(theta);
149 pos.z += x * sin(theta) + z * cos(theta);
150 pos.y += y;
151 inval_cache();
152 }
156 FlyCamera::FlyCamera()
157 {
158 pos.z = 10.0f;
159 }
161 void FlyCamera::calc_matrix(Matrix4x4 *mat) const
162 {
163 Matrix3x3 rmat = rot.get_rotation_matrix().transposed();
164 Matrix4x4 tmat;
165 tmat.set_translation(pos);
166 *mat = tmat * Matrix4x4(rmat);
167 }
169 /*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const
170 {
171 }*/
173 const Vector3 &FlyCamera::get_position() const
174 {
175 return pos;
176 }
178 const Quaternion &FlyCamera::get_rotation() const
179 {
180 return rot;
181 }
183 void FlyCamera::input_move(float x, float y, float z)
184 {
185 static const Vector3 vfwd(0, 0, 1), vright(1, 0, 0);
187 Vector3 k = vfwd.transformed(rot);
188 Vector3 i = vright.transformed(rot);
189 Vector3 j = cross_product(k, i);
191 pos += i * x + j * y + k * z;
192 inval_cache();
193 }
195 void FlyCamera::input_rotate(float x, float y, float z)
196 {
197 Vector3 axis(x, y, z);
198 float axis_len = axis.length();
199 rot.rotate(axis / axis_len, axis_len);
200 rot.normalize();
202 inval_cache();
203 }