#include "Camera.h" #include #include #include #include #include const int PI = 3.14159; using namespace std; const double Camera::MAX_D = 100.0; const double Camera::MIN_D = 0.1; const double Camera::DEF_STEP = 1.5; Camera::Camera(double theta, double phi, double d) : theta_(theta), phi_(phi), d_(d), pTrack_(NULL), // not tracking anything (yet) axes_(false), // disable axes by default currX_(-1), currY_(-1), lookAt_(0,0,0) // start by looking at origin { // Nothing (more) to do } Camera::~Camera(void) { // Nothing to do } void Camera::init() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, 1.0, 1.0, 3000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void Camera::display() { Tuple pt; if (pTrack_) pt = *pTrack_; else pt = lookAt_; // compute eye tuple Tuple eye( -d_ * cos(theta_) * sin(phi_), 2*d_ * sin(theta_), d_ * cos(theta_) * cos(phi_)); eye += pt; gluLookAt(eye.x(), eye.y(), eye.z(), pt.x(), pt.y(), pt.z(), 0.0, 1.0, 0.0); // draw axes if applicable if (axes_) { glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(100.0f, 0.0f, 0.0f); glEnd(); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 100.0f, 0.0f); glEnd(); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 100.0f); glEnd(); } } void Camera::track(const Tuple *pTrack) { // In case we're moving to not tracking anything, save our position if (pTrack_) lookAt_ = *pTrack_; pTrack_ = pTrack; } void Camera::rotate(int x, int y, int width, int height) { // wait until a mouse position is recorded and // avoid really big jumps if (currX_>0 && abs(x-currX_) < width/20 && abs(y-currY_) < height/20) { phi_ += (double) (x-currX_) / (double) width * PI; theta_ += (double) (y-currY_) / (double) height * PI; // limit theta to -16pi/33 and 16pi/33 // it is disorienting to lose "up" if (theta_ < -16*PI/33.0) theta_ = -16*PI/33.0; if (theta_ > 16*PI/33.0) theta_ = 16*PI/33.0; } currX_ = x; currY_ = y; //debug(); // ***** } void Camera::moveForward(double dist) { Tuple move( -cos(theta_) * sin(phi_), 2 * sin(theta_), cos(theta_) * cos(phi_)); lookAt_ -= move.norm() * dist; } void Camera::moveBackward(double dist) { Tuple move( -cos(theta_) * sin(phi_), 2 * sin(theta_), cos(theta_) * cos(phi_)); lookAt_ += move.norm() * dist; } void Camera::moveLeft(double dist) { Tuple move( -cos(theta_) * sin(phi_), 2 * sin(theta_), cos(theta_) * cos(phi_)); lookAt_ += move.cross(Tuple(0.0, 1.0, 0.0)).norm() * dist; } void Camera::moveRight(double dist) { Tuple move( -cos(theta_) * sin(phi_), 2 * sin(theta_), cos(theta_) * cos(phi_)); lookAt_ -= move.cross(Tuple(0.0, 1.0, 0.0)).norm() * dist; } void Camera::moveUp(double dist) { Tuple move( -cos(theta_) * sin(phi_), 2 * sin(theta_), cos(theta_) * cos(phi_)); lookAt_ += move.cross(Tuple(0.0, 1.0, 0.0)).cross(move).norm() * dist; } void Camera::moveDown(double dist) { Tuple move( -cos(theta_) * sin(phi_), 2 * sin(theta_), cos(theta_) * cos(phi_)); lookAt_ -= move.cross(Tuple(0.0, 1.0, 0.0)).cross(move).norm() * dist; } void Camera::zoomIn (double dist) { if (d_ > MIN_D + dist) d_ -= dist; else d_ = MIN_D; } void Camera::zoomOut (double dist) { if (d_ < MAX_D - dist) d_ += dist; else d_ = MAX_D; } const Tuple Camera::direction() const { return -Tuple( -cos(theta_) * sin(phi_), 2 * sin(theta_), cos(theta_) * cos(phi_)).norm(); } void Camera::debug() const { cout << "Theta: " << theta_ << ", Phi: " << phi_ << ", d: " << d_; }