diff options
-rw-r--r-- | src/Camera.h | 88 | ||||
-rw-r--r-- | src/GLView.cc | 52 | ||||
-rw-r--r-- | src/GLView.h | 20 | ||||
-rw-r--r-- | src/QGLView.cc | 48 | ||||
-rw-r--r-- | src/export_png.cc | 15 | ||||
-rw-r--r-- | src/mainwin.cc | 32 | ||||
-rw-r--r-- | src/openscad.cc | 6 |
7 files changed, 124 insertions, 137 deletions
diff --git a/src/Camera.h b/src/Camera.h index 8dd6f68..b35ef0c 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -1,64 +1,68 @@ #ifndef OPENSCAD_CAMERA_H_ #define OPENSCAD_CAMERA_H_ -// Cameras -// For usage, see GLView.cc / export_png.cc / openscad.cc +/* + +Camera + +For usage, see *View.cc / export_png.cc / openscad.cc + +There are two different types of cameras represented in this class: + +*Gimbal camera - uses Euler Angles, object translation, and viewer distance +*Vector camera - uses 'eye', 'center', and 'up' vectors ('lookat' style) + +*/ #include <vector> #include <Eigen/Geometry> #include <boost/variant.hpp> -class GimbalCamera +class Camera { public: - GimbalCamera() - { - object_trans << 0,0,0; - object_rot << 35,0,25; - viewer_distance = 500; + enum CameraType { NONE, GIMBAL, VECTOR } type; + Camera() { + type = Camera::NONE; } - GimbalCamera( std::vector<double> d ) + Camera( enum CameraType e ) { - assert( d.size() == 7 ); - object_trans << d[0], d[1], d[2]; - object_rot << d[3], d[4], d[5]; - viewer_distance = d[6]; + type = e; + if ( e == Camera::GIMBAL ) { + object_trans << 0,0,0; + object_rot << 35,0,25; + viewer_distance = 500; + } else if ( e == Camera::VECTOR ) { + center << 0,0,0; + Eigen::Vector3d cameradir(1, 1, -0.5); + eye = center - 500 * cameradir; + } } - Eigen::Vector3d object_trans; - Eigen::Vector3d object_rot; - double viewer_distance; -}; -class VectorCamera -{ -public: - VectorCamera() - { - center << 0,0,0; - Eigen::Vector3d cameradir(1, 1, -0.5); - eye = center - 500 * cameradir; - // "up" not currently used - } - VectorCamera( std::vector<double> d ) - { - assert( d.size() == 6 ); - eye << d[0], d[1], d[2]; - center << d[3], d[4], d[5]; + void setup( std::vector<double> params ) { + if ( params.size() == 7 ) { + type = Camera::GIMBAL; + object_trans << params[0], params[1], params[2]; + object_rot << params[3], params[4], params[5]; + viewer_distance = params[6]; + } else if ( params.size() == 6 ) { + type = Camera::VECTOR; + eye << params[0], params[1], params[2]; + center << params[3], params[4], params[5]; + } else { + assert( "Gimbal cam needs 7 numbers, Vector camera needs 6" ); + } } + + // Vectorcam Eigen::Vector3d eye; Eigen::Vector3d center; // (aka 'target') Eigen::Vector3d up; -}; -class Camera -{ -public: - enum CameraType { NONE, GIMBAL, VECTOR } type; - Camera() { type = Camera::NONE; } - void set( VectorCamera &c ) { vcam = c; type = Camera::VECTOR; } - void set( GimbalCamera &c ) { gcam = c; type = Camera::GIMBAL; } - GimbalCamera gcam; - VectorCamera vcam; + // Gimbalcam + Eigen::Vector3d object_trans; + Eigen::Vector3d object_rot; + double viewer_distance; }; diff --git a/src/GLView.cc b/src/GLView.cc index 6586ba2..77c3375 100644 --- a/src/GLView.cc +++ b/src/GLView.cc @@ -17,7 +17,7 @@ GLView::GLView() showaxes = false; showcrosshairs = false; renderer = NULL; - camtype = Camera::NONE; + cam.type = Camera::NONE; #ifdef ENABLE_OPENCSG is_opencsg_capable = false; has_shaders = false; @@ -50,7 +50,7 @@ void GLView::setupGimbalCamPerspective() glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-w_h_ratio, +w_h_ratio, -(1/w_h_ratio), +(1/w_h_ratio), +10.0, +FAR_FAR_AWAY); - gluLookAt(0.0, -gcam.viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); + gluLookAt(0.0, -cam.viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); } void GLView::setupGimbalCamOrtho(double distance, bool offset) @@ -63,14 +63,14 @@ void GLView::setupGimbalCamOrtho(double distance, bool offset) glOrtho(-w_h_ratio*l, +w_h_ratio*l, -(1/w_h_ratio)*l, +(1/w_h_ratio)*l, -FAR_FAR_AWAY, +FAR_FAR_AWAY); - gluLookAt(0.0, -gcam.viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); + gluLookAt(0.0, -cam.viewer_distance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); } void GLView::setupVectorCamPerspective() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); - double dist = (vcam.center - vcam.eye).norm(); + double dist = (cam.center - cam.eye).norm(); gluPerspective(45, w_h_ratio, 0.1*dist, 100*dist); } @@ -79,7 +79,7 @@ void GLView::setupVectorCamOrtho(bool offset) glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (offset) glTranslated(-0.8, -0.8, 0); - double l = (vcam.center - vcam.eye).norm() / 10; + double l = (cam.center - cam.eye).norm() / 10; glOrtho(-w_h_ratio*l, +w_h_ratio*l, -(1/w_h_ratio)*l, +(1/w_h_ratio)*l, -FAR_FAR_AWAY, +FAR_FAR_AWAY); @@ -87,20 +87,16 @@ void GLView::setupVectorCamOrtho(bool offset) void GLView::setCamera( Camera &cam ) { - camtype = cam.type; - if ( camtype == Camera::GIMBAL ) { - gcam = cam.gcam; - } else if ( camtype == Camera::VECTOR ) { - vcam = cam.vcam; - gcam.viewer_distance = 10*3*(vcam.center - vcam.eye).norm(); - } + this->cam = cam; + // kludge to make showAxes() work on vector camera + cam.viewer_distance = 10*3*(cam.center - cam.eye).norm(); } void GLView::paintGL() { - if (camtype == Camera::NONE) return; - else if (camtype == Camera::GIMBAL) gimbalCamPaintGL(); - else if (camtype == Camera::VECTOR) vectorCamPaintGL(); + if (cam.type == Camera::NONE) return; + else if (cam.type == Camera::GIMBAL) gimbalCamPaintGL(); + else if (cam.type == Camera::VECTOR) vectorCamPaintGL(); } #ifdef ENABLE_OPENCSG @@ -293,8 +289,8 @@ void GLView::vectorCamPaintGL() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - gluLookAt(vcam.eye[0], vcam.eye[1], vcam.eye[2], - vcam.center[0], vcam.center[1], vcam.center[2], + gluLookAt(cam.eye[0], cam.eye[1], cam.eye[2], + cam.center[0], cam.center[1], cam.center[2], 0.0, 0.0, 1.0); // fixme - showcrosshairs doesnt work with vector camera @@ -320,7 +316,7 @@ void GLView::gimbalCamPaintGL() { glEnable(GL_LIGHTING); - if (orthomode) GLView::setupGimbalCamOrtho(gcam.viewer_distance); + if (orthomode) GLView::setupGimbalCamOrtho(cam.viewer_distance); else GLView::setupGimbalCamPerspective(); glMatrixMode(GL_MODELVIEW); @@ -331,13 +327,13 @@ void GLView::gimbalCamPaintGL() glClearColor(bgcol[0], bgcol[1], bgcol[2], 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glRotated(gcam.object_rot.x(), 1.0, 0.0, 0.0); - glRotated(gcam.object_rot.y(), 0.0, 1.0, 0.0); - glRotated(gcam.object_rot.z(), 0.0, 0.0, 1.0); + glRotated(cam.object_rot.x(), 1.0, 0.0, 0.0); + glRotated(cam.object_rot.y(), 0.0, 1.0, 0.0); + glRotated(cam.object_rot.z(), 0.0, 0.0, 1.0); if (showcrosshairs) GLView::showCrosshairs(); - glTranslated(gcam.object_trans.x(), gcam.object_trans.y(), gcam.object_trans.z() ); + glTranslated(cam.object_trans.x(), cam.object_trans.y(), cam.object_trans.z() ); if (showaxes) GLView::showAxes(); @@ -360,7 +356,7 @@ void GLView::gimbalCamPaintGL() void GLView::showSmallaxes() { - // Fixme - this modifies the camera and doesnt work in 'non-gimbal' camera mode + // Fixme - this doesnt work in Vector Camera mode // Small axis cross in the lower left corner glDepthFunc(GL_ALWAYS); @@ -369,9 +365,9 @@ void GLView::showSmallaxes() glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glRotated(gcam.object_rot.x(), 1.0, 0.0, 0.0); - glRotated(gcam.object_rot.y(), 0.0, 1.0, 0.0); - glRotated(gcam.object_rot.z(), 0.0, 0.0, 1.0); + glRotated(cam.object_rot.x(), 1.0, 0.0, 0.0); + glRotated(cam.object_rot.y(), 0.0, 1.0, 0.0); + glRotated(cam.object_rot.z(), 0.0, 0.0, 1.0); glLineWidth(1); glBegin(GL_LINES); @@ -446,7 +442,7 @@ void GLView::showAxes() glLineWidth(1); glColor3d(0.5, 0.5, 0.5); glBegin(GL_LINES); - double l = gcam.viewer_distance/10; + double l = cam.viewer_distance/10; glVertex3d(-l, 0, 0); glVertex3d(+l, 0, 0); glVertex3d(0, -l, 0); @@ -467,7 +463,7 @@ void GLView::showCrosshairs() glBegin(GL_LINES); for (double xf = -1; xf <= +1; xf += 2) for (double yf = -1; yf <= +1; yf += 2) { - double vd = gcam.viewer_distance/20; + double vd = cam.viewer_distance/20; glVertex3d(-xf*vd, -yf*vd, -vd); glVertex3d(+xf*vd, +yf*vd, +vd); } diff --git a/src/GLView.h b/src/GLView.h index dae402a..e06296b 100644 --- a/src/GLView.h +++ b/src/GLView.h @@ -8,18 +8,12 @@ This class is inherited by: *QGLview - for Qt GUI *OffscreenView - for offscreen rendering, in tests and from command-line -There are two different types of cameras: +The view assumes either a Gimbal Camera (rotation,translation,distance) +or Vector Camera (eye,center/target) is being used. See Camera.h. The +cameras are not kept in sync. -*Gimbal camera - uses Euler Angles, object translation, and viewer distance -*Vector camera - uses 'eye', 'center', and 'up' vectors ('lookat' style) - -They are selectable by creating a GimbalCamera or VectorCamera (Camera.h) -and then calling GLView.setCamera(). - -Currently, the camera is set in two separate variables that are not kept -in sync. Some actions (showCrossHairs) only work properly on Gimbal -Camera. QGLView uses GimbalCamera while OffscreenView can use either one -(defaulting to Vector). +QGLView only uses GimbalCamera while OffscreenView can use either one. +Some actions (showCrossHairs) only work properly on Gimbal Camera. */ @@ -73,9 +67,7 @@ public: bool showedges; bool showcrosshairs; - Camera::CameraType camtype; - VectorCamera vcam; - GimbalCamera gcam; + Camera cam; #ifdef ENABLE_OPENCSG GLint shaderinfo[11]; diff --git a/src/QGLView.cc b/src/QGLView.cc index bbb67ca..dc3e467 100644 --- a/src/QGLView.cc +++ b/src/QGLView.cc @@ -63,10 +63,10 @@ static bool running_under_wine = false; void QGLView::init() { - camtype = Camera::GIMBAL; - gcam.object_rot << 35, 0, -25; - gcam.object_trans << 0, 0, 0; - gcam.viewer_distance = 500; + cam.type = Camera::GIMBAL; + cam.object_rot << 35, 0, -25; + cam.object_trans << 0, 0, 0; + cam.viewer_distance = 500; this->mouse_drag_active = false; this->statusLabel = NULL; @@ -152,8 +152,8 @@ void QGLView::paintGL() if (statusLabel) { QString msg; msg.sprintf("Viewport: translate = [ %.2f %.2f %.2f ], rotate = [ %.2f %.2f %.2f ], distance = %.2f", - -gcam.object_trans.x(), -gcam.object_trans.y(), -gcam.object_trans.z(), - fmodf(360 - gcam.object_rot.x() + 90, 360), fmodf(360 - gcam.object_rot.y(), 360), fmodf(360 - gcam.object_rot.z(), 360), gcam.viewer_distance); + -cam.object_trans.x(), -cam.object_trans.y(), -cam.object_trans.z(), + fmodf(360 - cam.object_rot.x() + 90, 360), fmodf(360 - cam.object_rot.y(), 360), fmodf(360 - cam.object_rot.z(), 360), cam.viewer_distance); statusLabel->setText(msg); } @@ -163,12 +163,12 @@ void QGLView::paintGL() void QGLView::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Plus) { - gcam.viewer_distance *= 0.9; + cam.viewer_distance *= 0.9; updateGL(); return; } if (event->key() == Qt::Key_Minus) { - gcam.viewer_distance /= 0.9; + cam.viewer_distance /= 0.9; updateGL(); return; } @@ -176,7 +176,7 @@ void QGLView::keyPressEvent(QKeyEvent *event) void QGLView::wheelEvent(QWheelEvent *event) { - gcam.viewer_distance *= pow(0.9, event->delta() / 120.0); + cam.viewer_distance *= pow(0.9, event->delta() / 120.0); updateGL(); } @@ -207,25 +207,25 @@ void QGLView::mouseMoveEvent(QMouseEvent *event) ) { // Left button rotates in xz, Shift-left rotates in xy // On Mac, Ctrl-Left is handled as right button on other platforms - gcam.object_rot.x() += dy; + cam.object_rot.x() += dy; if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0) - gcam.object_rot.y() += dx; + cam.object_rot.y() += dx; else - gcam.object_rot.z() += dx; + cam.object_rot.z() += dx; - normalizeAngle(gcam.object_rot.x()); - normalizeAngle(gcam.object_rot.y()); - normalizeAngle(gcam.object_rot.z()); + normalizeAngle(cam.object_rot.x()); + normalizeAngle(cam.object_rot.y()); + normalizeAngle(cam.object_rot.z()); } else { // Right button pans in the xz plane // Middle button pans in the xy plane // Shift-right and Shift-middle zooms if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0) { - gcam.viewer_distance += (GLdouble)dy; + cam.viewer_distance += (GLdouble)dy; } else { - double mx = +(dx) * gcam.viewer_distance/1000; - double mz = -(dy) * gcam.viewer_distance/1000; + double mx = +(dx) * cam.viewer_distance/1000; + double mz = -(dy) * cam.viewer_distance/1000; double my = 0; #if (QT_VERSION < QT_VERSION_CHECK(4, 7, 0)) @@ -241,9 +241,9 @@ void QGLView::mouseMoveEvent(QMouseEvent *event) } Matrix3d aax, aay, aaz, tm3; - aax = Eigen::AngleAxisd(-(gcam.object_rot.x()/180) * M_PI, Vector3d::UnitX()); - aay = Eigen::AngleAxisd(-(gcam.object_rot.y()/180) * M_PI, Vector3d::UnitY()); - aaz = Eigen::AngleAxisd(-(gcam.object_rot.z()/180) * M_PI, Vector3d::UnitZ()); + aax = Eigen::AngleAxisd(-(cam.object_rot.x()/180) * M_PI, Vector3d::UnitX()); + aay = Eigen::AngleAxisd(-(cam.object_rot.y()/180) * M_PI, Vector3d::UnitY()); + aaz = Eigen::AngleAxisd(-(cam.object_rot.z()/180) * M_PI, Vector3d::UnitZ()); tm3 = Matrix3d::Identity(); tm3 = aaz * (aay * (aax * tm3)); @@ -259,9 +259,9 @@ void QGLView::mouseMoveEvent(QMouseEvent *event) 0, 0, 0, 1 ; tm = tm * vec; - gcam.object_trans.x() += tm(0,3); - gcam.object_trans.y() += tm(1,3); - gcam.object_trans.z() += tm(2,3); + cam.object_trans.x() += tm(0,3); + cam.object_trans.y() += tm(1,3); + cam.object_trans.z() += tm(2,3); } } updateGL(); diff --git a/src/export_png.cc b/src/export_png.cc index bedc230..a8c7620 100644 --- a/src/export_png.cc +++ b/src/export_png.cc @@ -36,12 +36,11 @@ void export_png_with_cgal(CGAL_Nef_polyhedron *root_N, Camera &cam, std::ostream } if (cam.type == Camera::NONE) { - VectorCamera vcam; - vcam.center = getBoundingCenter(bbox); + cam.type = Camera::VECTOR; + cam.center = getBoundingCenter(bbox); double radius = getBoundingRadius(bbox); Vector3d cameradir(1, 1, -0.5); - vcam.eye = vcam.center - radius*2*cameradir; - cam.set(vcam); + cam.eye = cam.center - radius*2*cameradir; } //std::cerr << center << "\n"; @@ -79,17 +78,15 @@ void export_png_with_opencsg(Tree &tree, Camera &cam, std::ostream &output) OpenCSGRenderer opencsgRenderer(csgInfo.root_chain, csgInfo.highlights_chain, csgInfo.background_chain, csgInfo.glview->shaderinfo); if (cam.type == Camera::NONE) { - VectorCamera vcam; - vcam.center << 0,0,0; + cam.center << 0,0,0; double radius = 1.0; if (csgInfo.root_chain) { BoundingBox bbox = csgInfo.root_chain->getBoundingBox(); - vcam.center = (bbox.min() + bbox.max()) / 2; + cam.center = (bbox.min() + bbox.max()) / 2; radius = (bbox.max() - bbox.min()).norm() / 2; } Vector3d cameradir(1, 1, -0.5); - vcam.eye = vcam.center - radius*1.8*cameradir; - cam.set(vcam); + cam.eye = cam.center - radius*1.8*cameradir; } csgInfo.glview->setCamera( cam ); diff --git a/src/mainwin.cc b/src/mainwin.cc index da6149c..c82e949 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -964,7 +964,7 @@ void MainWindow::pasteViewportTranslation() { QTextCursor cursor = editor->textCursor(); QString txt; - txt.sprintf("[ %.2f, %.2f, %.2f ]", -qglview->gcam.object_trans.x(), -qglview->gcam.object_trans.y(), -qglview->gcam.object_trans.z()); + txt.sprintf("[ %.2f, %.2f, %.2f ]", -qglview->cam.object_trans.x(), -qglview->cam.object_trans.y(), -qglview->cam.object_trans.z()); cursor.insertText(txt); } @@ -973,7 +973,7 @@ void MainWindow::pasteViewportRotation() QTextCursor cursor = editor->textCursor(); QString txt; txt.sprintf("[ %.2f, %.2f, %.2f ]", - fmodf(360 - qglview->gcam.object_rot.x() + 90, 360), fmodf(360 - qglview->gcam.object_rot.y(), 360), fmodf(360 - qglview->gcam.object_rot.z(), 360)); + fmodf(360 - qglview->cam.object_rot.x() + 90, 360), fmodf(360 - qglview->cam.object_rot.y(), 360), fmodf(360 - qglview->cam.object_rot.z(), 360)); cursor.insertText(txt); } @@ -982,15 +982,15 @@ void MainWindow::updateTemporalVariables() this->root_ctx.set_variable("$t", Value(this->e_tval->text().toDouble())); Value::VectorType vpt; - vpt.push_back(Value(-qglview->gcam.object_trans.x())); - vpt.push_back(Value(-qglview->gcam.object_trans.y())); - vpt.push_back(Value(-qglview->gcam.object_trans.z())); + vpt.push_back(Value(-qglview->cam.object_trans.x())); + vpt.push_back(Value(-qglview->cam.object_trans.y())); + vpt.push_back(Value(-qglview->cam.object_trans.z())); this->root_ctx.set_variable("$vpt", Value(vpt)); Value::VectorType vpr; - vpr.push_back(Value(fmodf(360 - qglview->gcam.object_rot.x() + 90, 360))); - vpr.push_back(Value(fmodf(360 - qglview->gcam.object_rot.y(), 360))); - vpr.push_back(Value(fmodf(360 - qglview->gcam.object_rot.z(), 360))); + vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.x() + 90, 360))); + vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.y(), 360))); + vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.z(), 360))); root_ctx.set_variable("$vpr", Value(vpr)); } @@ -1617,49 +1617,49 @@ void MainWindow::animateUpdate() void MainWindow::viewAngleTop() { - qglview->gcam.object_rot << 90,0,0; + qglview->cam.object_rot << 90,0,0; this->qglview->updateGL(); } void MainWindow::viewAngleBottom() { - qglview->gcam.object_rot << 270,0,0; + qglview->cam.object_rot << 270,0,0; this->qglview->updateGL(); } void MainWindow::viewAngleLeft() { - qglview->gcam.object_rot << 0,0,90; + qglview->cam.object_rot << 0,0,90; this->qglview->updateGL(); } void MainWindow::viewAngleRight() { - qglview->gcam.object_rot << 0,0,270; + qglview->cam.object_rot << 0,0,270; this->qglview->updateGL(); } void MainWindow::viewAngleFront() { - qglview->gcam.object_rot << 0,0,0; + qglview->cam.object_rot << 0,0,0; this->qglview->updateGL(); } void MainWindow::viewAngleBack() { - qglview->gcam.object_rot << 0,0,180; + qglview->cam.object_rot << 0,0,180; this->qglview->updateGL(); } void MainWindow::viewAngleDiagonal() { - qglview->gcam.object_rot << 35,0,-25; + qglview->cam.object_rot << 35,0,-25; this->qglview->updateGL(); } void MainWindow::viewCenter() { - qglview->gcam.object_trans << 0,0,0; + qglview->cam.object_trans << 0,0,0; this->qglview->updateGL(); } diff --git a/src/openscad.cc b/src/openscad.cc index 5c8fe31..e7ab795 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -112,8 +112,7 @@ Camera determine_camera( po::variables_map vm ) } else { BOOST_FOREACH(string &s, strs) cam_parameters.push_back(lexical_cast<double>(s)); - GimbalCamera gcam( cam_parameters ); - camera.set( gcam ); + camera.setup( cam_parameters ); } } @@ -127,8 +126,7 @@ Camera determine_camera( po::variables_map vm ) } else { BOOST_FOREACH(string &s, strs) cam_parameters.push_back(lexical_cast<double>(s)); - VectorCamera vcam( cam_parameters ); - camera.set( vcam ); + camera.setup( cam_parameters ); } } |