Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 167 vs 168 for /trunk/Source Code/Rendering/Camera/Camera.cpp

Diff revisions: vs.
  @@ -4,139 +4,249 @@
4 4 #include "Hardware/Video/Headers/GFXDevice.h"
5 5 #include "Managers/Headers/SceneManager.h"
6 6
7 - void Camera::SaveCamera(){
8 - _savedVectors[0] = _eye;
9 - _savedVectors[1] = _center;
10 - _savedVectors[2] = _view;
11 - _savedVectors[3] = _left;
12 - _savedVectors[4] = _up;
13 -
14 - _savedFloats[0] = _angleX;
15 - _savedFloats[1] = _angleY;
16 -
7 + Camera::Camera(const CameraType& type) : Resource(),
8 + _saved(false),
9 + _viewMatrixDirty(true),
10 + _mouseSensitivity(1.0f),
11 + _moveSpeedFactor(1.0f),
12 + _turnSpeedFactor(0.1f),
13 + _cameraMoveSpeed(1.0f),
14 + _cameraTurnSpeed(1.0f),
15 + _camIOD(0.5f),
16 + _type(type)
17 + {
18 + _savedFloats[0] = 0.0f;
19 + _savedFloats[1] = 0.0f;
20 + _savedFloats[2] = 0.0f;
21 + _savedFloats[3] = 0.0f;
22 + _eye.set(0.0f, 0.0f, 0.0f);
23 + _xAxis.set(1.0f, 0.0f, 0.0f);
24 + _yAxis.set(0.0f, 1.0f, 0.0f);
25 + _zAxis.set(0.0f, 0.0f, 1.0f);
26 + _viewDir.set(0.0f, 0.0f, -1.0f);
27 + _fixedYawAxis.set(WORLD_Y_AXIS);
28 + _accumPitchDegrees = 0.0f;
29 + _orientation.identity();
30 + _viewMatrix.identity();
31 + _reflectedViewMatrix.identity();
32 + _yawFixed = false;
33 + }
34 +
35 + void Camera::saveCamera(){
36 + _savedVectors[0] = _eye;
37 + _savedVectors[1] = _fixedYawAxis;
38 + _savedFloats[0] = _camIOD;
39 + _savedFloats[1] = _moveSpeedFactor;
40 + _savedFloats[2] = _turnSpeedFactor;
41 + _savedFloats[3] = _mouseSensitivity;
42 + _savedOrientation = _orientation;
43 + _savedYawState = _yawFixed;
17 44 _saved = true;
18 45 }
19 46
20 - void Camera::RestoreCamera() {
47 + void Camera::restoreCamera() {
21 48 if(_saved) {
22 - _eye = _savedVectors[0];
23 - _center = _savedVectors[1];
24 - _view = _savedVectors[2];
25 - _left = _savedVectors[3];
26 - _up = _savedVectors[4];
27 -
28 - _angleX = _savedFloats[0];
29 - _angleY = _savedFloats[1];
49 + _eye = _savedVectors[0];
50 + _fixedYawAxis = _savedVectors[1];
51 + _camIOD = _savedFloats[0];
52 + _moveSpeedFactor = _savedFloats[1];
53 + _turnSpeedFactor = _savedFloats[2];
54 + _mouseSensitivity = _savedFloats[3];
55 + _orientation = _savedOrientation;
56 + _yawFixed = _savedYawState;
57 + updateViewMatrix();
58 + _saved = false;
30 59 }
31 -
32 - _saved = false;
33 60 }
34 61
35 - Camera::Camera(CameraType type) : Resource(),
36 - _saved(false),
37 - _angleX(3.0f),
38 - _angleY(M_PI/2),
39 - _type(type)
40 - {
41 - _up = vec3<F32>(0.0f, 1.0f, 0.0f);
42 - _eye = vec3<F32>(0.0f, 0.0f, 0.0f);
43 - _frameSpeedFactor = 1.0f;
44 - _saved = false;
45 - Refresh();
46 - }
47 -
48 - void Camera::Refresh() {
49 - _frameSpeedFactor = FRAME_SPEED_FACTOR;
50 - switch(_type) {
51 - case FREE_FLY:
52 - _view.x = cosf(_angleX) * sinf(_angleY);
53 - _view.y = cosf(_angleY);
54 - _view.z = sinf(_angleX) * sinf(_angleY);
55 - _center = _eye + _view;
56 - _left.cross(_up, _view);
57 - _left.normalize();
58 - break;
59 -
60 - case SCRIPTED:
61 - _view = _center - _eye;
62 - _view.normalize();
63 - _left.cross(_up, _view);
64 - _left.normalize();
65 - break;
62 + void Camera::tick(U32 elapsedTime) {
63 + //static bool oddFrame = true;
64 + _cameraMoveSpeed = FRAME_SPEED_FACTOR * _moveSpeedFactor;
65 + _cameraTurnSpeed = FRAME_SPEED_FACTOR * _turnSpeedFactor;
66 + //if(oddFrame)
67 + _orientation.normalize();
68 + //oddFrame = !oddFrame;
69 + }
70 +
71 + void Camera::setGlobalRotation(F32 yaw, F32 pitch, F32 roll) {
72 + Quaternion<F32> pitchRot(WORLD_X_AXIS, -pitch);
73 + Quaternion<F32> yawRot(WORLD_Y_AXIS, -yaw);
74 + if(!IS_ZERO(roll)){
75 + Quaternion<F32> rollRot;
76 + rollRot.fromAxisAngle(WORLD_Z_AXIS, -roll);
77 + setRotation(yawRot * pitchRot * rollRot);
78 + }else{
79 + setRotation(yawRot * pitchRot);
66 80 }
67 81 }
68 82
69 - void Camera::MoveForward(F32 factor) {
70 - _eye += (_view * factor) * _frameSpeedFactor;
71 - Refresh();
83 + void Camera::rotate(const Quaternion<F32>& q) {
84 + if(_type == FIRST_PERSON){
85 + vec3<F32> euler;
86 + q.getEuler(&euler);
87 + rotate(euler.yaw, euler.pitch,euler.roll);
88 + }else{
89 + Quaternion<F32> rot = q;
90 + rot.normalize();
91 + _orientation = rot * _orientation;
92 + }
93 +
94 + _viewMatrixDirty = true;
72 95 }
73 96
74 - void Camera::TranslateForward(F32 factor) {
75 - _eye += (_view * factor) * FRAME_SPEED_FACTOR;
76 - Refresh();
97 + void Camera::rotate(F32 yaw, F32 pitch, F32 roll) {
98 +
99 + yaw = -yaw * _cameraTurnSpeed;
100 + pitch = -pitch * _cameraTurnSpeed;
101 + roll = -roll * _cameraTurnSpeed;
102 +
103 + if(_type == FIRST_PERSON){
104 + _accumPitchDegrees += pitch;
105 +
106 + if (_accumPitchDegrees > 90.0f){
107 + pitch = 90.0f - (_accumPitchDegrees - pitch);
108 + _accumPitchDegrees = 90.0f;
109 + }
110 +
111 + if (_accumPitchDegrees < -90.0f){
112 + pitch = -90.0f - (_accumPitchDegrees - pitch);
113 + _accumPitchDegrees = -90.0f;
114 + }
115 +
116 + Quaternion<F32> rot;
117 +
118 + // Rotate camera about the world y axis.
119 + // Note the order the quaternions are multiplied. That is important!
120 + if (yaw != 0.0f){
121 + rot.fromAxisAngle(WORLD_Y_AXIS, yaw);
122 + _orientation = rot * _orientation;
123 + }
124 +
125 + // Rotate camera about its local x axis.
126 + // Note the order the quaternions are multiplied. That is important!
127 + if (pitch != 0.0f){
128 + rot.fromAxisAngle(WORLD_X_AXIS, pitch);
129 + _orientation = _orientation * rot;
130 + }
131 + }else{
132 + _orientation *= Quaternion<F32>(pitch,yaw,roll);
133 + }
134 +
135 + _viewMatrixDirty = true;
77 136 }
78 137
79 - void Camera::MoveStrafe(F32 factor) {
80 - _eye += (_left * factor) * _frameSpeedFactor;
81 - Refresh();
138 + void Camera::move(F32 dx, F32 dy, F32 dz) {
139 +
140 + _eye += _xAxis * dx * _cameraMoveSpeed;
141 + _eye += WORLD_Y_AXIS * dy * _cameraMoveSpeed;
142 +
143 + if (_type == FIRST_PERSON){
144 + // Calculate the forward direction. Can't just use the camera's local
145 + // z axis as doing so will cause the camera to move more slowly as the
146 + // camera's view approaches 90 degrees straight up and down.
147 + vec3<F32> forward;
148 + forward.cross(WORLD_Y_AXIS, _xAxis);
149 + forward.normalize();
150 + _eye += forward * dz * _cameraMoveSpeed;
151 + }else{
152 + _eye += _viewDir * dz * _cameraMoveSpeed;
153 + }
154 +
155 + _viewMatrixDirty = true;
82 156 }
83 157
84 - void Camera::TranslateStrafe(F32 factor) {
85 - _eye += (_left * factor) * _frameSpeedFactor;
86 - Refresh();
158 + void Camera::lookAt(const vec3<F32>& eye, const vec3<F32>& target, const vec3<F32>& up) {
159 + _eye = eye;
160 +
161 + _zAxis = eye - target;
162 + _zAxis.normalize();
163 + _xAxis.cross(up, _zAxis);
164 + _xAxis.normalize();
165 + _yAxis.cross(_zAxis, _xAxis);
166 + _yAxis.normalize();
167 +
168 + _viewDir = -_zAxis;
169 +
170 + _viewMatrix.m[0][0] = _xAxis.x;
171 + _viewMatrix.m[1][0] = _xAxis.y;
172 + _viewMatrix.m[2][0] = _xAxis.z;
173 + _viewMatrix.m[3][0] = -_xAxis.dot(eye);
174 +
175 + _viewMatrix.m[0][1] = _yAxis.x;
176 + _viewMatrix.m[1][1] = _yAxis.y;
177 + _viewMatrix.m[2][1] = _yAxis.z;
178 + _viewMatrix.m[3][1] = -_yAxis.dot(eye);
179 +
180 + _viewMatrix.m[0][2] = _zAxis.x;
181 + _viewMatrix.m[1][2] = _zAxis.y;
182 + _viewMatrix.m[2][2] = _zAxis.z;
183 + _viewMatrix.m[3][2] = -_zAxis.dot(eye);
184 +
185 + // Extract the pitch angle from the view matrix.
186 + _accumPitchDegrees = DEGREES(asinf(_zAxis.y));
187 +
188 + _orientation.fromMatrix(_viewMatrix);
189 +
190 + _viewMatrixDirty = false;
87 191 }
88 192
89 - void Camera::MoveAnaglyph(F32 factor){
90 - _eye += (_left * factor) * _frameSpeedFactor;
91 - _center += (_left * factor) * _frameSpeedFactor;
193 + void Camera::renderAnaglyph(bool rightEye){
194 + GFX_DEVICE.setAnaglyphFrustum(_camIOD,rightEye);
195 + if(rightEye) _eye.x += _camIOD/2;
196 + else _eye.x -= _camIOD/2;
197 +
198 + _viewMatrixDirty = true;
199 +
200 + renderLookAt();
92 201 }
93 202
94 203 ///Tell the rendering API to set up our desired PoV
95 - void Camera::RenderLookAt(bool invertx, bool inverty, F32 planey) {
96 - ///Tell the Rendering API to draw from our desired PoV
97 - if(inverty){
98 - ///If we need to flip the camera upside down (ex: for reflections)
99 - GFX_DEVICE.lookAt(vec3<F32>(_eye.x, planey-_eye.y, _eye.z),
100 - vec3<F32>(_center.x,planey-_center.y,_center.z),
101 - vec3<F32>(-_up.x, -_up.y, -_up.z),
102 - invertx);
103 - }else{
104 - GFX_DEVICE.lookAt(_eye,_center,_up);
105 - }
106 - ///Extract the frustum associated with our current PoV
204 + void Camera::renderLookAt(bool invertX) {
205 + updateViewMatrix();
206 +
207 + if(invertX) _viewMatrix.scale(vec3<F32>(-1,1,1));
208 + //Tell the Rendering API to draw from our desired PoV
209 + GFX_DEVICE.lookAt(_viewMatrix, _viewDir);
210 + //Extract the frustum associated with our current PoV
107 211 Frustum::getInstance().Extract(_eye);
108 - ///Inform all listeners of a new event
212 + //Inform all listeners of a new event
109 213 updateListeners();
110 214 }
111 215
112 - void Camera::RenderLookAtToCubeMap(const vec3<F32>& eye, U8 nFace){
113 - assert(nFace < 6);
114 - ///Get the center and up vectors for each cube face
115 - vec3<F32> TabCenter[6] = { vec3<F32>(eye.x+1.0f, eye.y, eye.z),
116 - vec3<F32>(eye.x-1.0f, eye.y, eye.z),
117 - vec3<F32>(eye.x, eye.y+1.0f, eye.z),
118 - vec3<F32>(eye.x, eye.y-1.0f, eye.z),
119 - vec3<F32>(eye.x, eye.y, eye.z+1.0f),
120 - vec3<F32>(eye.x, eye.y, eye.z-1.0f) };
121 -
122 - static vec3<F32> TabUp[6] = { vec3<F32>(0.0f, -1.0f, 0.0f),
123 - vec3<F32>(0.0f, -1.0f, 0.0f),
124 -
125 - vec3<F32>(0.0f, 0.0f, 1.0f),
126 - vec3<F32>(0.0f, 0.0f, -1.0f),
127 -
128 - vec3<F32>(0.0f, -1.0f, 0.0f),
129 - vec3<F32>(0.0f, -1.0f, 0.0f) };
130 - ///Set our eye position
131 - setEye( eye );
132 - ///Set our Rendering API to render the desired face
133 - GFX_DEVICE.lookAt(eye,TabCenter[nFace],TabUp[nFace]);
134 - ///Extract the view frustum associated with this face
135 - Frustum::getInstance().Extract(eye);
136 - ///Inform all listeners of a new event
216 + void Camera::renderLookAtReflected(const Plane<F32>& reflectionPlane, bool invertX){
217 + updateViewMatrix();
218 +
219 + _reflectedViewMatrix.reflect(reflectionPlane);
220 + if(invertX) _reflectedViewMatrix.scale(vec3<F32>(-1,1,1));
221 + GFX_DEVICE.lookAt(_reflectedViewMatrix * _viewMatrix, _reflectedViewMatrix * _viewDir);
222 + //Extract the frustum associated with our current PoV
223 + Frustum::getInstance().Extract(_reflectedViewMatrix * _eye);
224 + //Inform all listeners of a new event
137 225 updateListeners();
138 226 }
139 227
228 + void Camera::updateViewMatrix(){
229 +
230 + if(!_viewMatrixDirty)
231 + return;
232 +
233 + // Reconstruct the view matrix.
234 + _viewMatrix = _orientation.getMatrix();
235 +
236 + _xAxis.set(_viewMatrix.m[0][0], _viewMatrix.m[1][0], _viewMatrix.m[2][0]);
237 + _yAxis.set(_viewMatrix.m[0][1], _viewMatrix.m[1][1], _viewMatrix.m[2][1]);
238 + _zAxis.set(_viewMatrix.m[0][2], _viewMatrix.m[1][2], _viewMatrix.m[2][2]);
239 + _viewDir = -_zAxis;
240 + _target = _viewDir + _eye;
241 +
242 + _viewMatrix.m[3][0] = -_xAxis.dot(_eye);
243 + _viewMatrix.m[3][1] = -_yAxis.dot(_eye);
244 + _viewMatrix.m[3][2] = -_zAxis.dot(_eye);
245 + _orientation.getEuler(&_euler,true);
246 +
247 + _viewMatrixDirty = false;
248 + }
249 +
140 250 void Camera::updateListeners(){
141 251 for_each(boost::function0<void > listener, _listeners){
142 252 listener();