#include "rtsVector3d.h" #include "rtsPoint3d.h" #include "rtsQuaternion.h" #ifndef RTS_CAMERA_H #define RTS_CAMERA_H class rtsCamera { vector3D d; //direction that the camera is pointing point3D p; //position of the camera vector3D up; //"up" direction float focus; //focal length of the camera float fov; //private function makes sure that the up vector is orthogonal to the direction vector and both are normalized void stabalize() { vector3D side = up.X(d); up = d.X(side); up.Normalize(); d.Normalize(); } public: void setPosition(point3D pos) { p = pos; } void setPosition(float x, float y, float z){setPosition(point3D(x, y, z));} void setFocalDistance(float distance){focus = distance;} void setFOV(float field_of_view){fov = field_of_view;} void LookAt(point3D pos) { //find the new direction d = pos - p; //find the distance from the look-at point to the current position focus = d.Length(); //stabalize the camera stabalize(); } void LookAt(float px, float py, float pz){LookAt(point3D(px, py, pz));} void LookAt(point3D pos, vector3D new_up){up = new_up; LookAt(pos);} void LookAt(float px, float py, float pz, float ux, float uy, float uz){LookAt(point3D(px, py, pz), vector3D(ux, uy, uz));} void LookAtDolly(float lx, float ly, float lz) { //find the current focus point point3D f = p + focus*d; vector3D T = point3D(lx, ly, lz) - f; p = p + T; } void Dolly(vector3D direction) { p = p+direction; } void Dolly(float x, float y, float z){Dolly(vector3D(x, y, z));} void Push(float delta) { if(delta > focus) delta = focus; focus -= delta; Dolly(d*delta); } void Pan(float theta_x, float theta_y, float theta_z) { //x rotation is around the up axis rtsQuaternion qx; qx.CreateRotation(theta_x, up.x, up.y, up.z); //y rotation is around the side axis vector3D side = up.X(d); rtsQuaternion qy; qy.CreateRotation(theta_y, side.x, side.y, side.z); //z rotation is around the direction vector rtsQuaternion qz; qz.CreateRotation(theta_z, d.x, d.y, d.z); //combine the rotations in x, y, z order rtsQuaternion final = qz*qy*qx; //get the rotation matrix matrix4x4 rot_matrix = final.toMatrix(); //apply the rotation d = rot_matrix*d; up = rot_matrix*up; //stabalize the camera stabalize(); } void Pan(float theta_x){Pan(theta_x, 0, 0);} void Tilt(float theta_y){Pan(0, theta_y, 0);} void Twist(float theta_z){Pan(0, 0, theta_z);} void Zoom(float delta) { fov -= delta; if(fov < 0.5) fov = 0.5; if(fov > 180) fov = 180; } void OrbitFocus(float theta_x, float theta_y) { //find the focal point point3D focal_point = p + focus*d; //center the coordinate system on the focal point point3D centered = p - (focal_point - point3D(0, 0, 0)); //create the x rotation (around the up vector) rtsQuaternion qx; qx.CreateRotation(theta_x, up.x, up.y, up.z); centered = qx.toMatrix()*centered; //get a side vector for theta_y rotation vector3D side = up.X((point3D(0, 0, 0) - centered).Normalize()); rtsQuaternion qy; qy.CreateRotation(theta_y, side.x, side.y, side.z); centered = qy.toMatrix()*centered; //perform the rotation on the centered camera position //centered = final.toMatrix()*centered; //re-position the camera p = centered + (focal_point - point3D(0, 0, 0)); //make sure we are looking at the focal point LookAt(focal_point); //stabalize the camera stabalize(); } void Slide(float u, float v) { vector3D V = up.Normalize(); vector3D U = up.X(d).Normalize(); p = p + (V * v) + (U * u); } //accessor methods point3D getPosition(){return p;} vector3D getUp(){return up;} vector3D getDirection(){return d;} point3D getLookAt(){return p + focus*d;} float getFOV(){return fov;} //output the camera settings const void print(ostream& output) { output<<"Position: "<(0, 0, 0); d = vector3D(0, 0, 1); up = vector3D(0, 1, 0); focus = 1; } }; #endif