00001 #include "Camera.h"
00002 #include "Utility.h"
00003
00004 #define PLANE_FRONT 0
00005 #define PLANE_BACK 1
00006 #define PLANE_LEFT 2
00007 #define PLANE_RIGHT 3
00008 #define PLANE_BOTTOM 4
00009 #define PLANE_TOP 5
00010
00011 Camera::Camera ()
00012 {
00013 angle = CAMERA_STANDARD_ANGLE;
00014 aspect_ratio = CAMERA_STANDARD_RATIO;
00015 near_cutoff = CAMERA_STANDARD_NEAR;
00016 far_cutoff = CAMERA_STANDARD_FAR;
00017
00018 position = new PositionPath ();
00019 }
00020
00021 Camera::~Camera ()
00022 {
00023
00024 }
00025
00026 void Camera::SetAttributes (double a, double a_r, double n, double f)
00027 {
00028 angle = a;
00029 aspect_ratio = a_r;
00030 near_cutoff = n;
00031 far_cutoff = f;
00032 }
00033
00034 void Camera::ApplyAttributes ()
00035 {
00036 int previous_mode;
00037
00038 glGetIntegerv (GL_MATRIX_MODE, &previous_mode);
00039 glMatrixMode (GL_PROJECTION);
00040 glLoadIdentity ();
00041 gluPerspective (angle, aspect_ratio, near_cutoff, far_cutoff);
00042 glMatrixMode (previous_mode);
00043 }
00044
00045 void Camera::ApplyPosition (int time)
00046 {
00047 Position pos;
00048
00049 pos = position->GetPosition (time);
00050
00051
00052
00053 glRotatef (90, 0.0f, 1.0f, 0.0f);
00054 glRotatef (-90, 1.0f, 0.0f, 0.0f);
00055
00056
00057 glRotatef (-pos.roll, 1.0f, 0.0f, 0.0f);
00058 glRotatef (-pos.pitch, 0.0f, 1.0f, 0.0f);
00059 glRotatef (-pos.yaw, 0.0f, 0.0f, 1.0f);
00060 glTranslatef (-pos.x, -pos.y, -pos.z);
00061 }
00062
00063 void Camera::ComputeInverseView (int time)
00064 {
00065 Position pos;
00066 float view[16];
00067
00068 pos = position->GetPosition (time);
00069
00070
00071 glPushMatrix ();
00072 glLoadIdentity ();
00073
00074 glRotatef (90, 0.0f, 1.0f, 0.0f);
00075 glRotatef (-90, 1.0f, 0.0f, 0.0f);
00076
00077 glRotatef (-pos.roll, 1.0f, 0.0f, 0.0f);
00078 glRotatef (-pos.pitch, 0.0f, 1.0f, 0.0f);
00079 glRotatef (-pos.yaw, 0.0f, 0.0f, 1.0f);
00080 glTranslatef (-pos.x, -pos.y, -pos.z);
00081
00082 glGetFloatv (GL_MODELVIEW_MATRIX, view);
00083
00084 glPopMatrix ();
00085
00086
00087
00088 Geometry::InvertHomogenousMatrix (view, inverse_view);
00089 }
00090
00091 float * Camera::GetInverseView ()
00092 {
00093 return inverse_view;
00094 }
00095
00096 void Camera::BuildPlanes (int time)
00097 {
00098 double res[16];
00099 double mod[16];
00100
00101 Position pos;
00102 pos = position->GetPosition (time);
00103
00104
00105 glPushMatrix ();
00106 glLoadIdentity ();
00107
00108 glRotatef (90, 0.0f, 1.0f, 0.0f);
00109 glRotatef (-90, 1.0f, 0.0f, 0.0f);
00110
00111 glRotatef (-pos.roll, 1.0f, 0.0f, 0.0f);
00112 glRotatef (-pos.pitch, 0.0f, 1.0f, 0.0f);
00113 glRotatef (-pos.yaw, 0.0f, 0.0f, 1.0f);
00114 glTranslatef (-pos.x, -pos.y, -pos.z);
00115
00116 glGetDoublev (GL_MODELVIEW_MATRIX, mod);
00117 glPopMatrix ();
00118
00119
00120 glMatrixMode (GL_PROJECTION);
00121 glPushMatrix ();
00122 glLoadIdentity ();
00123 ApplyAttributes ();
00124 glMultMatrixd (mod);
00125 glGetDoublev (GL_PROJECTION_MATRIX, res);
00126 glPopMatrix ();
00127 glMatrixMode (GL_MODELVIEW);
00128
00129
00130 front.n.x = res[3] + res[2];
00131 front.n.y = res[7] + res[6];
00132 front.n.z = res[11] + res[10];
00133 front.d = res[15] + res[14];
00134
00135 back.n.x = res[3] - res[2];
00136 back.n.y = res[7] - res[6];
00137 back.n.z = res[11] - res[10];
00138 back.d = res[15] - res[14];
00139
00140 left.n.x = res[3] + res[0];
00141 left.n.y = res[7] + res[4];
00142 left.n.z = res[11] + res[8];
00143 left.d = res[15] + res[12];
00144
00145 right.n.x = res[3] - res[0];
00146 right.n.y = res[7] - res[4];
00147 right.n.z = res[11] - res[8];
00148 right.d = res[15] - res[12];
00149
00150 bottom.n.x = res[3] + res[1];
00151 bottom.n.y = res[7] + res[5];
00152 bottom.n.z = res[11] + res[9];
00153 bottom.d = res[15] + res[13];
00154
00155 top.n.x = res[3] - res[1];
00156 top.n.y = res[7] - res[5];
00157 top.n.z = res[11] - res[9];
00158 top.d = res[15] - res[13];
00159
00160
00161 float temp;
00162
00163 temp = sqrt (front.n.x * front.n.x + front.n.y * front.n.y + front.n.z * front.n.z);
00164 front.n.x /= temp;
00165 front.n.y /= temp;
00166 front.n.z /= temp;
00167 front.d /= temp;
00168
00169 temp = sqrt (back.n.x * back.n.x + back.n.y * back.n.y + back.n.z * back.n.z);
00170 back.n.x /= temp;
00171 back.n.y /= temp;
00172 back.n.z /= temp;
00173 back.d /= temp;
00174
00175 temp = sqrt (left.n.x * left.n.x + left.n.y * left.n.y + left.n.z * left.n.z);
00176 left.n.x /= temp;
00177 left.n.y /= temp;
00178 left.n.z /= temp;
00179 left.d /= temp;
00180
00181 temp = sqrt (right.n.x * right.n.x + right.n.y * right.n.y + right.n.z * right.n.z);
00182 right.n.x /= temp;
00183 right.n.y /= temp;
00184 right.n.z /= temp;
00185 right.d /= temp;
00186
00187 temp = sqrt (bottom.n.x * bottom.n.x + bottom.n.y * bottom.n.y + bottom.n.z * bottom.n.z);
00188 bottom.n.x /= temp;
00189 bottom.n.y /= temp;
00190 bottom.n.z /= temp;
00191 bottom.d /= temp;
00192
00193 temp = sqrt (top.n.x * top.n.x + top.n.y * top.n.y + top.n.z * top.n.z);
00194 top.n.x /= temp;
00195 top.n.y /= temp;
00196 top.n.z /= temp;
00197 top.d /= temp;
00198 }
00199
00200 void Camera::DrawFrustum ()
00201 {
00202 Point corner[8];
00203
00204
00205 corner[0] = Geometry::PlaneIntersection (front, left, top);
00206 corner[1] = Geometry::PlaneIntersection (front, left, bottom);
00207 corner[2] = Geometry::PlaneIntersection (front, right, top);
00208 corner[3] = Geometry::PlaneIntersection (front, right, bottom);
00209 corner[4] = Geometry::PlaneIntersection (back, left, top);
00210 corner[5] = Geometry::PlaneIntersection (back, left, bottom);
00211 corner[6] = Geometry::PlaneIntersection (back, right, top);
00212 corner[7] = Geometry::PlaneIntersection (back, right, bottom);
00213
00214 Utility::SetColor (0.2f, 0.2f, 0.8f, 1.0f);
00215
00216
00217 Utility::DrawQuad (corner[0], corner[2], corner[3], corner[1]);
00218
00219 Utility::DrawQuad (corner[6], corner[4], corner[5], corner[7]);
00220
00221 Utility::DrawQuad (corner[4], corner[0], corner[1], corner[5]);
00222
00223 Utility::DrawQuad (corner[2], corner[6], corner[7], corner[3]);
00224
00225 Utility::DrawQuad (corner[1], corner[3], corner[7], corner[5]);
00226
00227 Utility::DrawQuad (corner[4], corner[6], corner[2], corner[0]);
00228 }
00229
00230 void Camera::DrawFrustum2 (int time)
00231 {
00232 Point corner[8];
00233 Point c[8];
00234 double mod[16];
00235 double inv[16];
00236
00237
00238 corner[0] = Geometry::PlaneIntersection (planes[PLANE_FRONT], planes[PLANE_LEFT], planes[PLANE_TOP]);
00239 corner[1] = Geometry::PlaneIntersection (planes[PLANE_FRONT], planes[PLANE_LEFT], planes[PLANE_BOTTOM]);
00240 corner[2] = Geometry::PlaneIntersection (planes[PLANE_FRONT], planes[PLANE_RIGHT], planes[PLANE_TOP]);
00241 corner[3] = Geometry::PlaneIntersection (planes[PLANE_FRONT], planes[PLANE_RIGHT], planes[PLANE_BOTTOM]);
00242 corner[4] = Geometry::PlaneIntersection (planes[PLANE_BACK], planes[PLANE_LEFT], planes[PLANE_TOP]);
00243 corner[5] = Geometry::PlaneIntersection (planes[PLANE_BACK], planes[PLANE_LEFT], planes[PLANE_BOTTOM]);
00244 corner[6] = Geometry::PlaneIntersection (planes[PLANE_BACK], planes[PLANE_RIGHT], planes[PLANE_TOP]);
00245 corner[7] = Geometry::PlaneIntersection (planes[PLANE_BACK], planes[PLANE_RIGHT], planes[PLANE_BOTTOM]);
00246
00247
00248 glPushMatrix ();
00249 glLoadIdentity ();
00250
00251 ApplyPosition (time);
00252 glGetDoublev (GL_MODELVIEW_MATRIX, mod);
00253
00254 glPopMatrix ();
00255
00256 Geometry::InvertHomogenousMatrix (mod, inv);
00257
00258 c[0].x = corner[0].x * inv[0] + corner[0].y * inv[4] + corner[0].z * inv[8] + inv[12];
00259 c[0].y = corner[0].x * inv[1] + corner[0].y * inv[5] + corner[0].z * inv[9] + inv[13];
00260 c[0].z = corner[0].x * inv[2] + corner[0].y * inv[6] + corner[0].z * inv[10] + inv[14];
00261
00262 c[1].x = corner[1].x * inv[0] + corner[1].y * inv[4] + corner[1].z * inv[8] + inv[12];
00263 c[1].y = corner[1].x * inv[1] + corner[1].y * inv[5] + corner[1].z * inv[9] + inv[13];
00264 c[1].z = corner[1].x * inv[2] + corner[1].y * inv[6] + corner[1].z * inv[10] + inv[14];
00265
00266 c[2].x = corner[2].x * inv[0] + corner[2].y * inv[4] + corner[2].z * inv[8] + inv[12];
00267 c[2].y = corner[2].x * inv[1] + corner[2].y * inv[5] + corner[2].z * inv[9] + inv[13];
00268 c[2].z = corner[2].x * inv[2] + corner[2].y * inv[6] + corner[2].z * inv[10] + inv[14];
00269
00270 c[3].x = corner[3].x * inv[0] + corner[3].y * inv[4] + corner[3].z * inv[8] + inv[12];
00271 c[3].y = corner[3].x * inv[1] + corner[3].y * inv[5] + corner[3].z * inv[9] + inv[13];
00272 c[3].z = corner[3].x * inv[2] + corner[3].y * inv[6] + corner[3].z * inv[10] + inv[14];
00273
00274 c[4].x = corner[4].x * inv[0] + corner[4].y * inv[4] + corner[4].z * inv[8] + inv[12];
00275 c[4].y = corner[4].x * inv[1] + corner[4].y * inv[5] + corner[4].z * inv[9] + inv[13];
00276 c[4].z = corner[4].x * inv[2] + corner[4].y * inv[6] + corner[4].z * inv[10] + inv[14];
00277
00278 c[5].x = corner[5].x * inv[0] + corner[5].y * inv[4] + corner[5].z * inv[8] + inv[12];
00279 c[5].y = corner[5].x * inv[1] + corner[5].y * inv[5] + corner[5].z * inv[9] + inv[13];
00280 c[5].z = corner[5].x * inv[2] + corner[5].y * inv[6] + corner[5].z * inv[10] + inv[14];
00281
00282 c[6].x = corner[6].x * inv[0] + corner[6].y * inv[4] + corner[6].z * inv[8] + inv[12];
00283 c[6].y = corner[6].x * inv[1] + corner[6].y * inv[5] + corner[6].z * inv[9] + inv[13];
00284 c[6].z = corner[6].x * inv[2] + corner[6].y * inv[6] + corner[6].z * inv[10] + inv[14];
00285
00286 c[7].x = corner[7].x * inv[0] + corner[7].y * inv[4] + corner[7].z * inv[8] + inv[12];
00287 c[7].y = corner[7].x * inv[1] + corner[7].y * inv[5] + corner[7].z * inv[9] + inv[13];
00288 c[7].z = corner[7].x * inv[2] + corner[7].y * inv[6] + corner[7].z * inv[10] + inv[14];
00289
00290 Utility::SetColor (0.2f, 0.2f, 0.8f, 1.0f);
00291
00292 Utility::DrawQuad (c[0], c[2], c[3], c[1]);
00293 Utility::DrawQuad (c[6], c[4], c[5], c[7]);
00294 Utility::DrawQuad (c[4], c[0], c[1], c[5]);
00295 Utility::DrawQuad (c[2], c[6], c[7], c[3]);
00296 Utility::DrawQuad (c[1], c[3], c[7], c[5]);
00297 Utility::DrawQuad (c[4], c[6], c[2], c[0]);
00298 }
00299
00300 void Camera::BuildPlanes2 ()
00301 {
00302 double pro[16];
00303
00304 glMatrixMode (GL_PROJECTION);
00305 glPushMatrix ();
00306 glLoadIdentity ();
00307 ApplyAttributes ();
00308 glGetDoublev (GL_PROJECTION_MATRIX, pro);
00309 glPopMatrix ();
00310 glMatrixMode (GL_MODELVIEW);
00311
00312
00313 planes[PLANE_FRONT].n.x = pro[3] + pro[2];
00314 planes[PLANE_FRONT].n.y = pro[7] + pro[6];
00315 planes[PLANE_FRONT].n.z = pro[11] + pro[10];
00316 planes[PLANE_FRONT].d = pro[15] + pro[14];
00317
00318 planes[PLANE_BACK].n.x = pro[3] - pro[2];
00319 planes[PLANE_BACK].n.y = pro[7] - pro[6];
00320 planes[PLANE_BACK].n.z = pro[11] - pro[10];
00321 planes[PLANE_BACK].d = pro[15] - pro[14];
00322
00323 planes[PLANE_LEFT].n.x = pro[3] + pro[0];
00324 planes[PLANE_LEFT].n.y = pro[7] + pro[4];
00325 planes[PLANE_LEFT].n.z = pro[11] + pro[8];
00326 planes[PLANE_LEFT].d = pro[15] + pro[12];
00327
00328 planes[PLANE_RIGHT].n.x = pro[3] - pro[0];
00329 planes[PLANE_RIGHT].n.y = pro[7] - pro[4];
00330 planes[PLANE_RIGHT].n.z = pro[11] - pro[8];
00331 planes[PLANE_RIGHT].d = pro[15] - pro[12];
00332
00333 planes[PLANE_BOTTOM].n.x = pro[3] + pro[1];
00334 planes[PLANE_BOTTOM].n.y = pro[7] + pro[5];
00335 planes[PLANE_BOTTOM].n.z = pro[11] + pro[9];
00336 planes[PLANE_BOTTOM].d = pro[15] + pro[13];
00337
00338 planes[PLANE_TOP].n.x = pro[3] - pro[1];
00339 planes[PLANE_TOP].n.y = pro[7] - pro[5];
00340 planes[PLANE_TOP].n.z = pro[11] - pro[9];
00341 planes[PLANE_TOP].d = pro[15] - pro[13];
00342
00343
00344 for (int index = 0; index < 6; index++)
00345 {
00346 float temp;
00347
00348 temp = sqrt (planes[index].n.x * planes[index].n.x + planes[index].n.y * planes[index].n.y + planes[index].n.z * planes[index].n.z);
00349 planes[index].n.x /= temp;
00350 planes[index].n.y /= temp;
00351 planes[index].n.z /= temp;
00352 planes[index].d /= temp;
00353 }
00354 }
00355
00356 void Camera::MoveForward (double amount)
00357 {
00358 Position p;
00359 Vector delta;
00360
00361 p = position->GetPosition (0);
00362
00363 delta.x = cos(DEG2RAD(p.pitch)) * cos (DEG2RAD(p.yaw)) * amount;
00364 delta.y = cos(DEG2RAD(p.pitch)) * sin (DEG2RAD(p.yaw)) * amount;
00365 delta.z = - sin (DEG2RAD(p.pitch)) * amount;
00366
00367 position->SetConstantPosition (p.x + delta.x, p.y + delta.y , p.z + delta.z, p.roll, p.pitch, p.yaw);
00368 }
00369
00370 void Camera::MoveRight (double amount)
00371 {
00372 Position p;
00373 Vector delta;
00374
00375 p = position->GetPosition (0);
00376
00377 delta.x = (-cos(DEG2RAD(p.roll))*sin(DEG2RAD(p.yaw)) + sin(DEG2RAD(p.roll))*sin(DEG2RAD(p.pitch))*cos(DEG2RAD(p.yaw))) * amount;
00378 delta.y = (sin(DEG2RAD(p.roll))*sin(DEG2RAD(p.pitch))*sin(DEG2RAD(p.yaw)) + cos(DEG2RAD(p.roll))*cos(DEG2RAD(p.yaw))) * amount;
00379 delta.z = sin(DEG2RAD(p.roll))*cos(DEG2RAD(p.pitch))*amount;
00380
00381 position->SetConstantPosition (p.x + delta.x, p.y + delta.y, p.z + delta.z, p.roll, p.pitch, p.yaw);
00382 }
00383
00384 void Camera::MoveUp (double amount)
00385 {
00386 Position p;
00387 Vector delta;
00388
00389 p = position->GetPosition (0);
00390
00391 delta.x = (cos(DEG2RAD(p.roll))*sin(DEG2RAD(p.pitch))*cos(DEG2RAD(p.yaw)) + sin(DEG2RAD (p.roll))*sin(DEG2RAD(p.yaw))) * amount;
00392 delta.y = (-sin(DEG2RAD(p.roll))*cos(DEG2RAD(p.yaw)) + cos(DEG2RAD(p.roll))*sin(DEG2RAD(p.pitch))*sin(DEG2RAD(p.yaw))) * amount;
00393 delta.z = cos(DEG2RAD(p.roll))* cos(DEG2RAD(p.pitch)) * amount;
00394
00395 position->SetConstantPosition (p.x + delta.x, p.y + delta.y, p.z + delta.z, p.roll, p.pitch, p.yaw);
00396 }