00001
00002
00003
00004
00005
00006
00007
00009
00011
00012
00013
00014
00015
00017
00018 #pragma once
00019
00020 #include "algebra3.h"
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023
00066 class ViewModel
00067 {
00068 public:
00069 vec3 eye;
00070 vec3 lookat;
00071 vec3 up;
00072 vec3 side;
00073 vec3 forward;
00074 mat4 mtx;
00075 float distance;
00076
00082 void set_distance (float new_distance)
00083 {
00084 if (new_distance <= 0.0)
00085 return;
00086
00087
00088 forward = lookat - eye;
00089 forward.normalize ();
00090
00091
00092 distance = new_distance;
00093
00094
00095 eye = lookat - forward * distance;
00096 }
00097
00101 void set_up (vec3 new_up)
00102 {
00103 up = new_up;
00104 update ();
00105 }
00106
00110 void set_up (float x, float y, float z)
00111 {
00112 set_up (vec3 (x, y, z));
00113 }
00114
00118 void set_eye (vec3 new_eye)
00119 {
00120 eye = new_eye;
00121 update ();
00122 }
00123
00127 void set_eye (float x, float y, float z)
00128 {
00129 set_eye (vec3 (x, y, z));
00130 }
00131
00135 void set_lookat (vec3 new_lookat)
00136 {
00137 lookat = new_lookat;
00138 update ();
00139 }
00140
00144 void set_lookat (float x, float y, float z)
00145 {
00146 set_lookat (vec3 (x, y, z));
00147 }
00148
00153 void roll (float angle)
00154 {
00155 mat4 rot = mat4::rotation3D (forward, angle);
00156
00157 up = rot * up;
00158
00159 update ();
00160 }
00161
00166 void eye_yaw (float angle)
00167 {
00168 vec3 eye_pt = eye - lookat;
00169 mat4 rot = mat4::rotation3D (up, angle);
00170
00171 eye_pt = rot * eye_pt;
00172 eye = lookat + eye_pt;
00173
00174 update ();
00175 }
00176
00181 void eye_yaw_abs (float angle, vec3 axis)
00182 {
00183 vec3 eye_pt = eye - lookat;
00184 mat4 rot = mat4::rotation3D (axis, angle);
00185
00186 eye_pt = rot * eye_pt;
00187 eye = lookat + eye_pt;
00188
00189 up = rot * up;
00190
00191 update ();
00192 }
00193
00198 void eye_pitch (float angle)
00199 {
00200 vec3 eye_pt = eye - lookat;
00201 mat4 rot = mat4::rotation3D (side, angle);
00202
00203 eye_pt = rot * eye_pt;
00204 eye = lookat + eye_pt;
00205
00206 up = rot * up;
00207
00208 update ();
00209 }
00210
00216 void lookat_yaw (float angle)
00217 {
00218 vec3 lookat_pt = lookat - eye;
00219
00220 mat4 rot = mat4::rotation3D (up, -angle);
00221
00222 lookat_pt = rot * lookat_pt;
00223 lookat = eye + lookat_pt;
00224
00225 update ();
00226 }
00227
00233 void lookat_pitch (float angle)
00234 {
00235 vec3 lookat_pt = lookat - eye;
00236
00237 mat4 rot = mat4::rotation3D (side, -angle);
00238
00239 lookat_pt = rot * lookat_pt;
00240 lookat = eye + lookat_pt;
00241
00242 up = rot * up;
00243
00244 update ();
00245 }
00246
00252 void reset_up (int axis_num)
00253 {
00254 float eye_distance = (lookat - eye).length ();
00255 eye[axis_num] = lookat[axis_num];
00256
00257
00258 vec3 vector = eye - lookat;
00259 vector.normalize ();
00260 vector *= eye_distance;
00261
00262 eye = lookat + vector;
00263 up.set (0.0, 0.0, 0.0);
00264 up[axis_num] = 1.0;
00265
00266 update ();
00267 }
00268
00272 void reset_up (void)
00273 {
00274 reset_up (VY);
00275 }
00276
00283 void move (float side_move, float up_move, float forw_move)
00284 {
00285 eye += forward * forw_move;
00286 eye += side * side_move;
00287 eye += up * up_move;
00288 lookat += forward * forw_move;
00289 lookat += side * side_move;
00290 lookat += up * up_move;
00291 update ();
00292 }
00293
00298 void move (vec3 v)
00299 {
00300 move (v[VX], v[VY], v[VZ]);
00301 }
00302
00307 void move_by_eye (vec3 new_eye)
00308 {
00309 vec3 diff = new_eye - eye;
00310
00311 eye += diff;
00312 lookat += diff;
00313
00314 update ();
00315 }
00316
00321 void move_by_lookat (vec3 new_lookat)
00322 {
00323 vec3 diff = new_lookat - lookat;
00324
00325 lookat += diff;
00326 eye += diff;
00327
00328 update ();
00329 }
00330
00334 void move_abs (vec3 v)
00335 {
00336 eye += v;
00337 lookat += v;
00338
00339 update ();
00340 }
00341
00346 void rot_about_eye (mat4 rot)
00347 {
00348 vec3 view = lookat - eye;
00349
00350 view = rot * view;
00351 up = rot * up;
00352
00353 lookat = eye + view;
00354
00355 update ();
00356 }
00357
00362 void rot_about_lookat (mat4 rot)
00363 {
00364
00365
00366 vec3 view = eye - lookat;
00367
00368 view = rot * view;
00369 up = rot * up;
00370
00371 eye = lookat + view;
00372
00373 update ();
00374 }
00375
00379 void make_mtx (void)
00380 {
00381 update ();
00382
00383 mtx[0][0] = side[VX];
00384 mtx[0][1] = up[VX];
00385 mtx[0][2] = forward[VX];
00386 mtx[0][3] = 0.0;
00387 mtx[1][0] = side[VY];
00388 mtx[1][1] = up[VY];
00389 mtx[1][2] = forward[VY];
00390 mtx[1][3] = 0.0;
00391 mtx[2][0] = side[VZ];
00392 mtx[2][1] = up[VZ];
00393 mtx[2][2] = forward[VZ];
00394 mtx[2][3] = 0.0;
00395 mtx[3][0] = 0.0;
00396 mtx[3][1] = 0.0;
00397 mtx[3][2] = 0.0;
00398 mtx[3][3] = 1.0;
00399 }
00400
00405 void load_to_openGL (void)
00406 {
00407 make_mtx ();
00408
00409 glMatrixMode (GL_MODELVIEW);
00410 glLoadIdentity ();
00411 glMultMatrixf (&mtx[0][0]);
00412 glTranslatef (-eye[VX], -eye[VY], -eye[VZ]);
00413 }
00414
00420 void load_to_openGL_noident (void)
00421 {
00422
00423 make_mtx ();
00424
00425 glMatrixMode (GL_MODELVIEW);
00426 glMultMatrixf ((float *) &mtx[0][0]);
00427 glTranslatef (-eye[VX], -eye[VY], -eye[VZ]);
00428 }
00429
00433 void reset (void)
00434 {
00435 up.set (0.0, 1.0, 0.0);
00436
00437 eye.set (0.0, 0.0, 10.0);
00438 lookat.set (0.0, 0.0, 0.0);
00439
00440 mtx = mat4::identity3D ();
00441
00442 update ();
00443 }
00444
00448 ViewModel (void)
00449 {
00450 reset ();
00451 }
00452
00457 void update (void)
00458 {
00459
00460 forward = -(lookat - eye);
00461 distance = forward.length ();
00462 forward /= distance;
00463
00464 side = up ^ forward;
00465 up = forward ^ side;
00466
00467 forward.normalize ();
00468 up.normalize ();
00469 side.normalize ();
00470 }
00471
00476 void dump (FILE * output)
00477 {
00478 fprintf (output, "Viewmodel: \n");
00479 eye.print (output, " eye");
00480 lookat.print (output, " lookat");
00481 up.print (output, " up");
00482 side.print (output, " side");
00483 forward.print (output, " forward");
00484 mtx.print (output, " mtx");
00485 }
00486 };
00487