00001
00007 #include "Camera.h"
00008
00009 Camera::Camera() {
00010
00011
00012 m_headingDegrees = 0.0f;
00013 m_pitchDegrees = 0.0f;
00014
00015
00016 m_shakeTime = 0.0f;
00017 m_shakeIntensity = 0.0f;
00018 isMoved = false;
00019 }
00020
00021 Camera::~Camera() {
00022 }
00023
00024 void Camera::setPrespective(float dTime, bool movePos) {
00025 if (!isMoved) {
00026 float matrix[16];
00027 Quaternion q;
00028
00029 m_pitch.createFromAxisAngle(1.0f, 0.0f, 0.0f, m_pitchDegrees);
00030 m_heading.createFromAxisAngle(0.0f, 1.0f, 0.0f, m_headingDegrees);
00031
00032 q = m_pitch * m_heading;
00033 q.createMatrix(matrix);
00034
00035 glMultMatrixf(matrix);
00036
00037 m_pitch.createMatrix(matrix);
00038 m_direction.y = matrix[9];
00039
00040 m_strafe.y = matrix[1];
00041 m_up.y = matrix[5];
00042
00043 q = m_heading*m_pitch;
00044 q.createMatrix(matrix);
00045 m_direction.x = matrix[8];
00046 m_direction.z = matrix[10];
00047
00048 m_strafe.x = matrix[0];
00049 m_strafe.z = matrix[2];
00050
00051 m_up.x = matrix[4];
00052 m_up.z = matrix[6];
00053
00054 isMoved = true;
00055 }
00056
00057 if (movePos)
00058 setPos(dTime);
00059 }
00060
00061 void Camera::setPos(float dTime) {
00062 if (m_shakeTime > 0.0f) {
00063 Vec3 offset;
00064 offset.x += sinf(m_shakeTime*m_shakeSpeed)*cosf(m_shakeTime*m_shakeSpeed)*m_shakeIntensity*m_shakeTime;
00065 offset.y += cosf(m_shakeTime*m_shakeSpeed)*m_shakeIntensity*m_shakeTime;
00066 offset.z += cosf(m_shakeTime*m_shakeSpeed)*m_shakeIntensity*m_shakeTime;
00067 m_shakeTime -= dTime;
00068
00069 glTranslatef(-m_position.x+offset.x, -m_position.y+offset.y, m_position.z+offset.z);
00070 }
00071 else
00072 glTranslatef(-m_position.x, -m_position.y, m_position.z);
00073
00074 isMoved = false;
00075 }
00076
00077 void Camera::setProjection(float angle, int width, int height, float n, float f) {
00078 glMatrixMode(GL_PROJECTION);
00079 glLoadIdentity();
00080 gluPerspective (angle, (GLfloat)(width)/(GLfloat)(height), n, f);
00081 glMatrixMode(GL_MODELVIEW);
00082
00083 }
00084
00085 void Camera::changePitch(float degrees) {
00086 m_pitchDegrees += degrees;
00087
00088 if (m_pitchDegrees > 360.0f)
00089 m_pitchDegrees -= 360.0f;
00090 else if (m_pitchDegrees < -360.0f)
00091 m_pitchDegrees += 360.0f;
00092 }
00093
00094 void Camera::setPitch(float degrees) {
00095 m_pitchDegrees = degrees;
00096 }
00097
00098 void Camera::changeHeading(float degrees) {
00099 if (m_pitchDegrees > 90.0f && m_pitchDegrees < 270.0f || (m_pitchDegrees < -90.0f && m_pitchDegrees > -270.0f))
00100 m_headingDegrees -=degrees;
00101 else
00102 m_headingDegrees += degrees;
00103
00104 if (m_headingDegrees > 360.0f)
00105 m_headingDegrees -= 360.0f;
00106 else if (m_headingDegrees < -360.0f)
00107 m_headingDegrees += 360.0f;
00108 }
00109
00110 void Camera::setHeading(float degrees) {
00111 m_headingDegrees = degrees;
00112 }
00113
00114
00115 void Camera::moveForward(float val) {
00116 m_position += m_direction*val;
00117 }
00118
00119 void Camera::strafeRight(float val) {
00120 m_position += m_strafe*val;
00121 }
00122
00123 void Camera::moveUp(float val) {
00124 m_position += m_up*val;
00125 }
00126
00127 void Camera::setPosition(Vec3 position) {
00128 m_position = Vec3(position.x, position.y, -position.z);
00129 }
00130
00131 Vec3 Camera::getPosition() {
00132 return Vec3(m_position.x, m_position.y, -m_position.z);
00133 }
00134
00135 void Camera::shake(float time, float speed, float intensity) {
00136 m_shakeTime += time;
00137 m_shakeSpeed = speed;
00138 m_shakeIntensity = intensity;
00139 }
00140
00141 void Camera::updateFrustum() {
00142 GLfloat clip[16];
00143 GLfloat proj[16];
00144 GLfloat modl[16];
00145 GLfloat t;
00146
00147
00148 glGetFloatv( GL_PROJECTION_MATRIX, proj );
00149
00150
00151 glGetFloatv( GL_MODELVIEW_MATRIX, modl );
00152
00153
00154
00155
00156 clip[ 0] = modl[ 0] * proj[ 0];
00157 clip[ 1] = modl[ 1] * proj[ 5];
00158 clip[ 2] = modl[ 2] * proj[10] + modl[ 3] * proj[14];
00159 clip[ 3] = modl[ 2] * proj[11];
00160
00161 clip[ 4] = modl[ 4] * proj[ 0];
00162 clip[ 5] = modl[ 5] * proj[ 5];
00163 clip[ 6] = modl[ 6] * proj[10] + modl[ 7] * proj[14];
00164 clip[ 7] = modl[ 6] * proj[11];
00165
00166 clip[ 8] = modl[ 8] * proj[ 0];
00167 clip[ 9] = modl[ 9] * proj[ 5];
00168 clip[10] = modl[10] * proj[10] + modl[11] * proj[14];
00169 clip[11] = modl[10] * proj[11];
00170
00171 clip[12] = modl[12] * proj[ 0];
00172 clip[13] = modl[13] * proj[ 5];
00173 clip[14] = modl[14] * proj[10] + modl[15] * proj[14];
00174 clip[15] = modl[14] * proj[11];
00175
00176
00177 m_Frustum[0][0] = clip[ 3] - clip[ 0];
00178 m_Frustum[0][1] = clip[ 7] - clip[ 4];
00179 m_Frustum[0][2] = clip[11] - clip[ 8];
00180 m_Frustum[0][3] = clip[15] - clip[12];
00181
00182
00183 t = GLfloat(sqrt( m_Frustum[0][0] * m_Frustum[0][0] + m_Frustum[0][1] * m_Frustum[0][1]
00184 + m_Frustum[0][2] * m_Frustum[0][2] ));
00185 m_Frustum[0][0] /= t;
00186 m_Frustum[0][1] /= t;
00187 m_Frustum[0][2] /= t;
00188 m_Frustum[0][3] /= t;
00189
00190
00191 m_Frustum[1][0] = clip[ 3] + clip[ 0];
00192 m_Frustum[1][1] = clip[ 7] + clip[ 4];
00193 m_Frustum[1][2] = clip[11] + clip[ 8];
00194 m_Frustum[1][3] = clip[15] + clip[12];
00195
00196
00197 t = GLfloat(sqrt( m_Frustum[1][0] * m_Frustum[1][0] + m_Frustum[1][1] * m_Frustum[1][1]
00198 + m_Frustum[1][2] * m_Frustum[1][2] ));
00199 m_Frustum[1][0] /= t;
00200 m_Frustum[1][1] /= t;
00201 m_Frustum[1][2] /= t;
00202 m_Frustum[1][3] /= t;
00203
00204
00205 m_Frustum[2][0] = clip[ 3] + clip[ 1];
00206 m_Frustum[2][1] = clip[ 7] + clip[ 5];
00207 m_Frustum[2][2] = clip[11] + clip[ 9];
00208 m_Frustum[2][3] = clip[15] + clip[13];
00209
00210
00211 t = GLfloat(sqrt( m_Frustum[2][0] * m_Frustum[2][0] + m_Frustum[2][1] * m_Frustum[2][1]
00212 + m_Frustum[2][2] * m_Frustum[2][2] ));
00213 m_Frustum[2][0] /= t;
00214 m_Frustum[2][1] /= t;
00215 m_Frustum[2][2] /= t;
00216 m_Frustum[2][3] /= t;
00217
00218
00219 m_Frustum[3][0] = clip[ 3] - clip[ 1];
00220 m_Frustum[3][1] = clip[ 7] - clip[ 5];
00221 m_Frustum[3][2] = clip[11] - clip[ 9];
00222 m_Frustum[3][3] = clip[15] - clip[13];
00223
00224
00225 t = GLfloat(sqrt( m_Frustum[3][0] * m_Frustum[3][0] + m_Frustum[3][1] * m_Frustum[3][1]
00226 + m_Frustum[3][2] * m_Frustum[3][2] ));
00227 m_Frustum[3][0] /= t;
00228 m_Frustum[3][1] /= t;
00229 m_Frustum[3][2] /= t;
00230 m_Frustum[3][3] /= t;
00231
00232
00233 m_Frustum[4][0] = clip[ 3] - clip[ 2];
00234 m_Frustum[4][1] = clip[ 7] - clip[ 6];
00235 m_Frustum[4][2] = clip[11] - clip[10];
00236 m_Frustum[4][3] = clip[15] - clip[14];
00237
00238
00239 t = GLfloat(sqrt( m_Frustum[4][0] * m_Frustum[4][0] + m_Frustum[4][1] * m_Frustum[4][1]
00240 + m_Frustum[4][2] * m_Frustum[4][2] ));
00241 m_Frustum[4][0] /= t;
00242 m_Frustum[4][1] /= t;
00243 m_Frustum[4][2] /= t;
00244 m_Frustum[4][3] /= t;
00245
00246
00247 m_Frustum[5][0] = clip[ 3] + clip[ 2];
00248 m_Frustum[5][1] = clip[ 7] + clip[ 6];
00249 m_Frustum[5][2] = clip[11] + clip[10];
00250 m_Frustum[5][3] = clip[15] + clip[14];
00251
00252
00253 t = GLfloat(sqrt( m_Frustum[5][0] * m_Frustum[5][0] + m_Frustum[5][1] * m_Frustum[5][1]
00254 + m_Frustum[5][2] * m_Frustum[5][2] ));
00255 m_Frustum[5][0] /= t;
00256 m_Frustum[5][1] /= t;
00257 m_Frustum[5][2] /= t;
00258 m_Frustum[5][3] /= t;
00259 }
00260
00261 bool Camera::sphereInFrustum(Vec3 pos, float r) {
00262 for (int i = 0; i < 6; i++) {
00263 if (m_Frustum[i][0] * pos.x + m_Frustum[i][1] * pos.y + m_Frustum[i][2] * pos.z + m_Frustum[i][3] <= -r) {
00264 return false;
00265 }
00266 }
00267 return true;
00268 }