#ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_GL_GL_H # include #elif HAVE_OPENGL_GL_H # include #endif #include #include "camera.h" #include "globals.h" #include "vector.h" static const vector up = {0.0, 0.0, 1.0}; void camera_home(void){ vector releye; anugavis.eye[0] = anugavis.minX; anugavis.eye[1] = anugavis.minY; anugavis.eye[2] = 0; anugavis.focus[0] = anugavis.minX + (anugavis.maxX - anugavis.minX) / 2; anugavis.focus[1] = anugavis.minY + (anugavis.maxY - anugavis.minY) / 2; anugavis.focus[2] = 0; vsub(anugavis.eye, anugavis.focus, releye); anugavis.eye[2] = vlen(releye); } void camera_pitch(float theta){ float c = cos(theta); float s = sin(theta); float x; float y; float z; vector releye; vector newreleye; vector axis; float dot; float len; vsub(anugavis.eye, anugavis.focus, releye); /* Check we're not too near the vertical */ dot = vdot(up, releye); len = vlen(releye); if(((dot > 0.99 * len) && (theta > 0)) || ((dot < -0.99 * len) && (theta < 0))) return; /* Calculation from glRotatef manpage. */ vcross(releye, up, axis); vscale(axis, 1.0/vlen(axis), axis); x = axis[0]; y = axis[1]; z = axis[2]; newreleye[0] = releye[0] * (x*x*(1-c)+c) + releye[1] * (x*y*(1-c)-z*s) + releye[2] * (x*z*(1-c)+y*s); newreleye[1] = releye[0] * (y*x*(1-c)+z*s) + releye[1] * (y*y*(1-c)+c) + releye[2] * (y*z*(1-c)-x*s); newreleye[2] = releye[0] * (z*x*(1-c)-y*s) + releye[1] * (z*y*(1-c)+x*s) + releye[2] * (z*z*(1-c)+c); vadd(newreleye, anugavis.focus, anugavis.eye); } void camera_strafe(float dist){ vector releye; vector dir; vsub(anugavis.eye, anugavis.focus, releye); vcross(releye, up, dir); vscale(dir, dist/vlen(dir), dir); vadd(anugavis.eye, dir, anugavis.eye); vadd(anugavis.focus, dir, anugavis.focus); } void camera_track(float dist){ vector dir = {0, 0, 0}; vsub(anugavis.eye, anugavis.focus, dir); dir[2] = 0; vscale(dir, dist/vlen(dir), dir); vadd(anugavis.eye, dir, anugavis.eye); vadd(anugavis.focus, dir, anugavis.focus); } void camera_yaw(float theta){ float c = cos(theta); float s = sin(theta); vector releye; vector newreleye; vsub(anugavis.eye, anugavis.focus, releye); newreleye[0] = releye[0] * c + releye[1] * s; newreleye[1] = releye[0] * -1 * s + releye[1] * c; newreleye[2] = releye[2]; vadd(newreleye, anugavis.focus, anugavis.eye); } void camera_zoom(float dist){ vector releye; float len; vsub(anugavis.focus, anugavis.eye, releye); if((len = vlen(releye)) < dist) return; vscale(releye, dist/len, releye); vadd(anugavis.eye, releye, anugavis.eye); }