From 30d24405986b54ef4146f2d827d0ea73b5f1aca0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 7 Mar 2015 19:02:51 -0500 Subject: [PATCH] More camera fixes: Better viewall calculation, better switching between perspective and ortho --- src/Camera.cc | 44 ++++++++++++++++++-------------------------- src/GLView.cc | 21 ++++++++++----------- 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/src/Camera.cc b/src/Camera.cc index 567ded87..c166f268 100644 --- a/src/Camera.cc +++ b/src/Camera.cc @@ -3,7 +3,7 @@ #include "printutils.h" Camera::Camera(enum CameraType camtype) : - type(camtype), projection(Camera::PERSPECTIVE), fov(22.5), viewall(false), height(60) + type(camtype), projection(Camera::PERSPECTIVE), fov(22.5), viewall(false) { PRINTD("Camera()"); if (this->type == Camera::GIMBAL) { @@ -26,7 +26,7 @@ void Camera::setup(std::vector params) type = Camera::GIMBAL; object_trans << params[0], params[1], params[2]; object_rot << params[3], params[4], params[5]; - height = viewer_distance = params[6]; + viewer_distance = params[6]; } else if (params.size() == 6) { type = Camera::VECTOR; eye << params[0], params[1], params[2]; @@ -69,28 +69,20 @@ void Camera::viewAll(const BoundingBox &bbox) } } - switch (this->projection) { - case Camera::ORTHOGONAL: - this->height = this->viewer_distance = bbox.diagonal().norm(); + double bboxRadius = bbox.diagonal().norm()/2; + double radius = (bbox.center()-this->center).norm() + bboxRadius; + double distance = radius / sin(this->fov/2*M_PI/180); + switch (this->type) { + case Camera::GIMBAL: + this->viewer_distance = distance; + break; + case Camera::VECTOR: { + Vector3d cameradir = (this->center - this->eye).normalized(); + this->eye = this->center - distance*cameradir; break; - case Camera::PERSPECTIVE: { - double bboxRadius = bbox.diagonal().norm()/2; - double radius = (bbox.center()-this->center).norm() + bboxRadius; - double distance = radius / sin(this->fov*M_PI/360); - switch (this->type) { - case Camera::GIMBAL: - this->height = this->viewer_distance = distance; - break; - case Camera::VECTOR: { - Vector3d cameradir = (this->center - this->eye).normalized(); - this->eye = this->center - distance*cameradir; - break; - } - default: - assert(false && "Camera type not specified"); - } } - break; + default: + assert(false && "Camera type not specified"); } PRINTDB("modified center x y z %f %f %f",center.x() % center.y() % center.z()); PRINTDB("modified eye x y z %f %f %f",eye.x() % eye.y() % eye.z()); @@ -100,7 +92,7 @@ void Camera::viewAll(const BoundingBox &bbox) void Camera::zoom(int delta) { - this->height = this->viewer_distance *= pow(0.9, delta / 120.0); + this->viewer_distance *= pow(0.9, delta / 120.0); } void Camera::setProjection(ProjectionType type) @@ -113,12 +105,12 @@ void Camera::resetView() type = Camera::GIMBAL; object_rot << 35, 0, -25; object_trans << 0, 0, 0; - height = viewer_distance = 140; + viewer_distance = 140; } double Camera::zoomValue() { - return this->projection == PERSPECTIVE ? viewer_distance : height; + return viewer_distance; } std::string Camera::statusText() @@ -126,6 +118,6 @@ std::string Camera::statusText() boost::format fmt(_("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f")); fmt % object_trans.x() % object_trans.y() % object_trans.z() % object_rot.x() % object_rot.y() % object_rot.z() - % (this->projection == PERSPECTIVE ? viewer_distance : height); + % viewer_distance; return fmt.str(); } diff --git a/src/GLView.cc b/src/GLView.cc index 9c9e905b..4ea00abd 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -95,22 +95,21 @@ void GLView::setupCamera() switch (this->cam.type) { case Camera::GIMBAL: { - double eyeY = 0.0; + double dist = cam.zoomValue(); switch (this->cam.projection) { case Camera::PERSPECTIVE: { - eyeY = cam.zoomValue(); - gluPerspective(cam.fov, aspectratio, 0.1 * eyeY, 100 * eyeY); + gluPerspective(cam.fov, aspectratio, 0.1*dist, 100*dist); break; } case Camera::ORTHOGONAL: { - eyeY = cam.zoomValue(); - glOrtho(-eyeY/2*aspectratio, eyeY*aspectratio/2, - -eyeY/2, eyeY/2, + double height = dist * tan(cam.fov/2*M_PI/180); + glOrtho(-height*aspectratio, height*aspectratio, + -height, height, -far_far_away, +far_far_away); break; } } - gluLookAt(0.0, -eyeY, 0.0, + gluLookAt(0.0, -dist, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); @@ -121,16 +120,16 @@ void GLView::setupCamera() break; } case Camera::VECTOR: { + double dist = (cam.center - cam.eye).norm(); switch (this->cam.projection) { case Camera::PERSPECTIVE: { - double dist = (cam.center - cam.eye).norm(); gluPerspective(cam.fov, aspectratio, 0.1*dist, 100*dist); break; } case Camera::ORTHOGONAL: { - double height = cam.zoomValue(); - glOrtho(-height/2*aspectratio, height*aspectratio/2, - -height/2, height/2, + double height = dist * tan(cam.fov/2*M_PI/180); + glOrtho(-height*aspectratio, height*aspectratio, + -height, height, -far_far_away, +far_far_away); break; }