diff options
author | Maxime Curioni <maxime.curioni@gmail.com> | 2008-12-11 00:51:58 +0300 |
---|---|---|
committer | Maxime Curioni <maxime.curioni@gmail.com> | 2008-12-11 00:51:58 +0300 |
commit | d15321082e12385161afe8c7f364ec535dd5ce95 (patch) | |
tree | ffb93b64e81ddd86b549fe94bf0fc53e6d1aac53 | |
parent | 8b3e4bc069620a70da003f9ddff963db69ed297b (diff) |
removed AppGLWidget and all related classes
added an AppView class to transfer camera information from Blender to Freestyle
removed unused functions
24 files changed, 442 insertions, 7689 deletions
diff --git a/source/blender/freestyle/intern/app_blender/AppCanvas.cpp b/source/blender/freestyle/intern/app_blender/AppCanvas.cpp index ccd6a771dc7..848d8ce08bb 100755 --- a/source/blender/freestyle/intern/app_blender/AppCanvas.cpp +++ b/source/blender/freestyle/intern/app_blender/AppCanvas.cpp @@ -21,7 +21,7 @@ #include "../rendering/GLBlendEquation.h" -#include "AppGLWidget.h" +#include "AppView.h" #include "../image/Image.h" #include "../system/TimeStamp.h" #include "Controller.h" @@ -40,7 +40,7 @@ AppCanvas::AppCanvas() _MapsPath = StringUtils::toAscii( Config::Path::getInstance()->getMapsDir() ).c_str(); } -AppCanvas::AppCanvas(AppGLWidget* iViewer) +AppCanvas::AppCanvas(AppView* iViewer) :Canvas() { _pViewer = iViewer; @@ -57,7 +57,7 @@ AppCanvas::~AppCanvas() _pViewer = 0; } -void AppCanvas::setViewer(AppGLWidget *iViewer) +void AppCanvas::setViewer(AppView *iViewer) { _pViewer = iViewer; } @@ -69,7 +69,7 @@ int AppCanvas::width() const int AppCanvas::height() const { - return _pViewer->height(); + return _pViewer->height();; } BBox<Vec3r> AppCanvas::scene3DBBox() const diff --git a/source/blender/freestyle/intern/app_blender/AppCanvas.h b/source/blender/freestyle/intern/app_blender/AppCanvas.h index 7990cf84cc6..fa8d3cba373 100755 --- a/source/blender/freestyle/intern/app_blender/AppCanvas.h +++ b/source/blender/freestyle/intern/app_blender/AppCanvas.h @@ -2,15 +2,14 @@ #define ARTCANVAS_H #include "../stroke/Canvas.h" +#include "AppView.h" -//class AppGLWidget; class AppCanvas : public Canvas { -private: - mutable AppGLWidget *_pViewer; + public: AppCanvas(); - AppCanvas(AppGLWidget *iViewer); + AppCanvas(AppView *iViewer); AppCanvas(const AppCanvas& iBrother); virtual ~AppCanvas(); @@ -41,10 +40,12 @@ public: /*! accessors */ virtual int width() const ; virtual int height() const ; - inline const AppGLWidget * viewer() const {return _pViewer;} + + AppView *_pViewer; + inline const AppView * viewer() const {return _pViewer;} /*! modifiers */ - void setViewer(AppGLWidget *iViewer) ; + void setViewer(AppView *iViewer) ; }; diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget.cpp b/source/blender/freestyle/intern/app_blender/AppGLWidget.cpp deleted file mode 100755 index e0ab9b439d5..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget.cpp +++ /dev/null @@ -1,589 +0,0 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#include <iostream> -#include "../stroke/Canvas.h" -#include "AppGLWidget.h" -#include "../scene_graph/NodeLight.h" -#include "../rendering/GLRenderer.h" -#include "../rendering/GLSelectRenderer.h" -#include "../rendering/GLBBoxRenderer.h" -#include "../rendering/GLMonoColorRenderer.h" -#include "Controller.h" -#include "../view_map/Silhouette.h" -#include "../view_map/ViewMap.h" -#include "../scene_graph/LineRep.h" -#include "../scene_graph/NodeShape.h" -#include "../scene_graph/VertexRep.h" -#include "AppConfig.h" -#include "AppCanvas.h" - -#include "../system/StringUtils.h" - -extern "C" { -#include "BLI_blenlib.h" -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" -} - -// glut.h must be included last to avoid a conflict with stdlib.h on vc .net 2003 and 2005 -#ifdef __MACH__ -# include <GLUT/glut.h> -#else -# ifdef _WIN32 -# include <GL/glu.h> -# else -# include <GL/glut.h> -# endif -#endif - -GLuint texture = 0; - -bool AppGLWidget::_frontBufferFlag = false; -bool AppGLWidget::_backBufferFlag = true; - -AppGLWidget::AppGLWidget(const char *iName) -{ - //soc - _camera = new AppGLWidget_Camera; - - _Fovy = 30.f; - //_SceneDepth = 2.f; - _RenderStyle = LINE; - //_ModelRootNode->setBBox(BBox<Vec3f>(Vec3f(-10.f, -10.f, -10.f), Vec3f(10.f, 10.f, 10.f))); - _ModelRootNode = new NodeDrawingStyle; - _SilhouetteRootNode = new NodeDrawingStyle; - _DebugRootNode = new NodeDrawingStyle; - - _RootNode.AddChild(_ModelRootNode); - _SilhouetteRootNode->setStyle(DrawingStyle::LINES); - _SilhouetteRootNode->setLightingEnabled(false); - _SilhouetteRootNode->setLineWidth(2.f); - _SilhouetteRootNode->setPointSize(3.f); - - _RootNode.AddChild(_SilhouetteRootNode); - - _DebugRootNode->setStyle(DrawingStyle::LINES); - _DebugRootNode->setLightingEnabled(false); - _DebugRootNode->setLineWidth(1.f); - - _RootNode.AddChild(_DebugRootNode); - - _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], - _ModelRootNode->bbox().getMin()[1]), - _ModelRootNode->bbox().getMin()[2]); - _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], - _ModelRootNode->bbox().getMax()[1]), - _ModelRootNode->bbox().getMax()[2]); - - _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); - _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); - - _camera->setZNearCoefficient(0.1); - - // 2D Scene - // _pFENode = new NodeDrawingStyle; - // _pFENode->setStyle(DrawingStyle::LINES); - // _pFENode->setLightingEnabled(false); - // _pFENode->setLineWidth(1.f); - // - // _p2DNode.AddChild(_pFENode); - // - // _pVisibleSilhouetteNode = new NodeDrawingStyle; - // _pVisibleSilhouetteNode->setStyle(DrawingStyle::LINES); - // _pVisibleSilhouetteNode->setLightingEnabled(false); - // _pVisibleSilhouetteNode->setLineWidth(3.f); - // - // _p2DNode.AddChild(_pVisibleSilhouetteNode); - // - _p2DSelectionNode = new NodeDrawingStyle; - _p2DSelectionNode->setLightingEnabled(false); - _p2DSelectionNode->setStyle(DrawingStyle::LINES); - _p2DSelectionNode->setLineWidth(5.f); - - _p2DNode.AddChild(_p2DSelectionNode); - - _pGLRenderer = new GLRenderer; - _pSelectRenderer = new GLSelectRenderer; - _pBBoxRenderer = new GLBBoxRenderer; - _pMonoColorRenderer = new GLMonoColorRenderer; - _pDebugRenderer = new GLDebugRenderer; - - _pMainWindow = NULL; - _cameraStateSaved = false; - _drawBBox = false; - _silhouette = false; - _fedges = false; - _debug = false; - _selection_mode = false; - _Draw2DScene = true; - _Draw3DScene = false; - _drawEnvMap = false; - _currentEnvMap = 1; - _maxId = 0; - _blendFunc = 0; - - const string sep(Config::DIR_SEP); - const string filename = Config::Path::getInstance()->getHomeDir() + sep + - Config::OPTIONS_DIR + sep + Config::OPTIONS_QGLVIEWER_FILE; - setStateFileName(filename); - - //get camera frame: - //qglviewer::Camera * cam = camera(); - //qglviewer::ManipulatedFrame * fr = cam->frame() ; - - //soc _enableupdateSilhouettes = false; - - _captureMovie = false; - // _frontBufferFlag = false; - // _backBufferFlag = true; - _record = false; - - - workingBuffer = GL_BACK; //soc - -} - -AppGLWidget::~AppGLWidget() -{ - int ref = _RootNode.destroy(); - - _Light.destroy(); - ref = _p2DNode.destroy(); - - if(NULL != _pGLRenderer) - { - delete _pGLRenderer; - _pGLRenderer = NULL; - } - - if(NULL != _pSelectRenderer) - { - delete _pSelectRenderer; - _pSelectRenderer = NULL; - } - - if(NULL != _pBBoxRenderer) - { - delete _pBBoxRenderer; - _pBBoxRenderer = NULL; - } - - if(NULL != _pMonoColorRenderer) - { - delete _pMonoColorRenderer; - _pMonoColorRenderer = NULL; - } - - if(NULL != _pDebugRenderer) - { - delete _pDebugRenderer; - _pDebugRenderer = NULL; - } - - //saveToFile(filename); -} - - - -void AppGLWidget::LoadEnvMap(const char *filename) -{ - GLuint textureId; - //sgiImage img; - //cout << filename << endl; - ImBuf *image = IMB_loadiffname(filename, 0); - - //data = img.read(filename); // tres beau bleu gris mauve!! - // allocate a texture name - glGenTextures( 1, &textureId ); - if(textureId > (GLuint) _maxId) - _maxId = textureId; - - // select our current texture - glBindTexture( GL_TEXTURE_2D, textureId ); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - - glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, image->x, image->y, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image->rect ); -} - -void AppGLWidget::init() -{ - //setShortcut(QGLViewer::EXIT_VIEWER, 0); -// setShortcut(QGLViewer::DISPLAY_Z_BUFFER, 0); - //setShortcut(QGLViewer::STEREO, 0); - //setShortcut(QGLViewer::ANIMATION, 0); - //setShortcut(QGLViewer::EDIT_CAMERA, 0); - - //restoreStateFromFile(); - - //trackball().fitBBox(_ModelRootNode->bbox().getMin(), _ModelRootNode->bbox().getMax(), _Fovy); - - glClearColor(1,1,1,0); - glShadeModel(GL_SMOOTH); - - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - - // open and read texture data - Config::Path * cpath = Config::Path::getInstance(); - string envmapDir = cpath->getEnvMapDir(); - LoadEnvMap( StringUtils::toAscii(envmapDir + string("gray00.png")).c_str() ); - //LoadEnvMap(Config::ENV_MAP_DIR + "gray01.bmp"); - LoadEnvMap( StringUtils::toAscii(envmapDir + string("gray02.png")).c_str() ); - LoadEnvMap( StringUtils::toAscii(envmapDir + string("gray03.png")).c_str() ); - LoadEnvMap( StringUtils::toAscii(envmapDir + string("brown00.png")).c_str() ); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP) ; - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP) ; - - // gl settings for Environmental Texturing: - glColor3f(1, 1, 1); - - // Use GL auto-computed enviroment texture coordinates - //glEnable(GL_TEXTURE_GEN_S); - //glEnable(GL_TEXTURE_GEN_T); - - // Bind the texture to use - //glBindTexture(GL_TEXTURE_2D,texture); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - // parametres de melange - //glBlendFunc(GL_ONE, GL_ONE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - //glBlendEquatio(GL_FUNC_ADD); - - //glEnable(GL_BLEND); - NodeLight *light = new NodeLight; - _Light.AddChild(light); - - cout << "Renderer (GL) : " << glGetString(GL_RENDERER) << endl - << "Vendor (GL) : " << glGetString(GL_VENDOR) << endl << endl; -} - -void AppGLWidget::draw() -{ - if (true == _Draw3DScene) - { - if (true == _selection_mode) { - _pSelectRenderer->setSelectRendering(false); - _pSelectRenderer->resetColor(); - DrawScene(_pSelectRenderer); - } else - DrawScene(_pGLRenderer); - - if (true == _silhouette) - DrawSilhouette(); - - if (true == _drawBBox) { - glPushAttrib(GL_ALL_ATTRIB_BITS); - _ModelRootNode->accept(*_pBBoxRenderer); - glPopAttrib(); - } - - if (true == _debug) { - glPushAttrib(GL_ALL_ATTRIB_BITS); - _DebugRootNode->accept(*_pDebugRenderer); - glPopAttrib(); - } - } - - if (true == _Draw2DScene) { - Draw2DScene(_pGLRenderer); - set3DContext(); - } -} - -void AppGLWidget::DrawScene(SceneVisitor *iRenderer) -{ - glPushAttrib(GL_ALL_ATTRIB_BITS); - - if(_drawEnvMap) - { - _ModelRootNode->setLightingEnabled(false); - glEnable(GL_COLOR_MATERIAL); - - glEnable(GL_TEXTURE_2D); - // Bind the texture to use - glBindTexture(GL_TEXTURE_2D,_currentEnvMap); - switch(_blendFunc) - { - case 0: - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ; - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - break; - case 1: - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) ; - glDisable(GL_BLEND); - break; - // case 2: - // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ; - // glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // glEnable(GL_BLEND); - // break; - // case 3: - // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ; - // glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); - // glEnable(GL_BLEND); - // break; - // case 4: - // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ; - // glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); - // glEnable(GL_BLEND); - // break; - default: - break; - } - - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - } - - // FIXME - // //_ModelRootNode->setLightingEnabled(true); - // if(_ModelRootNode->style() == DrawingStyle::LINES){ - // glPushAttrib(GL_ALL_ATTRIB_BITS); - // //glDisable(GL_COLOR_MATERIAL); - // _ModelRootNode->setStyle(DrawingStyle::FILLED); - // _ModelRootNode->setLightingEnabled(true); - // _ModelRootNode->accept(*iRenderer); - // _ModelRootNode->setStyle(DrawingStyle::LINES); - // _ModelRootNode->setLightingEnabled(false); - // _ModelRootNode->accept(*iRenderer); - // glPopAttrib(); - // } - // else - _ModelRootNode->accept(*iRenderer); - - glDisable(GL_TEXTURE_GEN_S); - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_2D); - glDisable(GL_COLOR_MATERIAL); - _ModelRootNode->setLightingEnabled(true); - - if(_fedges == true) - _SilhouetteRootNode->accept(*iRenderer); - - // FIXME: deprecated -// if(_debug == true) -// _DebugRootNode->accept(*iRenderer); - - glPopAttrib(); -} - -void AppGLWidget::Draw2DScene(SceneVisitor *iRenderer) -{ - static bool first = 1; - glPushAttrib(GL_ALL_ATTRIB_BITS); - -// // Projection Matrix -// //================== - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0,width(), 0, height(), -1.0, 1.0); - -// //Modelview Matrix -// //================ - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // glBegin(GL_LINE_LOOP); - // glVertex2f(0,0); - // glVertex2f(100,0); - // glVertex2f(100,100); - // glVertex2f(0,100); - // glEnd(); - - //glDrawBuffer(GL_FRONT_AND_BACK); - // Draw visible silhouette - //_pVisibleSilhouetteNode->Render(iRenderer); - Canvas * canvas = Canvas::getInstance(); - if((canvas) && (!canvas->isEmpty())) - { - if (first) - { - canvas->init(); - first = false; - } - canvas->Render(canvas->renderer()); - } - - glLoadIdentity(); - // glColor3f(0.f,1.f,0.f); - // glLineWidth(5.f); - //glPolygonOffset(0.5f, 0.5f); - glPushAttrib(GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); - _p2DSelectionNode->accept(*iRenderer); - glPopAttrib(); - // Draw Feature edges - // if(_fedges == true) - // { - // _pFENode->Render(iRenderer); - // } - - glPopAttrib(); -} - -void AppGLWidget::DrawSilhouette() -{ - glPushAttrib(GL_ALL_ATTRIB_BITS); - - glDepthFunc(GL_LESS); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - DrawScene(_pMonoColorRenderer); - - glCullFace(GL_FRONT); - glDepthFunc(GL_LEQUAL); - glEnable(GL_POLYGON_OFFSET_FILL); - glLineWidth(3.0); - //glPolygonOffset(10.f, 10.f); - glPolygonOffset(0.5f, 0.5f); - - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - _pMonoColorRenderer->setColor(0.f, 0.f, 0.f); - DrawScene(_pMonoColorRenderer); - - //Restore old context - glPopAttrib(); - -} - -void AppGLWidget::ReInitRenderers() -{ - // Debug Renderer - if(NULL != _pDebugRenderer) - _pDebugRenderer->ReInit(rabs(_ModelRootNode->bbox().getMax()[1] - - _ModelRootNode->bbox().getMin()[1])); -} - -void AppGLWidget::setFrontBufferFlag(bool iBool){ - _frontBufferFlag = iBool; -} -bool AppGLWidget::getFrontBufferFlag() { - return _frontBufferFlag; -} -void AppGLWidget::setBackBufferFlag(bool iBool){ - _backBufferFlag = iBool; -} -bool AppGLWidget::getBackBufferFlag() { - return _backBufferFlag; -} - -//void AppGLWidget::DrawLines() -//{ -// //Antialiasing: -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// glEnable(GL_BLEND); -// glEnable(GL_LINE_SMOOTH); -// glPolygonMode(GL_FRONT, GL_LINE); -// -// glColor3f(0.f, 0.f, 0.f); -// glLineWidth(2.f); -// -// DrawScene(); -//} -// -//void AppGLWidget::DrawSurfacic() -//{ -// glPolygonMode(GL_FRONT, GL_FILL); -// glShadeModel(GL_SMOOTH); -// -// glEnable(GL_LIGHTING); -// glEnable(GL_LIGHT0); -// -// -// GLreal diffuseV[] = {0.5, 0.7, 0.5, 1.0}; -// glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseV); -// -// //glColor3f(0.f, 0.f, 0.f); -// -// DrawScene(); -// -// glDisable(GL_LIGHTING); -//} -// -//void AppGLWidget::DrawDepthBuffer() -//{ -// GLint w = width(); -// GLint h = height(); -// -// glPolygonMode(GL_FRONT, GL_FILL); -// -// //Disable the writing in the frame buffer -// glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); -// -// //This rendering will only fills the depth buffer -// DrawScene(); -// -// //Re-enable the frame buffer writing -// glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); -// -// -// GLreal *zPixels = new real[w*h]; -// GLreal *colorPixels = new real[4*w*h]; -// -// // glReadBuffer(GL_FRONT); //in reality: glReadBuffer and glDrawBuffer are both set to GL_BACK -// glReadPixels(0,0,w, h, GL_DEPTH_COMPONENT, GL_real, (GLreal*)zPixels); -// -// real *tmpZ = zPixels; -// real *tmpColor = colorPixels; -// -// for(int i=0; i<h; i++) -// { -// for(int j=0; j<w; j++) -// { -// //fprintf(test, " %.5f ", pixels[i*w+j]); -// tmpColor[0] = *tmpZ; -// tmpColor[1] = *tmpZ; -// tmpColor[2] = *tmpZ; -// tmpColor[3] = 1.f; -// -// tmpColor += 4; -// tmpZ++; -// } -// } -// glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); -// // glDrawBuffer(GL_FRONT_AND_BACK); -// //glRasterPos2i(0, 0); -// //glLoadIdentity(); -// glDrawPixels(w, h, GL_RGBA, GL_real, (GLreal *)colorPixels); -// -// delete [] zPixels; -// delete [] colorPixels; -//} - - -//******************************* -// COPIED FROM LIBQGLVIEWER -//******************************* - - // inherited - - // not-inherited - void AppGLWidget::setStateFileName(const string& name) { stateFileName_ = name; }; diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget.h b/source/blender/freestyle/intern/app_blender/AppGLWidget.h deleted file mode 100755 index 17319ce356f..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget.h +++ /dev/null @@ -1,524 +0,0 @@ -// -// Filename : AppConfig.h -// Author : Stephane Grabli -// Purpose : Configuration file -// Date of creation : 26/02/2003 -// -/////////////////////////////////////////////////////////////////////////////// - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef ARTGLWIDGET_H -# define ARTGLWIDGET_H - -# ifndef WIN32 -# include <algorithm> -using namespace std; -# define __min(x,y) (min(x,y)) -# define __max(x,y) (max(x,y)) -# endif // WIN32 - - -//# include <qstringlist.h> -# include "../geometry/Geom.h" -# include "../geometry/BBox.h" -# include "../scene_graph/NodeDrawingStyle.h" -# include "../system/TimeUtils.h" -# include "../system/Precision.h" -# include "AppConfig.h" -# include "../rendering/GLDebugRenderer.h" -//# include <QGLViewer/qglviewer.h> - -# include "../stroke/BlenderStrokeRenderer.h" - - -//soc -#include "AppGLWidget_camera.h" -#include "AppGLWidget_vec.h" -#include "AppGLWidget_quaternion.h" - -using namespace Geometry; - -typedef enum {SURFACIC, LINE, DEPTHBUFFER} RenderStyle; - -class FEdge; -class QMainWindow; -class GLRenderer; -class GLSelectRenderer; -class GLBBoxRenderer; -class GLMonoColorRenderer; -class GLDebugRenderer; - -class AppGLWidget -{ - - -public: - - AppGLWidget(const char *iName = 0); - virtual ~AppGLWidget(); - -public: - - //inherited - inline unsigned int width() { return _width; } - inline unsigned int height() { return _height; } - inline void setWidth( unsigned int width ) { _width = width; } - inline void setHeight( unsigned int height ) { _height = height; } - - // not-inherited - void setStateFileName(const string& name); - - - AppGLWidget_Camera * _camera; - int workingBuffer; - -protected: - unsigned int _width, _height; - Vec _min,_max; - string stateFileName_; - -public: - - // captures a frame animation that was previously registered - void captureMovie(); - - /*! Sets the rendering style. - iStyle - The style used to render. Can be: - SURFACIC : usual rendering - LINES : line rendering - DEPTHBUFFER : grey-levels rendering of the depth buffer - */ - inline void setRenderStyle(RenderStyle iStyle) - { - _RenderStyle = iStyle; - } - - /*! Sets the model to draw in the viewer - * iModel - * The Root Node of the model - */ - inline void setModel(NodeGroup *iModel) - { - if(0 != _ModelRootNode->numberOfChildren()) - { - _ModelRootNode->DetachChildren(); - _ModelRootNode->clearBBox(); - } - - AddModel(iModel); - } - - /*! Adds a model for displaying in the viewer */ - inline void AddModel(NodeGroup *iModel) - { - _ModelRootNode->AddChild(iModel); - - _ModelRootNode->UpdateBBox(); - - _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], - _ModelRootNode->bbox().getMin()[1]), - _ModelRootNode->bbox().getMin()[2]); - _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], - _ModelRootNode->bbox().getMax()[1]), - _ModelRootNode->bbox().getMax()[2]); - - _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); - - _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); - - // DEBUG: - ReInitRenderers(); - - } - - inline void AddSilhouette(NodeGroup* iSilhouette) - { - _SilhouetteRootNode->AddChild(iSilhouette); - //ToggleSilhouette(true); - - } - - inline void Add2DSilhouette(NodeGroup *iSilhouette) - { - //_pFENode->AddChild(iSilhouette); - //ToggleSilhouette(true); - - } - - inline void Add2DVisibleSilhouette(NodeGroup *iVSilhouette) - { - //_pVisibleSilhouetteNode->AddChild(iVSilhouette); - - } - - inline void setDebug(NodeGroup* iDebug) - { - if(0 != _DebugRootNode->numberOfChildren()) - { - _DebugRootNode->DetachChildren(); - _DebugRootNode->clearBBox(); - } - - AddDebug(iDebug); - } - - inline void AddDebug(NodeGroup* iDebug) - { - _DebugRootNode->AddChild(iDebug); - - } - - inline void DetachModel(Node *iModel) - { - _ModelRootNode->DetachChild(iModel); - _ModelRootNode->UpdateBBox(); - - _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], - _ModelRootNode->bbox().getMin()[1]), - _ModelRootNode->bbox().getMin()[2]); - _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], - _ModelRootNode->bbox().getMax()[1]), - _ModelRootNode->bbox().getMax()[2]); - - _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); - _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); - } - - inline void DetachModel() - { - _ModelRootNode->DetachChildren(); - _ModelRootNode->clearBBox(); - - // 2D Scene - //_p2DNode.DetachChildren(); - //_pFENode->DetachChildren(); - //_pVisibleSilhouetteNode->DetachChildren(); - - } - - inline void DetachSilhouette() - { - _SilhouetteRootNode->DetachChildren(); - //_pFENode->DetachChildren(); - //_pVisibleSilhouetteNode->DetachChildren(); - _p2DSelectionNode->destroy(); - // //FIXME - } - - inline void DetachVisibleSilhouette() - { - //_pVisibleSilhouetteNode->DetachChildren(); - _p2DSelectionNode->destroy(); - - } - - inline void DetachDebug() - { - _DebugRootNode->DetachChildren(); - - } - - void setMainWindow(QMainWindow *iMainWindow) ; - - inline void set3DContext() - { - // GL_PROJECTION matrix - _camera->loadProjectionMatrix(); - // GL_MODELVIEW matrix - _camera->loadModelViewMatrix(); - } - - inline void RetriveModelViewMatrix(float *p) - { - glGetFloatv(GL_MODELVIEW_MATRIX, p); - } - inline void RetriveModelViewMatrix(real *p) - { - glGetDoublev(GL_MODELVIEW_MATRIX, p); - } - - inline void RetrieveProjectionMatrix(float *p) - { - glGetFloatv(GL_PROJECTION_MATRIX, p); - - } - inline void RetrieveProjectionMatrix(real *p) - { - glGetDoublev(GL_PROJECTION_MATRIX, p); - - } - - inline void RetrieveViewport(int *p) - { - glGetIntegerv(GL_VIEWPORT,(GLint *)p); - } - - inline real GetFocalLength() const - { - real Near = __max(0.1,(real)(-2.f*_maxAbs+_camera->distanceToSceneCenter())); - return Near; - } - - inline real GetAspect() const - { - return ((real) _width/(real) _height); - } - - inline real GetFovyRadian() const - { - return _Fovy/180.0 * M_PI; - } - - inline real GetFovyDegrees() const - { - return _Fovy; - } - - inline void FitBBox() - { - Vec min_(_ModelRootNode->bbox().getMin()[0], - _ModelRootNode->bbox().getMin()[1], - _ModelRootNode->bbox().getMin()[2]); - Vec max_(_ModelRootNode->bbox().getMax()[0], - _ModelRootNode->bbox().getMax()[1], - _ModelRootNode->bbox().getMax()[2]); - _camera->setSceneBoundingBox(min_, max_); - _camera->showEntireScene(); - } - - inline void ToggleSilhouette(bool enabled) - { - _fedges = enabled; - - } - - // Reinit the renderers which need to be informed - // when a model is added to the scene. - void ReInitRenderers(); - - inline void setSelectedFEdge(FEdge* iFEdge) { _pDebugRenderer->setSelectedFEdge(iFEdge); } - - inline GLDebugRenderer* debugRenderer() { return _pDebugRenderer; } - inline void toggle3D() { _Draw3DScene == true ? _Draw3DScene = false : _Draw3DScene = true; } - - /*! glReadPixels */ - typedef enum{ - RGBA, - RGB, - DEPTH - } PixelFormat; - void readPixels(int x, - int y, - int width, - int height, - PixelFormat format, - float *pixels) - { - - //glReadBuffer(GL_FRONT); //in reality: glReadBuffer and glDrawBuffer are both set to GL_BACK - //glReadBuffer(GL_BACK); - GLenum glformat; - switch(format) - { - case RGBA: - glformat = GL_RGBA; - break; - case RGB: - glformat = GL_RGB; - break; - case DEPTH: - glformat = GL_DEPTH_COMPONENT; - break; - default: - break; - } - glReadPixels(x,y,width, height, glformat, GL_FLOAT, (GLfloat*)pixels); - } - - void clear() { glClear(GL_COLOR_BUFFER_BIT ); } - - typedef enum { - FRONT, - BACK - } GLBuffer; - - - BBox<Vec3r> scene3DBBox() const { return _ModelRootNode->bbox(); } - - inline real znear() const { - return _camera->zNear(); - } - - inline real zfar() const { - return _camera->zFar(); - } - - inline bool draw3DsceneEnabled() const { return _Draw3DScene; } - - inline bool getRecordFlag() const {return _record;} - - void setCameraState(const Vec& position, const Quaternion& orientation) { - _camera->setPosition(position); - _camera->setOrientation(orientation); - } - - void getCameraState(float* position, float* orientation) const { - Vec pos = _camera->position(); - Quaternion orient = _camera->orientation(); - int i; - for(i=0;i<3;++i){ - position[i] = pos[i]; - } - for(i=0;i<4;++i){ - orientation[i] = orient[i]; - } - } - - void saveCameraState() { - getCameraState(_cameraPosition, _cameraOrientation); - _cameraStateSaved = true; - } - - void setUpdateMode(bool b) { - _enableUpdateSilhouettes = b; - } - - bool getUpdateMode() const { - return _enableUpdateSilhouettes; - } - static void setFrontBufferFlag(bool iBool); - static bool getFrontBufferFlag(); - static void setBackBufferFlag(bool iBool); - static bool getBackBufferFlag(); - -public: - virtual void draw(); - -protected: - virtual void init(); - - /*! Loads an envmap */ - void LoadEnvMap(const char *filename); - -public: - /*! Core scene drawing */ - void DrawScene(SceneVisitor *iRenderer); - - /*! 2D Scene Drawing */ - void Draw2DScene(SceneVisitor *iRenderer); - - /*! Draws scene silhouettes in real time */ - void DrawSilhouette(); - - /*! Draws the Scene in lines style */ - // void DrawLines(); - // /*! Draws the scene in surfacic style */ - // void DrawSurfacic(); - // /*! Draws the scene as a depth buffer image */ - // void DrawDepthBuffer(); - - GLRenderer* glRenderer() {return _pGLRenderer;} - -protected: - - - //QString shortcutBindingsString() const; - - /*! fabs or abs */ - inline int rabs(int x) {return abs(x);} - inline real rabs(real x) {return fabs(x);} - - -protected: - float _Fovy; - //float _SceneDepth; - //BBox<Vec3f> _BBox; - - RenderStyle _RenderStyle; - - //The root node container - NodeGroup _RootNode; - NodeDrawingStyle *_ModelRootNode; - NodeDrawingStyle *_SilhouetteRootNode; - NodeDrawingStyle *_DebugRootNode; - - bool _silhouette; - bool _fedges; - bool _debug; - bool _selection_mode; - - //a Universal light: - NodeGroup _Light; - - real _minBBox; - real _maxBBox; - real _maxAbs; - - real _minAbs; - bool _drawBBox; - - // OpenGL Renderer - GLRenderer *_pGLRenderer; - GLSelectRenderer *_pSelectRenderer; - GLBBoxRenderer *_pBBoxRenderer; - GLMonoColorRenderer *_pMonoColorRenderer; - GLDebugRenderer *_pDebugRenderer; - - QMainWindow *_pMainWindow; - - Chronometer _Chrono; - - // 2D Scene - bool _Draw2DScene; - bool _Draw3DScene; NodeGroup _p2DNode; - //NodeDrawingStyle *_pFENode; // Feature edges node - //NodeDrawingStyle *_pVisibleSilhouetteNode; - NodeDrawingStyle *_p2DSelectionNode; - - // EnvMap - bool _drawEnvMap; - int _currentEnvMap; - int _maxId; - int _blendFunc; - - // Each time we compute the view map, the camera state is - // saved in order to be able to restore it later - bool _cameraStateSaved; - float _cameraPosition[3]; - float _cameraOrientation[4]; - - // interactive silhouette update - bool _enableUpdateSilhouettes; - //capture movie - bool _captureMovie; - // 2D drawing buffers - static bool _frontBufferFlag; - static bool _backBufferFlag; - - bool _record; - - - -}; - -#endif // ARTGLWIDGET_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_camera.cpp b/source/blender/freestyle/intern/app_blender/AppGLWidget_camera.cpp deleted file mode 100644 index 26f2e024cd8..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_camera.cpp +++ /dev/null @@ -1,1799 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#include "AppGLWidget_camera.h" -//#include "qglviewer.h" - -using namespace std; -//using namespace qglviewer; - -/*! Default constructor. - - sceneCenter() is set to (0,0,0) and sceneRadius() is set to 1.0. type() is Camera::PERSPECTIVE, - with a \c M_PI/4 fieldOfView(). - - See IODistance(), physicalDistanceToScreen(), physicalScreenWidth() and focusDistance() - documentations for default stereo parameter values. */ -AppGLWidget_Camera::AppGLWidget_Camera() - : fieldOfView_(M_PI/4.0f) -{ - // #CONNECTION# Camera copy constructor - //interpolationKfi_ = new KeyFrameInterpolator; - // Requires the interpolationKfi_ - setFrame(new ManipulatedCameraFrame()); - - // #CONNECTION# All these default values identical in initFromDOMElement. - - // Requires fieldOfView() to define focusDistance() - setSceneRadius(1.0); - - // Initial value (only scaled after this) - orthoCoef_ = tan(fieldOfView()/2.0); - - // Also defines the revolveAroundPoint(), which changes orthoCoef_. Requires a frame(). - setSceneCenter(Vec(0.0, 0.0, 0.0)); - - // Requires fieldOfView() when called with ORTHOGRAPHIC. Attention to projectionMatrix_ below. - setType(PERSPECTIVE); - - // #CONNECTION# initFromDOMElement default values - setZNearCoefficient(0.005f); - setZClippingCoefficient(sqrt(3.0)); - - // Dummy values - setScreenWidthAndHeight(600, 400); - - // Stereo parameters - setIODistance(0.062f); - setPhysicalDistanceToScreen(0.5f); - setPhysicalScreenWidth(0.4f); - // focusDistance is set from setFieldOfView() - - // #CONNECTION# Camera copy constructor - for (unsigned short j=0; j<16; ++j) - { - modelViewMatrix_[j] = ((j%5 == 0) ? 1.0 : 0.0); - // #CONNECTION# computeProjectionMatrix() is lazy and assumes 0.0 almost everywhere. - projectionMatrix_[j] = 0.0; - } - computeProjectionMatrix(); -} - -/*! Virtual destructor. - - The frame() is deleted, but the different keyFrameInterpolator() are \e not deleted (in case they - are shared). */ -AppGLWidget_Camera::~AppGLWidget_Camera() -{ - delete frame_; - //delete interpolationKfi_; -} - - -/*! Copy constructor. Performs a deep copy using operator=(). */ -AppGLWidget_Camera::AppGLWidget_Camera(const AppGLWidget_Camera& camera) -{ - // #CONNECTION# Camera constructor - //interpolationKfi_ = new KeyFrameInterpolator; - // Requires the interpolationKfi_ - setFrame(new ManipulatedCameraFrame()); - - for (unsigned short j=0; j<16; ++j) - { - modelViewMatrix_[j] = ((j%5 == 0) ? 1.0 : 0.0); - // #CONNECTION# computeProjectionMatrix() is lazy and assumes 0.0 almost everywhere. - projectionMatrix_[j] = 0.0; - } - - (*this)=camera; -} - -/*! Equal operator. - - All the parameters of \p camera are copied. The frame() pointer is not modified, but its - Frame::position() and Frame::orientation() are set to those of \p camera. - - \attention The Camera screenWidth() and screenHeight() are set to those of \p camera. If your - Camera is associated with a QGLViewer, you should update these value after the call to this method: - \code - *(camera()) = otherCamera; - camera()->setScreenWidthAndHeight(width(), height()); - \endcode - The same applies to sceneCenter() and sceneRadius(), if needed. */ -AppGLWidget_Camera& AppGLWidget_Camera::operator=(const AppGLWidget_Camera& camera) -{ - setScreenWidthAndHeight(camera.screenWidth(), camera.screenHeight()); - setFieldOfView(camera.fieldOfView()); - setSceneRadius(camera.sceneRadius()); - setSceneCenter(camera.sceneCenter()); - setZNearCoefficient(camera.zNearCoefficient()); - setZClippingCoefficient(camera.zClippingCoefficient()); - setType(camera.type()); - - // Stereo parameters - setIODistance(camera.IODistance()); - setFocusDistance(camera.focusDistance()); - setPhysicalScreenWidth(camera.physicalScreenWidth()); - setPhysicalDistanceToScreen(camera.physicalDistanceToScreen()); - - orthoCoef_ = camera.orthoCoef_; - - // frame_ and interpolationKfi_ pointers are not shared. - frame_->setReferenceFrame(NULL); - frame_->setPosition(camera.position()); - frame_->setOrientation(camera.orientation()); - - //interpolationKfi_->resetInterpolation(); - - //kfi_ = camera.kfi_; - - computeProjectionMatrix(); - computeModelViewMatrix(); - - return *this; -} - -/*! Sets Camera screenWidth() and screenHeight() (expressed in pixels). - -You should not call this method when the Camera is associated with a QGLViewer, since the -latter automatically updates these values when it is resized (hence overwritting your values). - -Non-positive dimension are silently replaced by a 1 pixel value to ensure frustrum coherence. - -If your Camera is used without a QGLViewer (offscreen rendering, shadow maps), use setAspectRatio() -instead to define the projection matrix. */ -void AppGLWidget_Camera::setScreenWidthAndHeight(int width, int height) -{ - // Prevent negative and zero dimensions that would cause divisions by zero. - screenWidth_ = width > 0 ? width : 1; - screenHeight_ = height > 0 ? height : 1; -} - -/*! Returns the near clipping plane distance used by the Camera projection matrix. - - The clipping planes' positions depend on the sceneRadius() and sceneCenter() rather than being fixed - small-enough and large-enough values. A good scene dimension approximation will hence result in an - optimal precision of the z-buffer. - - The near clipping plane is positioned at a distance equal to zClippingCoefficient() * sceneRadius() - in front of the sceneCenter(): - \code - zNear = distanceToSceneCenter() - zClippingCoefficient()*sceneRadius(); - \endcode - - In order to prevent negative or too small zNear() values (which would degrade the z precision), - zNearCoefficient() is used when the Camera is inside the sceneRadius() sphere: - \code - const float zMin = zNearCoefficient() * zClippingCoefficient() * sceneRadius(); - if (zNear < zMin) - zNear = zMin; - // With an ORTHOGRAPHIC type, the value is simply clamped to 0.0 - \endcode - - See also the zFar(), zClippingCoefficient() and zNearCoefficient() documentations. - - If you need a completely different zNear computation, overload the zNear() and zFar() methods in a - new class that publicly inherits from Camera and use QGLViewer::setCamera(): - \code - class myCamera :: public qglviewer::Camera - { - virtual float Camera::zNear() const { return 0.001; }; - virtual float Camera::zFar() const { return 100.0; }; - } - \endcode - - See the <a href="../examples/standardCamera.html">standardCamera example</a> for an application. - - \attention The value is always positive although the clipping plane is positioned at a negative z - value in the Camera coordinate system. This follows the \c gluPerspective standard. */ -float AppGLWidget_Camera::zNear() const -{ - float z = distanceToSceneCenter() - zClippingCoefficient()*sceneRadius(); - - // Prevents negative or null zNear values. - const float zMin = zNearCoefficient() * zClippingCoefficient() * sceneRadius(); - if (z < zMin) - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE : z = zMin; break; - case AppGLWidget_Camera::ORTHOGRAPHIC : z = 0.0; break; - } - return z; -} - -/*! Returns the far clipping plane distance used by the Camera projection matrix. - -The far clipping plane is positioned at a distance equal to zClippingCoefficient() * sceneRadius() -behind the sceneCenter(): -\code -zFar = distanceToSceneCenter() + zClippingCoefficient()*sceneRadius(); -\endcode - -See the zNear() documentation for details. */ -float AppGLWidget_Camera::zFar() const -{ - return distanceToSceneCenter() + zClippingCoefficient()*sceneRadius(); -} - -/*! Defines the Camera type(). - -Prefix the type with Camera, as in: \code camera()->setType(Camera::ORTHOGRAPHIC); // or even -qglviewer::Camera::ORTHOGRAPHIC if you do not use namespace \endcode */ -void AppGLWidget_Camera::setType(Type type) -{ - // make ORTHOGRAPHIC frustum fit PERSPECTIVE (at least in plane normal to viewDirection(), passing - // through RAP) Done only when CHANGING type since orthoCoef_ may have been changed with a - // setRevolveAroundPoint() in the meantime. - if ( (type == AppGLWidget_Camera::ORTHOGRAPHIC) && (type_ == AppGLWidget_Camera::PERSPECTIVE) ) - orthoCoef_ = tan(fieldOfView()/2.0); - type_ = type; -} - -/*! Sets the Camera frame(). - -If you want to move the Camera, use setPosition() and setOrientation() or one of the Camera -positioning methods (lookAt(), fitSphere(), showEntireScene()...) instead. - -If you want to save the Camera position(), there's no need to call this method either. Use -addKeyFrameToPath() and playPath() instead. - -This method is actually mainly useful if you derive the ManipulatedCameraFrame class and want to -use an instance of your new class to move the Camera. - -A \c NULL \p mcf pointer will silently be ignored. The calling method is responsible for -deleting the previous frame() pointer if needed in order to prevent memory leaks. */ -void AppGLWidget_Camera::setFrame(ManipulatedCameraFrame* const mcf) -{ - if (!mcf) - return; - - frame_ = mcf; - //interpolationKfi_->setFrame(frame()); -} - -/*! Returns the distance from the Camera center to sceneCenter(), projected along the Camera Z axis. - Used by zNear() and zFar() to optimize the Z range. */ -float AppGLWidget_Camera::distanceToSceneCenter() const -{ - return fabs((frame()->coordinatesOf(sceneCenter())).z); -} - - -/*! Returns the \p halfWidth and \p halfHeight of the Camera orthographic frustum. - - These values are only valid and used when the Camera is of type() Camera::ORTHOGRAPHIC. They are - expressed in OpenGL units and are used by loadProjectionMatrix() to define the projection matrix - using: - \code - glOrtho( -halfWidth, halfWidth, -halfHeight, halfHeight, zNear(), zFar() ) - \endcode - - These values are proportional to the Camera (z projected) distance to the revolveAroundPoint(). - When zooming on the object, the Camera is translated forward \e and its frustum is narrowed, making - the object appear bigger on screen, as intuitively expected. - - Overload this method to change this behavior if desired, as is done in the - <a href="../examples/standardCamera.html">standardCamera example</a>. */ -void AppGLWidget_Camera::getOrthoWidthHeight(GLdouble& halfWidth, GLdouble& halfHeight) const -{ - const float dist = orthoCoef_ * fabs(cameraCoordinatesOf(revolveAroundPoint()).z); - //#CONNECTION# fitScreenRegion - halfWidth = dist * ((aspectRatio() < 1.0) ? 1.0 : aspectRatio()); - halfHeight = dist * ((aspectRatio() < 1.0) ? 1.0/aspectRatio() : 1.0); -} - - -/*! Computes the projection matrix associated with the Camera. - - If type() is Camera::PERSPECTIVE, defines a \c GL_PROJECTION matrix similar to what would \c - gluPerspective() do using the fieldOfView(), window aspectRatio(), zNear() and zFar() parameters. - - If type() is Camera::ORTHOGRAPHIC, the projection matrix is as what \c glOrtho() would do. - Frustum's width and height are set using getOrthoWidthHeight(). - - Both types use zNear() and zFar() to place clipping planes. These values are determined from - sceneRadius() and sceneCenter() so that they best fit the scene size. - - Use getProjectionMatrix() to retrieve this matrix. Overload loadProjectionMatrix() if you want your - Camera to use an exotic projection matrix. - - \note You must call this method if your Camera is not associated with a QGLViewer and is used for - offscreen computations (using (un)projectedCoordinatesOf() for instance). loadProjectionMatrix() - does it otherwise. */ -void AppGLWidget_Camera::computeProjectionMatrix() const -{ - const float ZNear = zNear(); - const float ZFar = zFar(); - - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE: - { - // #CONNECTION# all non null coefficients were set to 0.0 in constructor. - const float f = 1.0/tan(fieldOfView()/2.0); - projectionMatrix_[0] = f/aspectRatio(); - projectionMatrix_[5] = f; - projectionMatrix_[10] = (ZNear + ZFar) / (ZNear - ZFar); - projectionMatrix_[11] = -1.0; - projectionMatrix_[14] = 2.0 * ZNear * ZFar / (ZNear - ZFar); - projectionMatrix_[15] = 0.0; - // same as gluPerspective( 180.0*fieldOfView()/M_PI, aspectRatio(), zNear(), zFar() ); - break; - } - case AppGLWidget_Camera::ORTHOGRAPHIC: - { - GLdouble w, h; - getOrthoWidthHeight(w,h); - projectionMatrix_[0] = 1.0/w; - projectionMatrix_[5] = 1.0/h; - projectionMatrix_[10] = -2.0/(ZFar - ZNear); - projectionMatrix_[11] = 0.0; - projectionMatrix_[14] = -(ZFar + ZNear)/(ZFar - ZNear); - projectionMatrix_[15] = 1.0; - // same as glOrtho( -w, w, -h, h, zNear(), zFar() ); - break; - } - } -} - -/*! Computes the modelView matrix associated with the Camera's position() and orientation(). - - This matrix converts from the world coordinates system to the Camera coordinates system, so that - coordinates can then be projected on screen using the projection matrix (see computeProjectionMatrix()). - - Use getModelViewMatrix() to retrieve this matrix. - - \note You must call this method if your Camera is not associated with a QGLViewer and is used for - offscreen computations (using (un)projectedCoordinatesOf() for instance). loadModelViewMatrix() - does it otherwise. */ -void AppGLWidget_Camera::computeModelViewMatrix() const -{ - const Quaternion q = frame()->orientation(); - - const double q00 = 2.0l * q[0] * q[0]; - const double q11 = 2.0l * q[1] * q[1]; - const double q22 = 2.0l * q[2] * q[2]; - - const double q01 = 2.0l * q[0] * q[1]; - const double q02 = 2.0l * q[0] * q[2]; - const double q03 = 2.0l * q[0] * q[3]; - - const double q12 = 2.0l * q[1] * q[2]; - const double q13 = 2.0l * q[1] * q[3]; - - const double q23 = 2.0l * q[2] * q[3]; - - modelViewMatrix_[0] = 1.0l - q11 - q22; - modelViewMatrix_[1] = q01 - q23; - modelViewMatrix_[2] = q02 + q13; - modelViewMatrix_[3] = 0.0l; - - modelViewMatrix_[4] = q01 + q23; - modelViewMatrix_[5] = 1.0l - q22 - q00; - modelViewMatrix_[6] = q12 - q03; - modelViewMatrix_[7] = 0.0l; - - modelViewMatrix_[8] = q02 - q13; - modelViewMatrix_[9] = q12 + q03; - modelViewMatrix_[10] = 1.0l - q11 - q00; - modelViewMatrix_[11] = 0.0l; - - const Vec t = q.inverseRotate(frame()->position()); - - modelViewMatrix_[12] = -t.x; - modelViewMatrix_[13] = -t.y; - modelViewMatrix_[14] = -t.z; - modelViewMatrix_[15] = 1.0l; -} - - -/*! Loads the OpenGL \c GL_PROJECTION matrix with the Camera projection matrix. - - The Camera projection matrix is computed using computeProjectionMatrix(). - - When \p reset is \c true (default), the method clears the previous projection matrix by calling \c - glLoadIdentity before setting the matrix. Setting \p reset to \c false is useful for \c GL_SELECT - mode, to combine the pushed matrix with a picking matrix. See QGLViewer::beginSelection() for details. - - This method is used by QGLViewer::preDraw() (called before user's QGLViewer::draw() method) to - set the \c GL_PROJECTION matrix according to the viewer's QGLViewer::camera() settings. - - Use getProjectionMatrix() to retrieve this matrix. Overload this method if you want your Camera to - use an exotic projection matrix. See also loadModelViewMatrix(). - - \attention \c glMatrixMode is set to \c GL_PROJECTION. - - \attention If you use several OpenGL contexts and bypass the Qt main refresh loop, you should call - QGLWidget::makeCurrent() before this method in order to activate the right OpenGL context. */ -void AppGLWidget_Camera::loadProjectionMatrix(bool reset) const -{ - // WARNING: makeCurrent must be called by every calling method - glMatrixMode(GL_PROJECTION); - - if (reset) - glLoadIdentity(); - - computeProjectionMatrix(); - - glMultMatrixd(projectionMatrix_); -} - -/*! Loads the OpenGL \c GL_MODELVIEW matrix with the modelView matrix corresponding to the Camera. - - Calls computeModelViewMatrix() to compute the Camera's modelView matrix. - - This method is used by QGLViewer::preDraw() (called before user's QGLViewer::draw() method) to - set the \c GL_MODELVIEW matrix according to the viewer's QGLViewer::camera() position() and - orientation(). - - As a result, the vertices used in QGLViewer::draw() can be defined in the so called world - coordinate system. They are multiplied by this matrix to get converted to the Camera coordinate - system, before getting projected using the \c GL_PROJECTION matrix (see loadProjectionMatrix()). - - When \p reset is \c true (default), the method loads (overwrites) the \c GL_MODELVIEW matrix. Setting - \p reset to \c false simply calls \c glMultMatrixd (might be useful for some applications). - - Overload this method or simply call glLoadMatrixd() at the beginning of QGLViewer::draw() if you - want your Camera to use an exotic modelView matrix. See also loadProjectionMatrix(). - - getModelViewMatrix() returns the 4x4 modelView matrix. - - \attention glMatrixMode is set to \c GL_MODELVIEW - - \attention If you use several OpenGL contexts and bypass the Qt main refresh loop, you should call - QGLWidget::makeCurrent() before this method in order to activate the right OpenGL context. */ -void AppGLWidget_Camera::loadModelViewMatrix(bool reset) const -{ - // WARNING: makeCurrent must be called by every calling method - glMatrixMode(GL_MODELVIEW); - computeModelViewMatrix(); - if (reset) - glLoadMatrixd(modelViewMatrix_); - else - glMultMatrixd(modelViewMatrix_); -} - -/*! Same as loadProjectionMatrix() but for a stereo setup. - - Only the Camera::PERSPECTIVE type() is supported for stereo mode. See - QGLViewer::setStereoDisplay(). - - Uses focusDistance(), IODistance(), and physicalScreenWidth() to compute cameras - offset and asymmetric frustums. - - When \p leftBuffer is \c true, computes the projection matrix associated to the left eye (right eye - otherwise). See also loadModelViewMatrixStereo(). - - See the <a href="../examples/stereoViewer.html">stereoViewer</a> and the <a - href="../examples/contribs.html#anaglyph">anaglyph</a> examples for an illustration. - - To retrieve this matrix, use a code like: - \code - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - loadProjectionMatrixStereo(left_or_right); - glGetFloatv(GL_PROJECTION_MATRIX, m); - glPopMatrix(); - \endcode - Note that getProjectionMatrix() always returns the mono-vision matrix. - - \attention glMatrixMode is set to \c GL_PROJECTION. */ -void AppGLWidget_Camera::loadProjectionMatrixStereo(bool leftBuffer) const -{ - float left, right, bottom, top; - float screenHalfWidth, halfWidth, side, shift, delta; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE: - // compute half width of screen, - // corresponding to zero parallax plane to deduce decay of cameras - screenHalfWidth = focusDistance() * tan(horizontalFieldOfView() / 2.0); - shift = screenHalfWidth * IODistance() / physicalScreenWidth(); - // should be * current y / y total - // to take into account that the window doesn't cover the entire screen - - // compute half width of "view" at znear and the delta corresponding to - // the shifted camera to deduce what to set for asymmetric frustums - halfWidth = zNear() * tan(horizontalFieldOfView() / 2.0); - delta = shift * zNear() / focusDistance(); - side = leftBuffer ? -1.0 : 1.0; - - left = -halfWidth + side * delta; - right = halfWidth + side * delta; - top = halfWidth / aspectRatio(); - bottom = -top; - glFrustum(left, right, bottom, top, zNear(), zFar() ); - break; - - case AppGLWidget_Camera::ORTHOGRAPHIC: - cout << "AppGLWidget_Camera::setProjectionMatrixStereo: Stereo not available with Ortho mode"; - break; - } -} - -/*! Same as loadModelViewMatrix() but for a stereo setup. - - Only the Camera::PERSPECTIVE type() is supported for stereo mode. See - QGLViewer::setStereoDisplay(). - - The modelView matrix is almost identical to the mono-vision one. It is simply translated along its - horizontal axis by a value that depends on stereo parameters (see focusDistance(), - IODistance(), and physicalScreenWidth()). - - When \p leftBuffer is \c true, computes the modelView matrix associated to the left eye (right eye - otherwise). - - loadProjectionMatrixStereo() explains how to retrieve to resulting matrix. - - See the <a href="../examples/stereoViewer.html">stereoViewer</a> and the <a - href="../examples/contribs.html#anaglyph">anaglyph</a> examples for an illustration. - - \attention glMatrixMode is set to \c GL_MODELVIEW. */ -void AppGLWidget_Camera::loadModelViewMatrixStereo(bool leftBuffer) const -{ - // WARNING: makeCurrent must be called by every calling method - glMatrixMode(GL_MODELVIEW); - - float halfWidth = focusDistance() * tan(horizontalFieldOfView() / 2.0); - float shift = halfWidth * IODistance() / physicalScreenWidth(); // * current window width / full screen width - - computeModelViewMatrix(); - if (leftBuffer) - modelViewMatrix_[12] -= shift; - else - modelViewMatrix_[12] += shift; - glLoadMatrixd(modelViewMatrix_); -} - -/*! Fills \p m with the Camera projection matrix values. - - Calls computeProjectionMatrix() to define the Camera projection matrix. - - This matrix only reflects the Camera's internal parameters and it may differ from the \c - GL_PROJECTION matrix retrieved using \c glGetDoublev(GL_PROJECTION_MATRIX, m). It actually - represents the state of the \c GL_PROJECTION after QGLViewer::preDraw(), at the beginning of - QGLViewer::draw(). If you modified the \c GL_PROJECTION matrix (for instance using - QGLViewer::startScreenCoordinatesSystem()), the two results differ. - - The result is an OpenGL 4x4 matrix, which is given in \e column-major order (see \c glMultMatrix - man page for details). - - See also getModelViewMatrix() and setFromProjectionMatrix(). */ -void AppGLWidget_Camera::getProjectionMatrix(GLdouble m[16]) const -{ - // May not be needed, but easier and more robust like this. - computeProjectionMatrix(); - for (unsigned short i=0; i<16; ++i) - m[i] = projectionMatrix_[i]; -} - -/*! Fills \p m with the Camera modelView matrix values. - - First calls computeModelViewMatrix() to define the Camera modelView matrix. - - Note that this matrix is usually \e not the one you would get from a \c - glGetDoublev(GL_MODELVIEW_MATRIX, m). It actually represents the state of the \c - GL_MODELVIEW after QGLViewer::preDraw(), at the beginning of QGLViewer::draw(). It converts from - the world to the Camera coordinate system. As soon as you modify the \c GL_MODELVIEW in your - QGLViewer::draw() method, the two matrices differ. - - The result is an OpenGL 4x4 matrix, which is given in \e column-major order (see \c glMultMatrix - man page for details). - - See also getProjectionMatrix() and setFromModelViewMatrix(). */ -void AppGLWidget_Camera::getModelViewMatrix(GLdouble m[16]) const -{ - // May not be needed, but easier like this. - // Prevents from retrieving matrix in stereo mode -> overwrites shifted value. - computeModelViewMatrix(); - for (unsigned short i=0; i<16; ++i) - m[i] = modelViewMatrix_[i]; -} - -/*! Fills \p m with the product of the ModelView and Projection matrices. - - Calls getModelViewMatrix() and getProjectionMatrix() and then fills \p m with the product of these two matrices. */ -void AppGLWidget_Camera::getModelViewProjectionMatrix(GLdouble m[16]) const -{ - GLdouble mv[16]; - GLdouble proj[16]; - getModelViewMatrix(mv); - getProjectionMatrix(proj); - - for (unsigned short i=0; i<4; ++i) - { - for (unsigned short j=0; j<4; ++j) - { - double sum = 0.0; - for (unsigned short k=0; k<4; ++k) - sum += proj[i+4*k]*mv[k+4*j]; - m[i+4*j] = sum; - } - } -} - -#ifndef DOXYGEN -void AppGLWidget_Camera::getProjectionMatrix(GLfloat m[16]) const -{ - cout << "Warning : AppGLWidget_Camera::getProjectionMatrix requires a GLdouble matrix array"; - static GLdouble mat[16]; - getProjectionMatrix(mat); - for (int i=0; i<16; ++i) - m[i] = float(mat[i]); -} - -void AppGLWidget_Camera::getModelViewMatrix(GLfloat m[16]) const -{ - cout << "Warning : AppGLWidget_Camera::getModelViewMatrix requires a GLdouble matrix array"; - static GLdouble mat[16]; - getModelViewMatrix(mat); - for (int i=0; i<16; ++i) - m[i] = float(mat[i]); -} -#endif - -/*! Sets the sceneRadius() value. Negative values are ignored. - -\attention This methods also sets focusDistance() to sceneRadius() / tan(fieldOfView()/2) and -flySpeed() to 1% of sceneRadius(). */ -void AppGLWidget_Camera::setSceneRadius(float radius) -{ - if (radius <= 0.0) - { - cout << "Scene radius must be positive - Ignoring value"; - return; - } - - sceneRadius_ = radius; - - setFocusDistance(sceneRadius() / tan(fieldOfView()/2.0)); - - frame()->setFlySpeed(0.01*sceneRadius()); -} - -/*! Similar to setSceneRadius() and setSceneCenter(), but the scene limits are defined by a (world - axis aligned) bounding box. */ -void AppGLWidget_Camera::setSceneBoundingBox(const Vec& min, const Vec& max) -{ - setSceneCenter((min+max)/2.0); - setSceneRadius(0.5*(max-min).norm()); -} - - -/*! Sets the sceneCenter(). - - \attention This method also sets the revolveAroundPoint() to sceneCenter(). */ -void AppGLWidget_Camera::setSceneCenter(const Vec& center) -{ - sceneCenter_ = center; - setRevolveAroundPoint(sceneCenter()); -} - -/*! setSceneCenter() to the result of pointUnderPixel(\p pixel). - - Returns \c true if a pointUnderPixel() was found and sceneCenter() was actually changed. - - See also setRevolveAroundPointFromPixel(). See the pointUnderPixel() documentation. */ -bool AppGLWidget_Camera::setSceneCenterFromPixel(const Point& pixel) -{ - bool found; - Vec point = pointUnderPixel(pixel, found); - if (found) - setSceneCenter(point); - return found; -} - -/*! Changes the revolveAroundPoint() to \p rap (defined in the world coordinate system). */ -void AppGLWidget_Camera::setRevolveAroundPoint(const Vec& rap) -{ - const float prevDist = fabs(cameraCoordinatesOf(revolveAroundPoint()).z); - - frame()->setRevolveAroundPoint(rap); - - // orthoCoef_ is used to compensate for changes of the revolveAroundPoint, so that the image does - // not change when the revolveAroundPoint is changed in ORTHOGRAPHIC mode. - const float newDist = fabs(cameraCoordinatesOf(revolveAroundPoint()).z); - // Prevents division by zero when rap is set to camera position - if ((prevDist > 1E-9) && (newDist > 1E-9)) - orthoCoef_ *= prevDist / newDist; -} - -/*! The revolveAroundPoint() is set to the point located under \p pixel on screen. - -Returns \c true if a pointUnderPixel() was found. If no point was found under \p pixel, the -revolveAroundPoint() is left unchanged. - -\p pixel is expressed in Qt format (origin in the upper left corner of the window). See -pointUnderPixel(). - -See also setSceneCenterFromPixel(). */ -bool AppGLWidget_Camera::setRevolveAroundPointFromPixel(const Point& pixel) -{ - bool found; - Vec point = pointUnderPixel(pixel, found); - if (found) - setRevolveAroundPoint(point); - return found; -} - -/*! Returns the ratio between pixel and OpenGL units at \p position. - - A line of \c n * pixelGLRatio() OpenGL units, located at \p position in the world coordinates - system, will be projected with a length of \c n pixels on screen. - - Use this method to scale objects so that they have a constant pixel size on screen. The following - code will draw a 20 pixel line, starting at sceneCenter() and always directed along the screen - vertical direction: - \code - glBegin(GL_LINES); - glVertex3fv(sceneCenter()); - glVertex3fv(sceneCenter() + 20 * pixelGLRatio(sceneCenter()) * camera()->upVector()); - glEnd(); - \endcode */ -float AppGLWidget_Camera::pixelGLRatio(const Vec& position) const -{ - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE : - return 2.0 * fabs((frame()->coordinatesOf(position)).z) * tan(fieldOfView()/2.0) / screenHeight(); - case AppGLWidget_Camera::ORTHOGRAPHIC : - { - GLdouble w, h; - getOrthoWidthHeight(w,h); - return 2.0 * h / screenHeight(); - } - } - // Bad compilers complain - return 1.0; -} - -/*! Changes the Camera fieldOfView() so that the entire scene (defined by QGLViewer::sceneCenter() - and QGLViewer::sceneRadius()) is visible from the Camera position(). - - The position() and orientation() of the Camera are not modified and you first have to orientate the - Camera in order to actually see the scene (see lookAt(), showEntireScene() or fitSphere()). - - This method is especially useful for \e shadow \e maps computation. Use the Camera positioning - tools (setPosition(), lookAt()) to position a Camera at the light position. Then use this method to - define the fieldOfView() so that the shadow map resolution is optimally used: - \code - // The light camera needs size hints in order to optimize its fieldOfView - lightCamera->setSceneRadius(sceneRadius()); - lightCamera->setSceneCenter(sceneCenter()); - - // Place the light camera. - lightCamera->setPosition(lightFrame->position()); - lightCamera->lookAt(sceneCenter()); - lightCamera->setFOVToFitScene(); - \endcode - - See the (soon available) shadowMap contribution example for a practical implementation. - - \attention The fieldOfView() is clamped to M_PI/2.0. This happens when the Camera is at a distance - lower than sqrt(2.0) * sceneRadius() from the sceneCenter(). It optimizes the shadow map - resolution, although it may miss some parts of the scene. */ -void AppGLWidget_Camera::setFOVToFitScene() -{ - if (distanceToSceneCenter() > sqrt(2.0)*sceneRadius()) - setFieldOfView(2.0 * asin(sceneRadius() / distanceToSceneCenter())); - else - setFieldOfView(M_PI / 2.0f); -} - -/*! Makes the Camera smoothly zoom on the pointUnderPixel() \p pixel. - - Nothing happens if no pointUnderPixel() is found. Otherwise a KeyFrameInterpolator is created that - animates the Camera on a one second path that brings the Camera closer to the point under \p pixel. - - See also interpolateToFitScene(). */ -// void Camera::interpolateToZoomOnPixel(const Point& pixel) -// { -// const float coef = 0.1f; -// -// bool found; -// Vec target = pointUnderPixel(pixel, found); -// -// if (!found) -// return; -// -// if (interpolationKfi_->interpolationIsStarted()) -// interpolationKfi_->stopInterpolation(); -// -// interpolationKfi_->deletePath(); -// interpolationKfi_->addKeyFrame(*(frame())); -// -// interpolationKfi_->addKeyFrame(Frame(0.3f*frame()->position() + 0.7f*target, frame()->orientation()), 0.4f); -// -// // Small hack: attach a temporary frame to take advantage of lookAt without modifying frame -// static ManipulatedCameraFrame* tempFrame = new ManipulatedCameraFrame(); -// ManipulatedCameraFrame* const originalFrame = frame(); -// tempFrame->setPosition(coef*frame()->position() + (1.0-coef)*target); -// tempFrame->setOrientation(frame()->orientation()); -// setFrame(tempFrame); -// lookAt(target); -// setFrame(originalFrame); -// -// interpolationKfi_->addKeyFrame(*(tempFrame), 1.0); -// -// interpolationKfi_->startInterpolation(); -// } - -/*! Interpolates the Camera on a one second KeyFrameInterpolator path so that the entire scene fits - the screen at the end. - - The scene is defined by its sceneCenter() and its sceneRadius(). See showEntireScene(). - - The orientation() of the Camera is not modified. See also interpolateToZoomOnPixel(). */ -// void Camera::interpolateToFitScene() -// { -// if (interpolationKfi_->interpolationIsStarted()) -// interpolationKfi_->stopInterpolation(); -// -// interpolationKfi_->deletePath(); -// interpolationKfi_->addKeyFrame(*(frame())); -// -// // Small hack: attach a temporary frame to take advantage of lookAt without modifying frame -// static ManipulatedCameraFrame* tempFrame = new ManipulatedCameraFrame(); -// ManipulatedCameraFrame* const originalFrame = frame(); -// tempFrame->setPosition(frame()->position()); -// tempFrame->setOrientation(frame()->orientation()); -// setFrame(tempFrame); -// showEntireScene(); -// setFrame(originalFrame); -// -// //interpolationKfi_->addKeyFrame(*(tempFrame)); -// -// //interpolationKfi_->startInterpolation(); -// } - - -/*! Smoothly interpolates the Camera on a KeyFrameInterpolator path so that it goes to \p fr. - - \p fr is expressed in world coordinates. \p duration tunes the interpolation speed (default is - 1 second). - - See also interpolateToFitScene() and interpolateToZoomOnPixel(). */ -// void Camera::interpolateTo(const Frame& fr, float duration) -// { -// if (interpolationKfi_->interpolationIsStarted()) -// interpolationKfi_->stopInterpolation(); -// -// interpolationKfi_->deletePath(); -// interpolationKfi_->addKeyFrame(*(frame())); -// interpolationKfi_->addKeyFrame(fr, duration); -// -// interpolationKfi_->startInterpolation(); -// } - - -/*! Returns the coordinates of the 3D point located at pixel (x,y) on screen. - - Calls a \c glReadPixel to get the pixel depth and applies an unprojectedCoordinatesOf() to the - result. \p found indicates whether a point was found or not (i.e. background pixel, result's depth - is zFar() in that case). - - \p x and \p y are expressed in pixel units with an origin in the upper left corner. Use - screenHeight() - y to convert to OpenGL standard. - - \attention This method assumes that a GL context is available, and that its content was drawn using - the Camera (i.e. using its projection and modelview matrices). This method hence cannot be used for - offscreen Camera computations. Use cameraCoordinatesOf() and worldCoordinatesOf() to perform - similar operations in that case. - - \note The precision of the z-Buffer highly depends on how the zNear() and zFar() values are fitted - to your scene. Loose boundaries will result in imprecision along the viewing direction. */ -Vec AppGLWidget_Camera::pointUnderPixel(const Point& pixel, bool& found) const -{ - float depth; - // Qt uses upper corner for its origin while GL uses the lower corner. - glReadPixels(pixel.x(), screenHeight()-1-pixel.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); - found = depth < 1.0; - Vec point(pixel.x(), pixel.y(), depth); - point = unprojectedCoordinatesOf(point); - return point; -} - -/*! Moves the Camera so that the entire scene is visible. - - Simply calls fitSphere() on a sphere defined by sceneCenter() and sceneRadius(). - - You will typically use this method in QGLViewer::init() after you defined a new sceneRadius(). */ -void AppGLWidget_Camera::showEntireScene() -{ - fitSphere(sceneCenter(), sceneRadius()); -} - -/*! Moves the Camera so that its sceneCenter() is projected on the center of the window. The - orientation() and fieldOfView() are unchanged. - - Simply projects the current position on a line passing through sceneCenter(). See also - showEntireScene().*/ -void AppGLWidget_Camera::centerScene() -{ - frame()->projectOnLine(sceneCenter(), viewDirection()); -} - -/*! Sets the Camera orientation(), so that it looks at point \p target (defined in the world - coordinate system). - - The Camera position() is not modified. Simply setViewDirection(). - - See also setUpVector(), setOrientation(), showEntireScene(), fitSphere() and fitBoundingBox(). */ -void AppGLWidget_Camera::lookAt(const Vec& target) -{ - setViewDirection(target - position()); -} - -/*! Moves the Camera so that the sphere defined by (\p center, \p radius) is visible and fits the window. - - The Camera is simply translated along its viewDirection() so that the sphere fits the screen. Its - orientation() and its fieldOfView() are unchanged. - - You should therefore orientate the Camera before you call this method. See lookAt(), - setOrientation() and setUpVector(). */ -void AppGLWidget_Camera::fitSphere(const Vec& center, float radius) -{ - float distance = 0.0f; - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE : - { - const float yview = radius / sin(fieldOfView()/2.0); - const float xview = radius / sin(horizontalFieldOfView()/2.0); - distance = qMax(xview,yview); - break; - } - case AppGLWidget_Camera::ORTHOGRAPHIC : - { - distance = ((center-revolveAroundPoint()) * viewDirection()) + (radius / orthoCoef_); - break; - } - } - Vec newPos(center - distance * viewDirection()); - frame()->setPositionWithConstraint(newPos); -} - -/*! Moves the Camera so that the (world axis aligned) bounding box (\p min, \p max) is entirely - visible, using fitSphere(). */ -void AppGLWidget_Camera::fitBoundingBox(const Vec& min, const Vec& max) -{ - float diameter = qMax(fabs(max[1]-min[1]), fabs(max[0]-min[0])); - diameter = qMax(fabsf(max[2]-min[2]), diameter); - fitSphere(0.5*(min+max), 0.5*diameter); -} - -/*! Rotates the Camera so that its upVector() becomes \p up (defined in the world coordinate - system). - - The Camera is rotated around an axis orthogonal to \p up and to the current upVector() direction. - Use this method in order to define the Camera horizontal plane. - - When \p noMove is set to \c false, the orientation modification is compensated by a translation, so - that the revolveAroundPoint() stays projected at the same position on screen. This is especially - useful when the Camera is an observer of the scene (default mouse binding). - - When \p noMove is \c true (default), the Camera position() is left unchanged, which is an intuitive - behavior when the Camera is in a walkthrough fly mode (see the QGLViewer::MOVE_FORWARD and - QGLViewer::MOVE_BACKWARD QGLViewer::MouseAction). */ -void AppGLWidget_Camera::setUpVector(const Vec& up, bool noMove) -{ - Quaternion q(Vec(0.0, 1.0, 0.0), frame()->transformOf(up)); - - if (!noMove) - frame()->setPosition(revolveAroundPoint() - (frame()->orientation()*q).rotate(frame()->coordinatesOf(revolveAroundPoint()))); - - frame()->rotate(q); - - // Useful in fly mode to keep the horizontal direction. - //frame()->updateFlyUpVector(); -} - -/*! Sets the orientation() of the Camera using polar coordinates. - - \p theta rotates the Camera around its Y axis, and \e then \p phi rotates it around its X axis. - The polar coordinates are defined in the world coordinates system: \p theta = \p phi = 0 means - that the Camera is directed towards the world Z axis. Both angles are expressed in radians. - - See also setUpVector(). The position() of the Camera is unchanged, you may want to call showEntireScene() - after this method to move the Camera. - - This method can be useful to create Quicktime VR panoramic sequences, see the - QGLViewer::saveSnapshot() documentation for details. */ -void AppGLWidget_Camera::setOrientation(float theta, float phi) -{ - Vec axis(0.0, 1.0, 0.0); - const Quaternion rot1(axis, theta); - axis = Vec(-cos(theta), 0., sin(theta)); - const Quaternion rot2(axis, phi); - setOrientation(rot1 * rot2); -} - -/*! Sets the Camera orientation(), defined in the world coordinate system. */ -void AppGLWidget_Camera::setOrientation(const Quaternion& q) -{ - frame()->setOrientation(q); - //frame()->updateFlyUpVector(); -} - -/*! Rotates the Camera so that its viewDirection() is \p direction (defined in the world coordinate - system). - - The Camera position() is not modified. The Camera is rotated so that the horizon (defined by its - upVector()) is preserved. See also lookAt() and setUpVector(). */ -void AppGLWidget_Camera::setViewDirection(const Vec& direction) -{ - if (direction.squaredNorm() < 1E-10) - return; - - Vec xAxis = direction ^ upVector(); - if (xAxis.squaredNorm() < 1E-10) - { - // target is aligned with upVector, this means a rotation around X axis - // X axis is then unchanged, let's keep it ! - xAxis = frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0)); - } - - Quaternion q; - q.setFromRotatedBasis(xAxis, xAxis^direction, -direction); - frame()->setOrientationWithConstraint(q); -} - -// Compute a 3 by 3 determinant. -static float det(float m00,float m01,float m02, - float m10,float m11,float m12, - float m20,float m21,float m22) -{ - return m00*m11*m22 + m01*m12*m20 + m02*m10*m21 - m20*m11*m02 - m10*m01*m22 - m00*m21*m12; -} - -// Computes the index of element [i][j] in a \c float matrix[3][4]. -static inline unsigned int ind(unsigned int i, unsigned int j) -{ - return (i*4+j); -} - - -/*! Sets the Camera's position() and orientation() from an OpenGL ModelView matrix. - -This enables a Camera initialisation from an other OpenGL application. \p modelView is a 16 GLdouble -vector representing a valid OpenGL ModelView matrix, such as one can get using: -\code -GLdouble mvm[16]; -glGetDoublev(GL_MODELVIEW_MATRIX, mvm); -myCamera->setFromModelViewMatrix(mvm); -\endcode - -After this method has been called, getModelViewMatrix() returns a matrix equivalent to \p -modelView. - -Only the orientation() and position() of the Camera are modified. - -\note If you defined your matrix as \c GLdouble \c mvm[4][4], pass \c &(mvm[0][0]) as a -parameter. */ -void AppGLWidget_Camera::setFromModelViewMatrix(const GLdouble* const modelViewMatrix) -{ - // Get upper left (rotation) matrix - double upperLeft[3][3]; - for (int i=0; i<3; ++i) - for (int j=0; j<3; ++j) - upperLeft[i][j] = modelViewMatrix[i*4+j]; - - // Transform upperLeft into the associated Quaternion - Quaternion q; - q.setFromRotationMatrix(upperLeft); - - setOrientation(q); - setPosition(-q.rotate(Vec(modelViewMatrix[12], modelViewMatrix[13], modelViewMatrix[14]))); -} - -/*! Defines the Camera position(), orientation() and fieldOfView() from a projection matrix. - - \p matrix has to be given in the format used by vision algorithm. It has 3 lines and 4 columns. It - transforms a point from the world homogeneous coordinate system (4 coordinates: \c sx, \c sy, \c sz - and \c s) into a point in the screen homogeneous coordinate system (3 coordinates: \c sx, \c sy, - and \c s, where \c x and \c y are the pixel coordinates on the screen). - - Its three lines correspond to the homogeneous coordinates of the normals to the planes x=0, y=0 and - z=0, defined in the Camera coordinate system. - - The elements of the matrix are ordered in line major order: you can call \c - setFromProjectionMatrix(&(matrix[0][0])) if you defined your matrix as a \c float \c matrix[3][4]. - - \attention Passing the result of getProjectionMatrix() or getModelViewMatrix() to this method is - not possible (purposefully incompatible matrix dimensions). \p matrix is more likely to be the - product of these two matrices, without the last line. - - Use setFromModelViewMatrix() to set position() and orientation() from a \c GL_MODELVIEW matrix. - fieldOfView() can also be retrieved from a \e perspective \c GL_PROJECTION matrix using 2.0 * - atan(1.0/projectionMatrix[5]). - - This code was written by Sylvain Paris. */ -void AppGLWidget_Camera::setFromProjectionMatrix(const float matrix[12]) -{ - // The 3 lines of the matrix are the normals to the planes x=0, y=0, z=0 - // in the camera CS. As we normalize them, we do not need the 4th coordinate. - Vec line_0(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,2)]); - Vec line_1(matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,2)]); - Vec line_2(matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,2)]); - - line_0.normalize(); - line_1.normalize(); - line_2.normalize(); - - // The camera position is at (0,0,0) in the camera CS so it is the - // intersection of the 3 planes. It can be seen as the kernel - // of the 3x4 projection matrix. We calculate it through 4 dimensional - // vectorial product. We go directly into 3D that is to say we directly - // divide the first 3 coordinates by the 4th one. - - // We derive the 4 dimensional vectorial product formula from the - // computation of a 4x4 determinant that is developped according to - // its 4th column. This implies some 3x3 determinants. - const Vec cam_pos = Vec(det(matrix[ind(0,1)],matrix[ind(0,2)],matrix[ind(0,3)], - matrix[ind(1,1)],matrix[ind(1,2)],matrix[ind(1,3)], - matrix[ind(2,1)],matrix[ind(2,2)],matrix[ind(2,3)]), - - -det(matrix[ind(0,0)],matrix[ind(0,2)],matrix[ind(0,3)], - matrix[ind(1,0)],matrix[ind(1,2)],matrix[ind(1,3)], - matrix[ind(2,0)],matrix[ind(2,2)],matrix[ind(2,3)]), - - det(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,3)], - matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,3)], - matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,3)])) / - - (-det(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,2)], - matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,2)], - matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,2)])); - - // We compute the rotation matrix column by column. - - // GL Z axis is front facing. - Vec column_2 = -line_2; - - // X-axis is almost like line_0 but should be orthogonal to the Z axis. - Vec column_0 = ((column_2^line_0)^column_2); - column_0.normalize(); - - // Y-axis is almost like line_1 but should be orthogonal to the Z axis. - // Moreover line_1 is downward oriented as the screen CS. - Vec column_1 = -((column_2^line_1)^column_2); - column_1.normalize(); - - double rot[3][3]; - rot[0][0] = column_0[0]; - rot[1][0] = column_0[1]; - rot[2][0] = column_0[2]; - - rot[0][1] = column_1[0]; - rot[1][1] = column_1[1]; - rot[2][1] = column_1[2]; - - rot[0][2] = column_2[0]; - rot[1][2] = column_2[1]; - rot[2][2] = column_2[2]; - - // We compute the field of view - - // line_1^column_0 -> vector of intersection line between - // y_screen=0 and x_camera=0 plane. - // column_2*(...) -> cos of the angle between Z vector et y_screen=0 plane - // * 2 -> field of view = 2 * half angle - - // We need some intermediate values. - Vec dummy = line_1^column_0; - dummy.normalize(); - float fov = acos(column_2*dummy) * 2.0; - - // We set the camera. - Quaternion q; - q.setFromRotationMatrix(rot); - setOrientation(q); - setPosition(cam_pos); - setFieldOfView(fov); -} - - -/* - // persp : projectionMatrix_[0] = f/aspectRatio(); -void Camera::setFromProjectionMatrix(const GLdouble* projectionMatrix) -{ - QString message; - if ((fabs(projectionMatrix[1]) > 1E-3) || - (fabs(projectionMatrix[2]) > 1E-3) || - (fabs(projectionMatrix[3]) > 1E-3) || - (fabs(projectionMatrix[4]) > 1E-3) || - (fabs(projectionMatrix[6]) > 1E-3) || - (fabs(projectionMatrix[7]) > 1E-3) || - (fabs(projectionMatrix[8]) > 1E-3) || - (fabs(projectionMatrix[9]) > 1E-3)) - message = "Non null coefficient in projection matrix - Aborting"; - else - if ((fabs(projectionMatrix[11]+1.0) < 1E-5) && (fabs(projectionMatrix[15]) < 1E-5)) - { - if (projectionMatrix[5] < 1E-4) - message="Negative field of view in Camera::setFromProjectionMatrix"; - else - setType(Camera::PERSPECTIVE); - } - else - if ((fabs(projectionMatrix[11]) < 1E-5) && (fabs(projectionMatrix[15]-1.0) < 1E-5)) - setType(Camera::ORTHOGRAPHIC); - else - message = "Unable to determine camera type in setFromProjectionMatrix - Aborting"; - - if (!message.isEmpty()) - { - qWarning(message); - return; - } - - switch (type()) - { - case Camera::PERSPECTIVE: - { - setFieldOfView(2.0 * atan(1.0/projectionMatrix[5])); - const float far = projectionMatrix[14] / (2.0 * (1.0 + projectionMatrix[10])); - const float near = (projectionMatrix[10]+1.0) / (projectionMatrix[10]-1.0) * far; - setSceneRadius((far-near)/2.0); - setSceneCenter(position() + (near + sceneRadius())*viewDirection()); - break; - } - case Camera::ORTHOGRAPHIC: - { - GLdouble w, h; - getOrthoWidthHeight(w,h); - projectionMatrix_[0] = 1.0/w; - projectionMatrix_[5] = 1.0/h; - projectionMatrix_[10] = -2.0/(ZFar - ZNear); - projectionMatrix_[11] = 0.0; - projectionMatrix_[14] = -(ZFar + ZNear)/(ZFar - ZNear); - projectionMatrix_[15] = 1.0; - // same as glOrtho( -w, w, -h, h, zNear(), zFar() ); - break; - } - } -} -*/ - -///////////////////////// Camera to world transform /////////////////////// - -/*! Same as cameraCoordinatesOf(), but with \c float[3] parameters (\p src and \p res may be identical pointers). */ -void AppGLWidget_Camera::getCameraCoordinatesOf(const float src[3], float res[3]) const -{ - Vec r = cameraCoordinatesOf(Vec(src)); - for (int i=0; i<3; ++i) - res[i] = r[i]; -} - -/*! Same as worldCoordinatesOf(), but with \c float[3] parameters (\p src and \p res may be identical pointers). */ -void AppGLWidget_Camera::getWorldCoordinatesOf(const float src[3], float res[3]) const -{ - Vec r = worldCoordinatesOf(Vec(src)); - for (int i=0; i<3; ++i) - res[i] = r[i]; -} - -/*! Fills \p viewport with the Camera OpenGL viewport. - -This method is mainly used in conjunction with \c gluProject, which requires such a viewport. -Returned values are (0, screenHeight(), screenWidth(), - screenHeight()), so that the origin is -located in the \e upper left corner of the window (Qt style coordinate system). */ -void AppGLWidget_Camera::getViewport(GLint viewport[4]) const -{ - viewport[0] = 0; - viewport[1] = screenHeight(); - viewport[2] = screenWidth(); - viewport[3] = -screenHeight(); -} - -/*! Returns the screen projected coordinates of a point \p src defined in the \p frame coordinate - system. - - When \p frame in \c NULL (default), \p src is expressed in the world coordinate system. - - The x and y coordinates of the returned Vec are expressed in pixel, (0,0) being the \e upper left - corner of the window. The z coordinate ranges between 0.0 (near plane) and 1.0 (excluded, far - plane). See the \c gluProject man page for details. - - unprojectedCoordinatesOf() performs the inverse transformation. - - See the <a href="../examples/screenCoordSystem.html">screenCoordSystem example</a>. - - This method only uses the intrinsic Camera parameters (see getModelViewMatrix(), - getProjectionMatrix() and getViewport()) and is completely independent of the OpenGL \c - GL_MODELVIEW, \c GL_PROJECTION and viewport matrices. You can hence define a virtual Camera and use - this method to compute projections out of a classical rendering context. - - \attention However, if your Camera is not attached to a QGLViewer (used for offscreen computations - for instance), make sure the Camera matrices are updated before calling this method. Call - computeModelViewMatrix() and computeProjectionMatrix() to do so. - - If you call this method several times with no change in the matrices, consider precomputing the - projection times modelview matrix to save computation time if required (\c P x \c M in the \c - gluProject man page). */ -Vec AppGLWidget_Camera::projectedCoordinatesOf(const Vec& src, const Frame* frame) const -{ - GLdouble x,y,z; - static GLint viewport[4]; - getViewport(viewport); - - if (frame) - { - const Vec tmp = frame->inverseCoordinatesOf(src); - gluProject(tmp.x,tmp.y,tmp.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z); - } - else - gluProject(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z); - - return Vec(x,y,z); -} - -/*! Returns the world unprojected coordinates of a point \p src defined in the screen coordinate - system. - - The \p src.x and \p src.y input values are expressed in pixels, (0,0) being the \e upper left corner - of the window. \p src.z is a depth value ranging in [0..1[ (near and far plane respectively). See - the \c gluUnProject man page for details. - - The result is expressed in the \p frame coordinate system. When \p frame is \c NULL (default), the - result is expressed in the world coordinates system. The possible \p frame Frame::referenceFrame() - are taken into account. - - projectedCoordinatesOf() performs the inverse transformation. - - This method only uses the intrinsic Camera parameters (see getModelViewMatrix(), - getProjectionMatrix() and getViewport()) and is completely independent of the OpenGL \c - GL_MODELVIEW, \c GL_PROJECTION and viewport matrices. You can hence define a virtual Camera and use - this method to compute un-projections out of a classical rendering context. - - \attention However, if your Camera is not attached to a QGLViewer (used for offscreen computations - for instance), make sure the Camera matrices are updated before calling this method (use - computeModelViewMatrix(), computeProjectionMatrix()). See also setScreenWidthAndHeight(). - - This method is not computationally optimized. If you call it several times with no change in the - matrices, you should buffer the entire inverse projection matrix (modelview, projection and then - viewport) to speed-up the queries. See the \c gluUnProject man page for details. */ -Vec AppGLWidget_Camera::unprojectedCoordinatesOf(const Vec& src, const Frame* frame) const -{ - GLdouble x,y,z; - static GLint viewport[4]; - getViewport(viewport); - gluUnProject(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z); - if (frame) - return frame->coordinatesOf(Vec(x,y,z)); - else - return Vec(x,y,z); -} - -/*! Same as projectedCoordinatesOf(), but with \c float parameters (\p src and \p res can be identical pointers). */ -void AppGLWidget_Camera::getProjectedCoordinatesOf(const float src[3], float res[3], const Frame* frame) const -{ - Vec r = projectedCoordinatesOf(Vec(src), frame); - for (int i=0; i<3; ++i) - res[i] = r[i]; -} - -/*! Same as unprojectedCoordinatesOf(), but with \c float parameters (\p src and \p res can be identical pointers). */ -void AppGLWidget_Camera::getUnprojectedCoordinatesOf(const float src[3], float res[3], const Frame* frame) const -{ - Vec r = unprojectedCoordinatesOf(Vec(src), frame); - for (int i=0; i<3; ++i) - res[i] = r[i]; -} - -///////////////////////////////////// KFI ///////////////////////////////////////// - -/*! Returns the KeyFrameInterpolator that defines the Camera path number \p i. - -If path \p i is not defined for this index, the method returns a \c NULL pointer. */ -// KeyFrameInterpolator* Camera::keyFrameInterpolator(int i) -// { -// if ( kfi_.find(i) != kfi_.end()) -// return kfi_[i]; -// else -// return NULL; -// } - -/*! Sets the KeyFrameInterpolator that defines the Camera path of index \p i. - - The previous keyFrameInterpolator() is lost and should be deleted by the calling method if - needed. - - The KeyFrameInterpolator::interpolated() signal of \p kfi probably needs to be connected to the - Camera's associated QGLViewer::updateGL() slot, so that when the Camera position is interpolated - using \p kfi, every interpolation step updates the display: - \code - myViewer.camera()->deletePath(3); - myViewer.camera()->setKeyFrameInterpolator(3, myKeyFrameInterpolator); - connect(myKeyFrameInterpolator, SIGNAL(interpolated()), myViewer, SLOT(updateGL()); - \endcode - - \note These connections are done automatically when a Camera is attached to a QGLViewer, or when a - new KeyFrameInterpolator is defined using the QGLViewer::addKeyFrameKeyboardModifiers() and - QGLViewer::pathKey() (default is Alt+F[1-12]). See the <a href="../keyboard.html">keyboard page</a> - for details. */ -// void Camera::setKeyFrameInterpolator(int i, KeyFrameInterpolator* const kfi) -// { -// if (kfi) -// kfi_[i] = kfi; -// else -// kfi_.erase(i); -// } - -/*! Adds the current Camera position() and orientation() as a keyFrame to the path number \p i. - -This method can also be used if you simply want to save a Camera point of view (a path made of a -single keyFrame). Use playPath() to make the Camera play the keyFrame path (resp. restore -the point of view). Use deletePath() to clear the path. - -The default keyboard shortcut for this method is Alt+F[1-12]. Set QGLViewer::pathKey() and -QGLViewer::addKeyFrameKeyboardModifiers(). - -If you use directly this method and the keyFrameInterpolator(i) does not exist, a new one is -created. Its KeyFrameInterpolator::interpolated() signal should then be connected to the -QGLViewer::updateGL() slot (see setKeyFrameInterpolator()). */ -// void Camera::addKeyFrameToPath(int i) -// { -// if (kfi_.find(i) != kfi_.end()) -// setKeyFrameInterpolator(i, new KeyFrameInterpolator(frame())); -// -// kfi_[i]->addKeyFrame(*(frame())); -// } - -/*! Makes the Camera follow the path of keyFrameInterpolator() number \p i. - - If the interpolation is started, it stops it instead. - - This method silently ignores undefined (empty) paths (see keyFrameInterpolator()). - - The default keyboard shortcut for this method is F[1-12]. Set QGLViewer::pathKey() and - QGLViewer::playPathKeyboardModifiers(). */ -// void Camera::playPath(int i) -// { -// if (kfi_.find(i) != kfi_.end()) -// if (kfi_[i]->interpolationIsStarted()) -// kfi_[i]->stopInterpolation(); -// else -// kfi_[i]->startInterpolation(); -// } - -/*! Resets the path of the keyFrameInterpolator() number \p i. - -If this path is \e not being played (see playPath() and -KeyFrameInterpolator::interpolationIsStarted()), resets it to is its starting position (see -KeyFrameInterpolator::resetInterpolation()). If the path is played, simply stops interpolation. */ -// void Camera::resetPath(int i) -// { -// // if (kfi_.contains(i)) -// if (kfi_.find(i) != kfi_.end()) -// if ((kfi_[i]->interpolationIsStarted())) -// kfi_[i]->stopInterpolation(); -// else -// { -// kfi_[i]->resetInterpolation(); -// kfi_[i]->interpolateAtTime(kfi_[i]->interpolationTime()); -// } -// } - -/*! Deletes the keyFrameInterpolator() of index \p i. - -Disconnect the keyFrameInterpolator() KeyFrameInterpolator::interpolated() signal before deleting the -keyFrameInterpolator() if needed: -\code -disconnect(camera()->keyFrameInterpolator(i), SIGNAL(interpolated()), this, SLOT(updateGL())); -camera()->deletePath(i); -\endcode */ -// void Camera::deletePath(int i) -// { -// if (kfi_.find(i) != kfi_.end()) -// { -// kfi_[i]->stopInterpolation(); -// delete kfi_[i]; -// kfi_.erase(i); -// } -// } - - - -/*! Gives the coefficients of a 3D half-line passing through the Camera eye and pixel (x,y). - - The origin of the half line (eye position) is stored in \p orig, while \p dir contains the properly - oriented and normalized direction of the half line. - - \p x and \p y are expressed in Qt format (origin in the upper left corner). Use screenHeight() - y - to convert to OpenGL units. - - This method is useful for analytical intersection in a selection method. - - See the <a href="../examples/select.html">select example</a> for an illustration. */ -void AppGLWidget_Camera::convertClickToLine(const Point& pixel, Vec& orig, Vec& dir) const -{ - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE: - orig = position(); - dir = Vec( ((2.0 * pixel.x() / screenWidth()) - 1.0) * tan(fieldOfView()/2.0) * aspectRatio(), - ((2.0 * (screenHeight()-pixel.y()) / screenHeight()) - 1.0) * tan(fieldOfView()/2.0), - -1.0 ); - dir = worldCoordinatesOf(dir) - orig; - dir.normalize(); - break; - - case AppGLWidget_Camera::ORTHOGRAPHIC: - { - GLdouble w,h; - getOrthoWidthHeight(w,h); - orig = Vec((2.0 * pixel.x() / screenWidth() - 1.0)*w, -(2.0 * pixel.y() / screenHeight() - 1.0)*h, 0.0); - orig = worldCoordinatesOf(orig); - dir = viewDirection(); - break; - } - } -} - -#ifndef DOXYGEN -/*! This method has been deprecated in libQGLViewer version 2.2.0 */ -void AppGLWidget_Camera::drawCamera(float, float, float) -{ - cout << "drawCamera is deprecated. Use AppGLWidget_Camera::draw() instead."; -} -#endif - -/*! Draws a representation of the Camera in the 3D world. - -The near and far planes are drawn as quads, the frustum is drawn using lines and the camera up -vector is represented by an arrow to disambiguate the drawing. See the -<a href="../examples/standardCamera.html">standardCamera example</a> for an illustration. - -Note that the current \c glColor and \c glPolygonMode are used to draw the near and far planes. See -the <a href="../examples/frustumCulling.html">frustumCulling example</a> for an example of -semi-transparent plane drawing. Similarly, the current \c glLineWidth and \c glColor is used to draw -the frustum outline. - -When \p drawFarPlane is \c false, only the near plane is drawn. \p scale can be used to scale the -drawing: a value of 1.0 (default) will draw the Camera's frustum at its actual size. - -This method assumes that the \c glMatrixMode is \c GL_MODELVIEW and that the current ModelView -matrix corresponds to the world coordinate system (as it is at the beginning of QGLViewer::draw()). -The Camera is then correctly positioned and orientated. - -\note The drawing of a QGLViewer's own QGLViewer::camera() should not be visible, but may create -artefacts due to numerical imprecisions. */ -void AppGLWidget_Camera::draw(bool drawFarPlane, float scale) const -{ - glPushMatrix(); - glMultMatrixd(frame()->worldMatrix()); - - // 0 is the upper left coordinates of the near corner, 1 for the far one - Vec points[2]; - - points[0].z = scale * zNear(); - points[1].z = scale * zFar(); - - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE: - { - points[0].y = points[0].z * tan(fieldOfView()/2.0); - points[0].x = points[0].y * aspectRatio(); - - const float ratio = points[1].z / points[0].z; - - points[1].y = ratio * points[0].y; - points[1].x = ratio * points[0].x; - break; - } - case AppGLWidget_Camera::ORTHOGRAPHIC: - { - GLdouble hw, hh; - getOrthoWidthHeight(hw, hh); - points[0].x = points[1].x = scale * float(hw); - points[0].y = points[1].y = scale * float(hh); - break; - } - } - - const int farIndex = drawFarPlane?1:0; - - // Near and (optionally) far plane(s) - glBegin(GL_QUADS); - for (int i=farIndex; i>=0; --i) - { - glNormal3f(0.0, 0.0, (i==0)?1.0:-1.0); - glVertex3f( points[i].x, points[i].y, -points[i].z); - glVertex3f(-points[i].x, points[i].y, -points[i].z); - glVertex3f(-points[i].x, -points[i].y, -points[i].z); - glVertex3f( points[i].x, -points[i].y, -points[i].z); - } - glEnd(); - - // Up arrow - const float arrowHeight = 1.5f * points[0].y; - const float baseHeight = 1.2f * points[0].y; - const float arrowHalfWidth = 0.5f * points[0].x; - const float baseHalfWidth = 0.3f * points[0].x; - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - // Base - glBegin(GL_QUADS); - glVertex3f(-baseHalfWidth, points[0].y, -points[0].z); - glVertex3f( baseHalfWidth, points[0].y, -points[0].z); - glVertex3f( baseHalfWidth, baseHeight, -points[0].z); - glVertex3f(-baseHalfWidth, baseHeight, -points[0].z); - glEnd(); - - // Arrow - glBegin(GL_TRIANGLES); - glVertex3f( 0.0f, arrowHeight, -points[0].z); - glVertex3f(-arrowHalfWidth, baseHeight, -points[0].z); - glVertex3f( arrowHalfWidth, baseHeight, -points[0].z); - glEnd(); - - // Frustum lines - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE : - glBegin(GL_LINES); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f( points[farIndex].x, points[farIndex].y, -points[farIndex].z); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(-points[farIndex].x, points[farIndex].y, -points[farIndex].z); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(-points[farIndex].x, -points[farIndex].y, -points[farIndex].z); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f( points[farIndex].x, -points[farIndex].y, -points[farIndex].z); - glEnd(); - break; - case AppGLWidget_Camera::ORTHOGRAPHIC : - if (drawFarPlane) - { - glBegin(GL_LINES); - glVertex3f( points[0].x, points[0].y, -points[0].z); - glVertex3f( points[1].x, points[1].y, -points[1].z); - glVertex3f(-points[0].x, points[0].y, -points[0].z); - glVertex3f(-points[1].x, points[1].y, -points[1].z); - glVertex3f(-points[0].x, -points[0].y, -points[0].z); - glVertex3f(-points[1].x, -points[1].y, -points[1].z); - glVertex3f( points[0].x, -points[0].y, -points[0].z); - glVertex3f( points[1].x, -points[1].y, -points[1].z); - glEnd(); - } - } - - glPopMatrix(); -} - - -/*! Returns the 6 plane equations of the Camera frustum. - -The six 4-component vectors of \p coef respectively correspond to the left, right, near, far, top -and bottom Camera frustum planes. Each vector holds a plane equation of the form: -\code -a*x + b*y + c*z + d = 0 -\endcode -where \c a, \c b, \c c and \c d are the 4 components of each vector, in that order. - -See the <a href="../examples/frustumCulling.html">frustumCulling example</a> for an application. - -This format is compatible with the \c glClipPlane() function. One camera frustum plane can hence be -applied in an other viewer to visualize the culling results: -\code - // Retrieve plance equations - GLdouble coef[6][4]; - mainViewer->camera()->getFrustumPlanesCoefficients(coef); - - // These two additional clipping planes (which must have been enabled) - // will reproduce the mainViewer's near and far clipping. - glClipPlane(GL_CLIP_PLANE0, coef[2]); - glClipPlane(GL_CLIP_PLANE1, coef[3]); -\endcode */ -void AppGLWidget_Camera::getFrustumPlanesCoefficients(GLdouble coef[6][4]) const -{ - // Computed once and for all - const Vec pos = position(); - const Vec viewDir = viewDirection(); - const Vec up = upVector(); - const Vec right = rightVector(); - const float posViewDir = pos * viewDir; - - static Vec normal[6]; - static GLdouble dist[6]; - - switch (type()) - { - case AppGLWidget_Camera::PERSPECTIVE : - { - const float hhfov = horizontalFieldOfView() / 2.0; - const float chhfov = cos(hhfov); - const float shhfov = sin(hhfov); - normal[0] = - shhfov * viewDir; - normal[1] = normal[0] + chhfov * right; - normal[0] = normal[0] - chhfov * right; - - normal[2] = -viewDir; - normal[3] = viewDir; - - const float hfov = fieldOfView() / 2.0; - const float chfov = cos(hfov); - const float shfov = sin(hfov); - normal[4] = - shfov * viewDir; - normal[5] = normal[4] - chfov * up; - normal[4] = normal[4] + chfov * up; - - for (int i=0; i<2; ++i) - dist[i] = pos * normal[i]; - for (int j=4; j<6; ++j) - dist[j] = pos * normal[j]; - - // Natural equations are: - // dist[0,1,4,5] = pos * normal[0,1,4,5]; - // dist[2] = (pos + zNear() * viewDir) * normal[2]; - // dist[3] = (pos + zFar() * viewDir) * normal[3]; - - // 2 times less computations using expanded/merged equations. Dir vectors are normalized. - const float posRightCosHH = chhfov * pos * right; - dist[0] = -shhfov * posViewDir; - dist[1] = dist[0] + posRightCosHH; - dist[0] = dist[0] - posRightCosHH; - const float posUpCosH = chfov * pos * up; - dist[4] = - shfov * posViewDir; - dist[5] = dist[4] - posUpCosH; - dist[4] = dist[4] + posUpCosH; - - break; - } - case AppGLWidget_Camera::ORTHOGRAPHIC : - normal[0] = -right; - normal[1] = right; - normal[4] = up; - normal[5] = -up; - - GLdouble hw, hh; - getOrthoWidthHeight(hw, hh); - dist[0] = (pos - hw * right) * normal[0]; - dist[1] = (pos + hw * right) * normal[1]; - dist[4] = (pos + hh * up) * normal[4]; - dist[5] = (pos - hh * up) * normal[5]; - break; - } - - // Front and far planes are identical for both camera types. - normal[2] = -viewDir; - normal[3] = viewDir; - dist[2] = -posViewDir - zNear(); - dist[3] = posViewDir + zFar(); - - for (int i=0; i<6; ++i) - { - coef[i][0] = GLdouble(normal[i].x); - coef[i][1] = GLdouble(normal[i].y); - coef[i][2] = GLdouble(normal[i].z); - coef[i][3] = dist[i]; - } -} diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_camera.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_camera.h deleted file mode 100644 index e71e85839b1..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_camera.h +++ /dev/null @@ -1,565 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#ifndef QGLVIEWER_CAMERA_H -#define QGLVIEWER_CAMERA_H - -#include "AppGLWidget_manipulatedCameraFrame.h" - - /*! \brief A perspective or orthographic camera. - \class Camera camera.h QGLViewer/camera.h - - A Camera defines some intrinsic parameters (fieldOfView(), position(), viewDirection(), - upVector()...) and useful positioning tools that ease its placement (showEntireScene(), - fitSphere(), lookAt()...). It exports its associated OpenGL projection and modelview matrices and - can interactively be modified using the mouse. - - <h3>Mouse manipulation</h3> - - The position() and orientation() of the Camera are defined by a ManipulatedCameraFrame (retrieved - using frame()). These methods are just convenient wrappers to the equivalent Frame methods. This - also means that the Camera frame() can be attached to a Frame::referenceFrame() which enables - complex Camera setups. - - Different displacements can be performed using the mouse. The list of possible actions is defined - by the QGLViewer::MouseAction enum. Use QGLViewer::setMouseBinding() to attach a specific action - to an arbitrary mouse button-state key binding. These actions are detailed in the <a - href="../mouse.html">mouse page</a>. - - The default button binding are: QGLViewer::ROTATE (left), QGLViewer::ZOOM (middle) and - QGLViewer::TRANSLATE (right). With this configuration, the Camera \e observes a scene and rotates - around its revolveAroundPoint(). You can switch between this mode and a fly mode using the - QGLViewer::CAMERA_MODE (see QGLViewer::toggleCameraMode()) keyboard shortcut (default is 'Space'). - - <h3>Other functionalities</h3> - - The type() of the Camera can be Camera::ORTHOGRAPHIC or Camera::PERSPECTIVE (see Type()). - fieldOfView() is meaningless with Camera::ORTHOGRAPHIC. - - The near and far planes of the Camera are fitted to the scene and determined from - QGLViewer::sceneRadius(), QGLViewer::sceneCenter() and zClippingCoefficient() by the zNear() and - zFar() methods. Reasonable values on the scene extends hence have to be provided to the QGLViewer - in order for the Camera to correctly display the scene. High level positioning methods also use - this information (showEntireScene(), centerScene()...). - - A Camera holds KeyFrameInterpolator that can be used to save Camera positions and paths. You can - interactively addKeyFrameToPath() to a given path using the default \c Alt+F[1-12] shortcuts. Use - playPath() to make the Camera follow the path (default shortcut is F[1-12]). See the <a - href="../keyboard.html">keyboard page</a> for details on key customization. - - Use cameraCoordinatesOf() and worldCoordinatesOf() to convert to and from the Camera frame() - coordinate system. projectedCoordinatesOf() and unprojectedCoordinatesOf() will convert from - screen to 3D coordinates. convertClickToLine() is very useful for analytical object selection. - - Stereo display is possible on machines with quad buffer capabilities (with Camera::PERSPECTIVE - type() only). Test the <a href="../examples/stereoViewer.html">stereoViewer example</a> to check. - - A Camera can also be used outside of a QGLViewer or even without OpenGL for its coordinate system - conversion capabilities. Note however that some of them explicitly rely on the presence of a - Z-buffer. \nosubgrouping */ - class AppGLWidget_Camera - { - - public: - AppGLWidget_Camera(); - virtual ~AppGLWidget_Camera(); - - AppGLWidget_Camera(const AppGLWidget_Camera& camera); - AppGLWidget_Camera& operator=(const AppGLWidget_Camera& camera); - - - /*! Enumerates the two possible types of Camera. - - See type() and setType(). This type mainly defines different Camera projection matrix (see - loadProjectionMatrix()). Many other methods (pointUnderPixel(), convertClickToLine(), - projectedCoordinatesOf(), pixelGLRatio()...) take this Type into account. */ - enum Type { PERSPECTIVE, ORTHOGRAPHIC }; - - /*! @name Position and orientation */ - //@{ - public: - /*! Returns the Camera position (the eye), defined in the world coordinate system. - - Use setPosition() to set the Camera position. Other convenient methods are showEntireScene() or - fitSphere(). Actually returns \c frame()->position(). - - This position corresponds to the projection center of a Camera::PERSPECTIVE Camera. It is not - located in the image plane, which is at a zNear() distance ahead. */ - Vec position() const { return frame()->position(); }; - - /*! Returns the normalized up vector of the Camera, defined in the world coordinate system. - - Set using setUpVector() or setOrientation(). It is orthogonal to viewDirection() and to - rightVector(). - - It corresponds to the Y axis of the associated frame() (actually returns - frame()->inverseTransformOf(Vec(0.0, 1.0, 0.0)) ). */ - Vec upVector() const - { - return frame()->inverseTransformOf(Vec(0.0, 1.0, 0.0)); - } - /*! Returns the normalized view direction of the Camera, defined in the world coordinate system. - - Change this value using setViewDirection(), lookAt() or setOrientation(). It is orthogonal to - upVector() and to rightVector(). - - This corresponds to the negative Z axis of the frame() ( frame()->inverseTransformOf(Vec(0.0, - 0.0, -1.0)) ). */ - Vec viewDirection() const { return frame()->inverseTransformOf(Vec(0.0, 0.0, -1.0)); }; - - /*! Returns the normalized right vector of the Camera, defined in the world coordinate system. - - This vector lies in the Camera horizontal plane, directed along the X axis (orthogonal to - upVector() and to viewDirection()). Set using setUpVector(), lookAt() or setOrientation(). - - Simply returns frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0)). */ - Vec rightVector() const - { - return frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0)); - } - - /*! Returns the Camera orientation, defined in the world coordinate system. - - Actually returns \c frame()->orientation(). Use setOrientation(), setUpVector() or lookAt() to - set the Camera orientation. */ - Quaternion orientation() const { return frame()->orientation(); }; - - void setFromModelViewMatrix(const GLdouble* const modelViewMatrix); - void setFromProjectionMatrix(const float matrix[12]); - - public: - /*! Sets the Camera position() (the eye), defined in the world coordinate system. */ - void setPosition(const Vec& pos) { frame()->setPosition(pos); }; - void setOrientation(const Quaternion& q); - void setOrientation(float theta, float phi); - void setUpVector(const Vec& up, bool noMove=true); - void setViewDirection(const Vec& direction); - //@} - - - /*! @name Positioning tools */ - //@{ - public: - void lookAt(const Vec& target); - void showEntireScene(); - void fitSphere(const Vec& center, float radius); - void fitBoundingBox(const Vec& min, const Vec& max); - void centerScene(); - void interpolateToZoomOnPixel(const Point& pixel); - void interpolateToFitScene(); - void interpolateTo(const Frame& fr, float duration); - //@} - - - /*! @name Frustum */ - //@{ - public: - /*! Returns the Camera::Type of the Camera. - - Set by setType(). Mainly used by loadProjectionMatrix(). - - A Camera::PERSPECTIVE Camera uses a classical projection mainly defined by its fieldOfView(). - - With a Camera::ORTHOGRAPHIC type(), the fieldOfView() is meaningless and the width and height of - the Camera frustum are inferred from the distance to the revolveAroundPoint() using - getOrthoWidthHeight(). - - Both types use zNear() and zFar() (to define their clipping planes) and aspectRatio() (for - frustum shape). */ - Type type() const { return type_; }; - - /*! Returns the vertical field of view of the Camera (in radians). - - Value is set using setFieldOfView(). Default value is pi/4 radians. This value is meaningless if - the Camera type() is Camera::ORTHOGRAPHIC. - - The field of view corresponds the one used in \c gluPerspective (see manual). It sets the Y - (vertical) aperture of the Camera. The X (horizontal) angle is inferred from the window aspect - ratio (see aspectRatio() and horizontalFieldOfView()). - - Use setFOVToFitScene() to adapt the fieldOfView() to a given scene. */ - float fieldOfView() const { return fieldOfView_; }; - - /*! Returns the horizontal field of view of the Camera (in radians). - - Value is set using setHorizontalFieldOfView() or setFieldOfView(). These values - are always linked by: - \code - horizontalFieldOfView() = 2.0 * atan ( tan(fieldOfView()/2.0) * aspectRatio() ). - \endcode */ - float horizontalFieldOfView() const { return 2.0 * atan ( tan(fieldOfView()/2.0) * aspectRatio() ); }; - - /*! Returns the Camera aspect ratio defined by screenWidth() / screenHeight(). - - When the Camera is attached to a QGLViewer, these values and hence the aspectRatio() are - automatically fitted to the viewer's window aspect ratio using setScreenWidthAndHeight(). */ - float aspectRatio() const { return static_cast<float>(screenWidth_)/static_cast<float>(screenHeight_); }; - /*! Returns the width (in pixels) of the Camera screen. - - Set using setScreenWidthAndHeight(). This value is automatically fitted to the QGLViewer's - window dimensions when the Camera is attached to a QGLViewer. See also QGLWidget::width() */ - int screenWidth() const { return screenWidth_; }; - /*! Returns the height (in pixels) of the Camera screen. - - Set using setScreenWidthAndHeight(). This value is automatically fitted to the QGLViewer's - window dimensions when the Camera is attached to a QGLViewer. See also QGLWidget::height() */ - int screenHeight() const { return screenHeight_; }; - void getViewport(GLint viewport[4]) const; - float pixelGLRatio(const Vec& position) const; - - /*! Returns the coefficient which is used to set zNear() when the Camera is inside the sphere - defined by sceneCenter() and zClippingCoefficient() * sceneRadius(). - - In that case, the zNear() value is set to zNearCoefficient() * zClippingCoefficient() * - sceneRadius(). See the zNear() documentation for details. - - Default value is 0.005, which is appropriate for most applications. In case you need a high - dynamic ZBuffer precision, you can increase this value (~0.1). A lower value will prevent - clipping of very close objects at the expense of a worst Z precision. - - Only meaningful when Camera type is Camera::PERSPECTIVE. */ - float zNearCoefficient() const { return zNearCoef_; }; - /*! Returns the coefficient used to position the near and far clipping planes. - - The near (resp. far) clipping plane is positioned at a distance equal to zClippingCoefficient() * - sceneRadius() in front of (resp. behind) the sceneCenter(). This garantees an optimal use of - the z-buffer range and minimizes aliasing. See the zNear() and zFar() documentations. - - Default value is square root of 3.0 (so that a cube of size sceneRadius() is not clipped). - - However, since the sceneRadius() is used for other purposes (see showEntireScene(), flySpeed(), - ...) and you may want to change this value to define more precisely the location of the clipping - planes. See also zNearCoefficient(). - - For a total control on clipping planes' positions, an other option is to overload the zNear() - and zFar() methods. See the <a href="../examples/standardCamera.html">standardCamera example</a>. - - \attention When QGLViewer::cameraPathAreEdited(), this value is set to 5.0 so that the Camera - paths are not clipped. The previous zClippingCoefficient() value is restored back when you leave - this mode. */ - float zClippingCoefficient() const { return zClippingCoef_; } - - virtual float zNear() const; - virtual float zFar() const; - virtual void getOrthoWidthHeight(GLdouble& halfWidth, GLdouble& halfHeight) const; - void getFrustumPlanesCoefficients(GLdouble coef[6][4]) const; - - public: - void setType(Type type); - - /*! Sets the vertical fieldOfView() of the Camera (in radians). - - Note that focusDistance() is set to sceneRadius() / tan(fieldOfView()/2) by this method. */ - void setFieldOfView(float fov) { fieldOfView_ = fov; setFocusDistance(sceneRadius() / tan(fov/2.0)); }; - - /*! Sets the horizontalFieldOfView() of the Camera (in radians). - - horizontalFieldOfView() and fieldOfView() are linked by the aspectRatio(). This method actually - calls setFieldOfView(( 2.0 * atan (tan(hfov / 2.0) / aspectRatio()) )) so that a call to - horizontalFieldOfView() returns the expected value. */ - void setHorizontalFieldOfView(float hfov) { setFieldOfView( 2.0 * atan (tan(hfov / 2.0) / aspectRatio()) ); }; - - void setFOVToFitScene(); - - /*! Defines the Camera aspectRatio(). - - This value is actually inferred from the screenWidth() / screenHeight() ratio. You should use - setScreenWidthAndHeight() instead. - - This method might however be convenient when the Camera is not associated with a QGLViewer. It - actually sets the screenHeight() to 100 and the screenWidth() accordingly. See also - setFOVToFitScene(). - - \note If you absolutely need an aspectRatio() that does not correspond to your viewer's window - dimensions, overload loadProjectionMatrix() or multiply the created GL_PROJECTION matrix by a - scaled diagonal matrix in your QGLViewer::draw() method. */ - void setAspectRatio(float aspect) { setScreenWidthAndHeight(int(100.0*aspect), 100); }; - - void setScreenWidthAndHeight(int width, int height); - /*! Sets the zNearCoefficient() value. */ - void setZNearCoefficient(float coef) { zNearCoef_ = coef; }; - /*! Sets the zClippingCoefficient() value. */ - void setZClippingCoefficient(float coef) { zClippingCoef_ = coef; } - //@} - - - /*! @name Scene radius and center */ - //@{ - public: - /*! Returns the radius of the scene observed by the Camera. - - You need to provide such an approximation of the scene dimensions so that the Camera can adapt - its zNear() and zFar() values. See the sceneCenter() documentation. - - See also setSceneBoundingBox(). - - Note that QGLViewer::sceneRadius() (resp. QGLViewer::setSceneRadius()) simply call this method - (resp. setSceneRadius()) on its associated QGLViewer::camera(). */ - float sceneRadius() const { return sceneRadius_; }; - - /*! Returns the position of the scene center, defined in the world coordinate system. - - The scene observed by the Camera should be roughly centered on this position, and included in a - sceneRadius() sphere. This approximate description of the scene permits a zNear() and zFar() - clipping planes definition, and allows convenient positioning methods such as showEntireScene(). - - Default value is (0,0,0) (world origin). Use setSceneCenter() to change it. See also - setSceneBoundingBox(). - - Note that QGLViewer::sceneCenter() (resp. QGLViewer::setSceneCenter()) simply call this method - (resp. setSceneCenter()) on its associated QGLViewer::camera(). */ - Vec sceneCenter() const { return sceneCenter_; }; - float distanceToSceneCenter() const; - - public: - void setSceneRadius(float radius); - void setSceneCenter(const Vec& center); - bool setSceneCenterFromPixel(const Point& pixel); - void setSceneBoundingBox(const Vec& min, const Vec& max); - //@} - - - /*! @name Revolve Around Point */ - //@{ - public: - void setRevolveAroundPoint(const Vec& rap); - bool setRevolveAroundPointFromPixel(const Point& pixel); - - public: - /*! The point the Camera revolves around with the QGLViewer::ROTATE mouse binding. Defined in world coordinate system. - - Default value is the sceneCenter(). - - \attention setSceneCenter() changes this value. */ - Vec revolveAroundPoint() const { return frame()->revolveAroundPoint(); }; - //@} - - - /*! @name Associated frame */ - //@{ - public: - /*! Returns the ManipulatedCameraFrame attached to the Camera. - - This ManipulatedCameraFrame defines its position() and orientation() and can translate mouse - events into Camera displacement. Set using setFrame(). */ - ManipulatedCameraFrame* frame() const { return frame_; }; - public: - void setFrame(ManipulatedCameraFrame* const mcf); - //@} - - - /*! @name KeyFramed paths */ - //@{ - public: - //KeyFrameInterpolator* keyFrameInterpolator(int i); - -public: - //void setKeyFrameInterpolator(int i, KeyFrameInterpolator* const kfi); - - //virtual void addKeyFrameToPath(int i); - //virtual void playPath(int i); - //virtual void deletePath(int i); - //virtual void resetPath(int i); - //@} - - - /*! @name OpenGL matrices */ - //@{ - public: - virtual void loadProjectionMatrix(bool reset=true) const; - virtual void loadModelViewMatrix(bool reset=true) const; - void computeProjectionMatrix() const; - void computeModelViewMatrix() const; - - virtual void loadProjectionMatrixStereo(bool leftBuffer=true) const; - virtual void loadModelViewMatrixStereo(bool leftBuffer=true) const; - - void getProjectionMatrix(GLdouble m[16]) const; - void getModelViewMatrix(GLdouble m[16]) const; - void getModelViewProjectionMatrix(GLdouble m[16]) const; - -#ifndef DOXYGEN - // Required for windows which otherwise silently fills - void getProjectionMatrix(GLfloat m[16]) const; - void getModelViewMatrix(GLfloat m[16]) const; -#endif - //@} - - - /*! @name Drawing */ - //@{ -#ifndef DOXYGEN - static void drawCamera(float scale=1.0, float aspectRatio=1.33, float fieldOfView=M_PI/4.0); -#endif - virtual void draw(bool drawFarPlane=true, float scale=1.0) const; - //@} - - - /*! @name World to Camera coordinate systems conversions */ - //@{ - public: - /*! Returns the Camera frame coordinates of a point \p src defined in world coordinates. - - worldCoordinatesOf() performs the inverse transformation. - - Note that the point coordinates are simply converted in a different coordinate system. They are - not projected on screen. Use projectedCoordinatesOf() for that. */ - Vec cameraCoordinatesOf(const Vec& src) const { return frame()->coordinatesOf(src); }; - /*! Returns the world coordinates of the point whose position \p src is defined in the Camera - coordinate system. - - cameraCoordinatesOf() performs the inverse transformation. */ - Vec worldCoordinatesOf(const Vec& src) const { return frame()->inverseCoordinatesOf(src); }; - void getCameraCoordinatesOf(const float src[3], float res[3]) const; - void getWorldCoordinatesOf(const float src[3], float res[3]) const; - //@} - - - /*! @name 2D screen to 3D world coordinate systems conversions */ - //@{ - public: - Vec projectedCoordinatesOf(const Vec& src, const Frame* frame=NULL) const; - Vec unprojectedCoordinatesOf(const Vec& src, const Frame* frame=NULL) const; - void getProjectedCoordinatesOf(const float src[3], float res[3], const Frame* frame=NULL) const; - void getUnprojectedCoordinatesOf(const float src[3], float res[3], const Frame* frame=NULL) const; - void convertClickToLine(const Point& pixel, Vec& orig, Vec& dir) const; - Vec pointUnderPixel(const Point& pixel, bool& found) const; - //@} - - - /*! @name Fly speed */ - //@{ - public: - /*! Returns the fly speed of the Camera. - - Simply returns frame()->flySpeed(). See the ManipulatedCameraFrame::flySpeed() documentation. - This value is only meaningful when the MouseAction bindings is QGLViewer::MOVE_FORWARD or - QGLViewer::MOVE_BACKWARD. - - Set to 0.5% of the sceneRadius() by setSceneRadius(). See also setFlySpeed(). */ - float flySpeed() const { return frame()->flySpeed(); }; - public: - /*! Sets the Camera flySpeed(). - - \attention This value is modified by setSceneRadius(). */ - void setFlySpeed(float speed) { frame()->setFlySpeed(speed); }; - //@} - - - /*! @name Stereo parameters */ - //@{ - public: - /*! Returns the user's inter-ocular distance (in meters). Default value is 0.062m, which fits most people. - - loadProjectionMatrixStereo() uses this value to define the Camera offset and frustum. See - setIODistance(). */ - float IODistance() const { return IODistance_; }; - - /*! Returns the physical distance between the user's eyes and the screen (in meters). - - Default value is 0.5m. - - Used by loadModelViewMatrixStereo() and loadProjectionMatrixStereo() for stereo display. Value - is set using setPhysicalDistanceToScreen(). - - physicalDistanceToScreen() and focusDistance() represent the same distance. The first one is - expressed in physical real world units, while the latter is expressed in OpenGL virtual world - units. Use their ratio to convert distances between these worlds. - - Use the following code to detect a reality center configuration (using its screen aspect ratio) - and to automatically set physical distances accordingly: - \code - QDesktopWidget screen; - if (fabs((float)screen.width() / (float)screen.height()) > 2.0) - { - camera()->setPhysicalDistanceToScreen(4.0); - camera()->setPhysicalScreenWidth(10.0); - } - \endcode */ - float physicalDistanceToScreen() const { return physicalDistanceToScreen_; }; - - /*! Returns the physical screen width, in meters. Default value is 0.4m (average monitor). - - Used for stereo display only (see loadModelViewMatrixStereo() and loadProjectionMatrixStereo()). - Set using setPhysicalScreenWidth(). - - See physicalDistanceToScreen() for reality center automatic configuration. */ - float physicalScreenWidth() const { return physicalScreenWidth_; }; - - /*! Returns the focus distance used by stereo display, expressed in OpenGL units. - - This is the distance in the virtual world between the Camera and the plane where the horizontal - stereo parallax is null (the stereo left and right images are superimposed). - - This distance is the virtual world equivalent of the real-world physicalDistanceToScreen(). - - \attention This value is modified by QGLViewer::setSceneRadius(), setSceneRadius() and - setFieldOfView(). When one of these values is modified, focusDistance() is set to sceneRadius() - / tan(fieldOfView()/2), which provides good results. */ - float focusDistance() const { return focusDistance_; }; - public: - /*! Sets the IODistance(). */ - void setIODistance(float distance) { IODistance_ = distance; }; - - /*! Sets the physicalDistanceToScreen(). */ - void setPhysicalDistanceToScreen(float distance) { physicalDistanceToScreen_ = distance; }; - - /*! Sets the physical screen (monitor or projected wall) width (in meters). */ - void setPhysicalScreenWidth(float width) { physicalScreenWidth_ = width; }; - - /*! Sets the focusDistance(), in OpenGL scene units. */ - void setFocusDistance(float distance) { focusDistance_ = distance; }; - //@} - - - private: - // F r a m e - ManipulatedCameraFrame* frame_; - - // C a m e r a p a r a m e t e r s - int screenWidth_, screenHeight_; // size of the window, in pixels - float fieldOfView_; // in radians - Vec sceneCenter_; - float sceneRadius_; // OpenGL units - float zNearCoef_; - float zClippingCoef_; - float orthoCoef_; - Type type_; // PERSPECTIVE or ORTHOGRAPHIC - mutable GLdouble modelViewMatrix_[16]; // Buffered model view matrix. - mutable GLdouble projectionMatrix_[16]; // Buffered projection matrix. - - // S t e r e o p a r a m e t e r s - float IODistance_; // inter-ocular distance, in meters - float focusDistance_; // in scene units - float physicalDistanceToScreen_; // in meters - float physicalScreenWidth_; // in meters - - // P o i n t s o f V i e w s a n d K e y F r a m e s - //map<int, KeyFrameInterpolator*> kfi_; - //KeyFrameInterpolator* interpolationKfi_; - }; - - -#endif // QGLVIEWER_CAMERA_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_config.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_config.h deleted file mode 100644 index f504ccb3d77..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_config.h +++ /dev/null @@ -1,59 +0,0 @@ -/////////////////////////////////////////////////////////////////// -// libQGLViewer configuration file // -// Modify these settings according to your local configuration // -/////////////////////////////////////////////////////////////////// - -#ifndef QGLVIEWER_CONFIG_H -#define QGLVIEWER_CONFIG_H - - - - - -#include <map> -#include <ostream> - -#include <math.h> -#include <iostream> - -using namespace std; - -// Pi definition -# ifndef M_PI -# define M_PI 3.14159265 -# endif // M_PI - -#include "AppGLWidget_point.h" - -# ifdef WIN32 -# include <windows.h> -# endif -# ifdef __MACH__ -# include <OpenGL/gl.h> -# else -# include <GL/gl.h> -# endif - -#ifdef __APPLE_CC__ - #include <GLUT/glut.h> -#else -# ifdef WIN32 -# include <GL/glu.h> -# else -# include <GL/glut.h> -# endif -#endif - -#ifndef Q_UNUSED - # define Q_UNUSED(x) (void)x; -#endif - -template <typename T> -inline const T &qMin(const T &a, const T &b) { if (a < b) return a; return b; } -template <typename T> -inline const T &qMax(const T &a, const T &b) { if (a < b) return b; return a; } -template <typename T> -inline const T &qBound(const T &min, const T &val, const T &max) -{ return qMax(min, qMin(max, val)); } - -#endif // QGLVIEWER_CONFIG_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_constraint.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_constraint.h deleted file mode 100644 index 4bd629a05de..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_constraint.h +++ /dev/null @@ -1,341 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#ifndef QGLVIEWER_CONSTRAINT_H -#define QGLVIEWER_CONSTRAINT_H - -#include "AppGLWidget_vec.h" -#include "AppGLWidget_quaternion.h" - -//namespace qglviewer { - class Frame; - class AppGLWidget_Camera; - - /*! \brief An interface class for Frame constraints. - \class Constraint constraint.h QGLViewer/constraint.h - - This class defines the interface for the Constraints that can be applied to a Frame to limit its - motion. Use Frame::setConstraint() to associate a Constraint to a Frame (default is a \c NULL - Frame::constraint()). - - <h3>How does it work ?</h3> - - The Constraint acts as a filter on the translation and rotation Frame increments. - constrainTranslation() and constrainRotation() should be overloaded to specify the constraint - behavior: the desired displacement is given as a parameter that can optionally be modified. - - Here is how the Frame::translate() and Frame::rotate() methods use the Constraint: - \code - Frame::translate(Vec& T) - { - if (constraint()) - constraint()->constrainTranslation(T, this); - t += T; - } - - Frame::rotate(Quaternion& Q) - { - if (constraint()) - constraint()->constrainRotation(Q, this); - q *= Q; - } - \endcode - - The default behavior of constrainTranslation() and constrainRotation() is empty (meaning no - filtering). - - The Frame which uses the Constraint is passed as a parameter to the constrainTranslation() and - constrainRotation() methods, so that they can have access to its current state (mainly - Frame::position() and Frame::orientation()). It is not \c const for versatility reasons, but - directly modifying it should be avoided. - - \attention Frame::setTranslation(), Frame::setRotation() and similar methods will actually indeed - set the frame position and orientation, without taking the constraint into account. Use the \e - WithConstraint versions of these methods to enforce the Constraint. - - <h3>Implemented Constraints</h3> - - Classical axial and plane Constraints are provided for convenience: see the LocalConstraint, - WorldConstraint and CameraConstraint classes' documentations. - - Try the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a - href="../examples/constrainedCamera.html">constrainedCamera</a> examples for an illustration. - - <h3>Creating new Constraints</h3> - - The implementation of a new Constraint class simply consists in overloading the filtering methods: - \code - // This Constraint enforces that the Frame cannot have a negative z world coordinate. - class myConstraint : public Constraint - { - public: - virtual void constrainTranslation(Vec& t, Frame * const fr) - { - // Express t in the world coordinate system. - const Vec tWorld = fr->inverseTransformOf(t); - if (fr->position().z + tWorld.z < 0.0) // check the new fr z coordinate - t.z = fr->transformOf(-fr->position().z); // t.z is clamped so that next z position is 0.0 - } - }; - \endcode - - Note that the translation (resp. rotation) parameter passed to constrainTranslation() (resp. - constrainRotation()) is expressed in the \e local Frame coordinate system. Here, we use the - Frame::transformOf() and Frame::inverseTransformOf() method to convert it to and from the world - coordinate system. - - Combined constraints can easily be achieved by creating a new class that applies the different - constraint filters: - \code - myConstraint::constrainTranslation(Vec& v, Frame* const fr) - { - constraint1->constrainTranslation(v, fr); - constraint2->constrainTranslation(v, fr); - // and so on, with possible branches, tests, loops... - } - \endcode - */ - class Constraint - { - public: - /*! Virtual destructor. Empty. */ - virtual ~Constraint() {}; - - /*! Filters the translation applied to the \p frame. This default implementation is empty (no - filtering). - - Overload this method in your own Constraint class to define a new translation constraint. \p - frame is the Frame to which is applied the translation. It is not defined \c const, but you - should refrain from directly changing its value in the constraint. Use its Frame::position() and - update the \p translation accordingly instead. - - \p translation is expressed in local frame coordinate system. Use Frame::inverseTransformOf() to - express it in the world coordinate system if needed. */ - virtual void constrainTranslation(Vec& translation, Frame* const frame) { Q_UNUSED(translation); Q_UNUSED(frame); }; - /*! Filters the rotation applied to the \p frame. This default implementation is empty (no - filtering). - - Overload this method in your own Constraint class to define a new rotation constraint. See - constrainTranslation() for details. - - Use Frame::inverseTransformOf() on the \p rotation Quaternion::axis() to express \p rotation in - the world coordinate system if needed. */ - virtual void constrainRotation(Quaternion& rotation, Frame* const frame) { Q_UNUSED(rotation); Q_UNUSED(frame); }; - }; - - /*! - \brief An abstract class for Frame Constraints defined by an axis or a plane. - \class AxisPlaneConstraint constraint.h QGLViewer/constraint.h - - AxisPlaneConstraint is an interface for (translation and/or rotation) Constraint that are defined - by a direction. translationConstraintType() and rotationConstraintType() define how this - direction should be interpreted: as an axis (AxisPlaneConstraint::AXIS) or as a plane normal - (AxisPlaneConstraint::PLANE). See the Type() documentation for details. - - The three implementations of this class: LocalConstraint, WorldConstraint and CameraConstraint - differ by the coordinate system in which this direction is expressed. - - Different implementations of this class are illustrated in the - <a href="../examples/constrainedCamera.html">contrainedCamera</a> and - <a href="../examples/constrainedFrame.html">constrainedFrame</a> examples. - - \attention When applied, the rotational Constraint may not intuitively follow the mouseQU - displacement. A solution would be to directly measure the rotation angle in screen coordinates, - but that would imply to know the QGLViewer::camera(), so that we can compute the projected - coordinates of the rotation center (as is done with the QGLViewer::SCREEN_ROTATE binding). - However, adding an extra pointer to the QGLViewer::camera() in all the AxisPlaneConstraint - derived classes (which the user would have to update in a multi-viewer application) was judged as - an overkill. */ - class AxisPlaneConstraint : public Constraint - { - public: - AxisPlaneConstraint(); - /*! Virtual destructor. Empty. */ - virtual ~AxisPlaneConstraint() {}; - - /*! Type lists the different types of translation and rotation constraints that are available. - - It specifies the meaning of the constraint direction (see translationConstraintDirection() and - rotationConstraintDirection()): as an axis direction (AxisPlaneConstraint::AXIS) or a plane - normal (AxisPlaneConstraint::PLANE). AxisPlaneConstraint::FREE means no constraint while - AxisPlaneConstraint::FORBIDDEN completely forbids the translation and/or the rotation. - - See translationConstraintType() and rotationConstraintType(). - - \attention The AxisPlaneConstraint::PLANE Type is not valid for rotational constraint. - - New derived classes can use their own extended enum for specific constraints: - \code - class MyAxisPlaneConstraint : public AxisPlaneConstraint - { - public: - enum MyType { FREE, AXIS, PLANE, FORBIDDEN, CUSTOM }; - virtual void constrainTranslation(Vec &translation, Frame *const frame) - { - // translationConstraintType() is simply an int. CUSTOM Type is handled seamlessly. - switch (translationConstraintType()) - { - case MyAxisPlaneConstraint::FREE: ... break; - case MyAxisPlaneConstraint::CUSTOM: ... break; - } - }; - - MyAxisPlaneConstraint* c = new MyAxisPlaneConstraint(); - // Note the Type conversion - c->setTranslationConstraintType(AxisPlaneConstraint::Type(MyAxisPlaneConstraint::CUSTOM)); - }; - \endcode */ - enum Type { FREE, AXIS, PLANE, FORBIDDEN }; - - /*! @name Translation constraint */ - //@{ - /*! Overloading of Constraint::constrainTranslation(). Empty */ - virtual void constrainTranslation(Vec& translation, Frame* const frame) { Q_UNUSED(translation); Q_UNUSED(frame); }; - - void setTranslationConstraint(Type type, const Vec& direction); - /*! Sets the Type() of the translationConstraintType(). Default is AxisPlaneConstraint::FREE. */ - void setTranslationConstraintType(Type type) { translationConstraintType_ = type; }; - void setTranslationConstraintDirection(const Vec& direction); - - /*! Returns the translation constraint Type(). - - Depending on this value, the Frame will freely translate (AxisPlaneConstraint::FREE), will only - be able to translate along an axis direction (AxisPlaneConstraint::AXIS), will be forced to stay - into a plane (AxisPlaneConstraint::PLANE) or will not able to translate at all - (AxisPlaneConstraint::FORBIDDEN). - - Use Frame::setPosition() to define the position of the constrained Frame before it gets - constrained. */ - Type translationConstraintType() const { return translationConstraintType_; }; - /*! Returns the direction used by the translation constraint. - - It represents the axis direction (AxisPlaneConstraint::AXIS) or the plane normal - (AxisPlaneConstraint::PLANE) depending on the translationConstraintType(). It is undefined for - AxisPlaneConstraint::FREE or AxisPlaneConstraint::FORBIDDEN. - - The AxisPlaneConstraint derived classes express this direction in different coordinate system - (camera for CameraConstraint, local for LocalConstraint, and world for WorldConstraint). This - value can be modified with setTranslationConstraintDirection(). */ - Vec translationConstraintDirection() const { return translationConstraintDir_; }; - //@} - - /*! @name Rotation constraint */ - //@{ - /*! Overloading of Constraint::constrainRotation(). Empty. */ - virtual void constrainRotation(Quaternion& rotation, Frame* const frame) { Q_UNUSED(rotation); Q_UNUSED(frame); }; - - void setRotationConstraint(Type type, const Vec& direction); - void setRotationConstraintType(Type type); - void setRotationConstraintDirection(const Vec& direction); - - /*! Returns the rotation constraint Type(). */ - Type rotationConstraintType() const { return rotationConstraintType_; }; - /*! Returns the axis direction used by the rotation constraint. - - This direction is defined only when rotationConstraintType() is AxisPlaneConstraint::AXIS. - - The AxisPlaneConstraint derived classes express this direction in different coordinate system - (camera for CameraConstraint, local for LocalConstraint, and world for WorldConstraint). This - value can be modified with setRotationConstraintDirection(). */ - Vec rotationConstraintDirection() const { return rotationConstraintDir_; }; - //@} - - private: - // int and not Type to allow for overloading and new types definition. - Type translationConstraintType_; - Type rotationConstraintType_; - - Vec translationConstraintDir_; - Vec rotationConstraintDir_; - }; - - - /*! \brief An AxisPlaneConstraint defined in the Frame local coordinate system. - \class LocalConstraint constraint.h QGLViewer/constraint.h - - The translationConstraintDirection() and rotationConstraintDirection() are expressed in the Frame - local coordinate system (see Frame::referenceFrame()). - - See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> example for an illustration. */ - class LocalConstraint : public AxisPlaneConstraint - { - public: - /*! Virtual destructor. Empty. */ - virtual ~LocalConstraint() {}; - - virtual void constrainTranslation(Vec& translation, Frame* const frame); - virtual void constrainRotation (Quaternion& rotation, Frame* const frame); - }; - - - - /*! \brief An AxisPlaneConstraint defined in the world coordinate system. - \class WorldConstraint constraint.h QGLViewer/constraint.h - - The translationConstraintDirection() and rotationConstraintDirection() are expressed in world - coordinate system. - - See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a - href="../examples/multiView.html">multiView</a> examples for an illustration. */ - class WorldConstraint : public AxisPlaneConstraint - { - public: - /*! Virtual destructor. Empty. */ - virtual ~WorldConstraint() {}; - - virtual void constrainTranslation(Vec& translation, Frame* const frame); - virtual void constrainRotation (Quaternion& rotation, Frame* const frame); - }; - - - - /*! \brief An AxisPlaneConstraint defined in the camera coordinate system. - \class CameraConstraint constraint.h QGLViewer/constraint.h - - The translationConstraintDirection() and rotationConstraintDirection() are expressed in the - associated camera() coordinate system. - - See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a - href="../examples/constrainedCamera.html">constrainedCamera</a> examples for an illustration. */ - class CameraConstraint : public AxisPlaneConstraint - { - public: - explicit CameraConstraint(const AppGLWidget_Camera* const camera); - /*! Virtual destructor. Empty. */ - virtual ~CameraConstraint() {}; - - virtual void constrainTranslation(Vec& translation, Frame* const frame); - virtual void constrainRotation (Quaternion& rotation, Frame* const frame); - - /*! Returns the associated Camera. Set using the CameraConstraint constructor. */ - const AppGLWidget_Camera* camera() const { return camera_; }; - - private: - const AppGLWidget_Camera* const camera_; - }; - -//} // namespace qglviewer - -#endif // QGLVIEWER_CONSTRAINT_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.cpp b/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.cpp deleted file mode 100644 index 8fb17a7c1c6..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.cpp +++ /dev/null @@ -1,1070 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#include "AppGLWidget_frame.h" -#include <math.h> - -//using namespace qglviewer; -using namespace std; - - -/*! Creates a default Frame. - - Its position() is (0,0,0) and it has an identity orientation() Quaternion. The referenceFrame() - and the constraint() are \c NULL. */ -Frame::Frame() - : constraint_(NULL), referenceFrame_(NULL) -{} - -/*! Creates a Frame with a position() and an orientation(). - - See the Vec and Quaternion documentations for convenient constructors and methods. - - The Frame is defined in the world coordinate system (its referenceFrame() is \c NULL). It - has a \c NULL associated constraint(). */ -Frame::Frame(const Vec& position, const Quaternion& orientation) - : t_(position), q_(orientation), constraint_(NULL), referenceFrame_(NULL) -{} - -/*! Equal operator. - - The referenceFrame() and constraint() pointers are copied. - - \attention Signal and slot connections are not copied. */ -Frame& Frame::operator=(const Frame& frame) -{ - // Automatic compiler generated version would not emit the modified signals as is done in - // setTranslationAndRotation. - setTranslationAndRotation(frame.translation(), frame.rotation()); - setConstraint(frame.constraint()); - setReferenceFrame(frame.referenceFrame()); - return *this; -} - -/*! Copy constructor. - - The translation() and rotation() as well as constraint() and referenceFrame() pointers are - copied. */ -Frame::Frame(const Frame& frame) -{ - (*this) = frame; -} - -/////////////////////////////// MATRICES ////////////////////////////////////// - -/*! Returns the 4x4 OpenGL transformation matrix represented by the Frame. - - This method should be used in conjunction with \c glMultMatrixd() to modify the OpenGL modelview - matrix from a Frame hierarchy. With this Frame hierarchy: - \code - Frame* body = new Frame(); - Frame* leftArm = new Frame(); - Frame* rightArm = new Frame(); - leftArm->setReferenceFrame(body); - rightArm->setReferenceFrame(body); - \endcode - - The associated OpenGL drawing code should look like: - \code - void Viewer::draw() - { - glPushMatrix(); - glMultMatrixd(body->matrix()); - drawBody(); - - glPushMatrix(); - glMultMatrixd(leftArm->matrix()); - drawArm(); - glPopMatrix(); - - glPushMatrix(); - glMultMatrixd(rightArm->matrix()); - drawArm(); - glPopMatrix(); - - glPopMatrix(); - } - \endcode - Note the use of nested \c glPushMatrix() and \c glPopMatrix() blocks to represent the frame hierarchy: \c - leftArm and \c rightArm are both correctly drawn with respect to the \c body coordinate system. - - This matrix only represents the local Frame transformation (i.e. with respect to the - referenceFrame()). Use worldMatrix() to get the full Frame transformation matrix (i.e. from the - world to the Frame coordinate system). These two match when the referenceFrame() is \c NULL. - - The result is only valid until the next call to matrix(), getMatrix(), worldMatrix() or - getWorldMatrix(). Use it immediately (as above) or use getMatrix() instead. - - \attention The OpenGL format of the result is the transpose of the actual mathematical European - representation (translation is on the last \e line instead of the last \e column). - - \note The scaling factor of the 4x4 matrix is 1.0. */ -const GLdouble* Frame::matrix() const -{ - static GLdouble m[4][4]; - getMatrix(m); - return (const GLdouble*)(m); -} - -/*! \c GLdouble[4][4] version of matrix(). See also getWorldMatrix() and matrix(). */ -void Frame::getMatrix(GLdouble m[4][4]) const -{ - q_.getMatrix(m); - - m[3][0] = t_[0]; - m[3][1] = t_[1]; - m[3][2] = t_[2]; -} - -/*! \c GLdouble[16] version of matrix(). See also getWorldMatrix() and matrix(). */ -void Frame::getMatrix(GLdouble m[16]) const -{ - q_.getMatrix(m); - - m[12] = t_[0]; - m[13] = t_[1]; - m[14] = t_[2]; -} - -/*! Returns a Frame representing the inverse of the Frame space transformation. - - The rotation() of the new Frame is the Quaternion::inverse() of the original rotation. - Its translation() is the negated inverse rotated image of the original translation. - - If a Frame is considered as a space rigid transformation (translation and rotation), the inverse() - Frame performs the inverse transformation. - - Only the local Frame transformation (i.e. defined with respect to the referenceFrame()) is inverted. - Use worldInverse() for a global inverse. - - The resulting Frame has the same referenceFrame() as the Frame and a \c NULL constraint(). - - \note The scaling factor of the 4x4 matrix is 1.0. */ -Frame Frame::inverse() const -{ - Frame fr(-(q_.inverseRotate(t_)), q_.inverse()); - fr.setReferenceFrame(referenceFrame()); - return fr; -} - -/*! Returns the 4x4 OpenGL transformation matrix represented by the Frame. - - This method should be used in conjunction with \c glMultMatrixd() to modify - the OpenGL modelview matrix from a Frame: - \code - // The modelview here corresponds to the world coordinate system. - Frame fr(pos, Quaternion(from, to)); - glPushMatrix(); - glMultMatrixd(fr.worldMatrix()); - // draw object in the fr coordinate system. - glPopMatrix(); - \endcode - - This matrix represents the global Frame transformation: the entire referenceFrame() hierarchy is - taken into account to define the Frame transformation from the world coordinate system. Use - matrix() to get the local Frame transformation matrix (i.e. defined with respect to the - referenceFrame()). These two match when the referenceFrame() is \c NULL. - - The OpenGL format of the result is the transpose of the actual mathematical European - representation (translation is on the last \e line instead of the last \e column). - - \attention The result is only valid until the next call to matrix(), getMatrix(), worldMatrix() or - getWorldMatrix(). Use it immediately (as above) or use getWorldMatrix() instead. - - \note The scaling factor of the 4x4 matrix is 1.0. */ -const GLdouble* Frame::worldMatrix() const -{ - // This test is done for efficiency reasons (creates lots of temp objects otherwise). - if (referenceFrame()) - { - static Frame fr; - fr.setTranslation(position()); - fr.setRotation(orientation()); - return fr.matrix(); - } - else - return matrix(); -} - -/*! float[4][4] parameter version of worldMatrix(). See also getMatrix() and matrix(). */ -void Frame::getWorldMatrix(GLdouble m[4][4]) const -{ - const GLdouble* mat = worldMatrix(); - for (int i=0; i<4; ++i) - for (int j=0; j<4; ++j) - m[i][j] = mat[i*4+j]; -} - -/*! float[16] parameter version of worldMatrix(). See also getMatrix() and matrix(). */ -void Frame::getWorldMatrix(GLdouble m[16]) const -{ - const GLdouble* mat = worldMatrix(); - for (int i=0; i<16; ++i) - m[i] = mat[i]; -} - -/*! This is an overloaded method provided for convenience. Same as setFromMatrix(). */ -void Frame::setFromMatrix(const GLdouble m[4][4]) -{ - if (fabs(m[3][3]) < 1E-8) - { - cout << "Frame::setFromMatrix: Null homogeneous coefficient" << endl; - return; - } - - double rot[3][3]; - for (int i=0; i<3; ++i) - { - t_[i] = m[3][i] / m[3][3]; - for (int j=0; j<3; ++j) - // Beware of the transposition (OpenGL to European math) - rot[i][j] = m[j][i] / m[3][3]; - } - q_.setFromRotationMatrix(rot); -} - -/*! Sets the Frame from an OpenGL matrix representation (rotation in the upper left 3x3 matrix and - translation on the last line). - - Hence, if a code fragment looks like: - \code - GLdouble m[16]={...}; - glMultMatrixd(m); - \endcode - It is equivalent to write: - \code - Frame fr; - fr.setFromMatrix(m); - glMultMatrixd(fr.matrix()); - \endcode - - Using this conversion, you can benefit from the powerful Frame transformation methods to translate - points and vectors to and from the Frame coordinate system to any other Frame coordinate system - (including the world coordinate system). See coordinatesOf() and transformOf(). - - Emits the modified() signal. See also matrix(), getMatrix() and - Quaternion::setFromRotationMatrix(). - - \attention A Frame does not contain a scale factor. The possible scaling in \p m will not be - converted into the Frame by this method. */ -void Frame::setFromMatrix(const GLdouble m[16]) -{ - GLdouble mat[4][4]; - for (int i=0; i<4; ++i) - for (int j=0; j<4; ++j) - mat[i][j] = m[i*4+j]; - setFromMatrix(mat); -} - -//////////////////// SET AND GET LOCAL TRANSLATION AND ROTATION /////////////////////////////// - - -/*! Same as setTranslation(), but with \p float parameters. */ -void Frame::setTranslation(float x, float y, float z) -{ - setTranslation(Vec(x, y, z)); -} - -/*! Fill \c x, \c y and \c z with the translation() of the Frame. */ -void Frame::getTranslation(float& x, float& y, float& z) const -{ - const Vec t = translation(); - x = t[0]; - y = t[1]; - z = t[2]; -} - -/*! Same as setRotation() but with \c float Quaternion parameters. */ -void Frame::setRotation(double q0, double q1, double q2, double q3) -{ - setRotation(Quaternion(q0, q1, q2, q3)); -} - -/*! The \p q are set to the rotation() of the Frame. - -See Quaternion::Quaternion(double, double, double, double) for details on \c q. */ -void Frame::getRotation(double& q0, double& q1, double& q2, double& q3) const -{ - const Quaternion q = rotation(); - q0 = q[0]; - q1 = q[1]; - q2 = q[2]; - q3 = q[3]; -} - -//////////////////////////////////////////////////////////////////////////////// - -/*! Translates the Frame of \p t (defined in the Frame coordinate system). - - The translation actually applied to the Frame may differ from \p t since it can be filtered by the - constraint(). Use translate(Vec&) or setTranslationWithConstraint() to retrieve the filtered - translation value. Use setTranslation() to directly translate the Frame without taking the - constraint() into account. - - See also rotate(const Quaternion&). Emits the modified() signal. */ -void Frame::translate(const Vec& t) -{ - Vec tbis = t; - translate(tbis); -} - -/*! Same as translate(const Vec&) but \p t may be modified to satisfy the translation constraint(). - Its new value corresponds to the translation that has actually been applied to the Frame. */ -void Frame::translate(Vec& t) -{ - if (constraint()) - constraint()->constrainTranslation(t, this); - t_ += t; -} - -/*! Same as translate(const Vec&) but with \c float parameters. */ -void Frame::translate(float x, float y, float z) -{ - Vec t(x,y,z); - translate(t); -} - -/*! Same as translate(Vec&) but with \c float parameters. */ -void Frame::translate(float& x, float& y, float& z) -{ - Vec t(x,y,z); - translate(t); - x = t[0]; - y = t[1]; - z = t[2]; -} - -/*! Rotates the Frame by \p q (defined in the Frame coordinate system): R = R*q. - - The rotation actually applied to the Frame may differ from \p q since it can be filtered by the - constraint(). Use rotate(Quaternion&) or setRotationWithConstraint() to retrieve the filtered - rotation value. Use setRotation() to directly rotate the Frame without taking the constraint() - into account. - - See also translate(const Vec&). Emits the modified() signal. */ -void Frame::rotate(const Quaternion& q) -{ - Quaternion qbis = q; - rotate(qbis); -} - -/*! Same as rotate(const Quaternion&) but \p q may be modified to satisfy the rotation constraint(). - Its new value corresponds to the rotation that has actually been applied to the Frame. */ -void Frame::rotate(Quaternion& q) -{ - if (constraint()) - constraint()->constrainRotation(q, this); - q_ *= q; - q_.normalize(); // Prevents numerical drift -} - -/*! Same as rotate(Quaternion&) but with \c float Quaternion parameters. */ -void Frame::rotate(double& q0, double& q1, double& q2, double& q3) -{ - Quaternion q(q0,q1,q2,q3); - rotate(q); - q0 = q[0]; - q1 = q[1]; - q2 = q[2]; - q3 = q[3]; -} - -/*! Same as rotate(const Quaternion&) but with \c float Quaternion parameters. */ -void Frame::rotate(double q0, double q1, double q2, double q3) -{ - Quaternion q(q0,q1,q2,q3); - rotate(q); -} - -/*! Makes the Frame rotate() by \p rotation around \p point. - - \p point is defined in the world coordinate system, while the \p rotation axis is defined in the - Frame coordinate system. - - If the Frame has a constraint(), \p rotation is first constrained using - Constraint::constrainRotation(). The translation which results from the filtered rotation around - \p point is then computed and filtered using Constraint::constrainTranslation(). The new \p - rotation value corresponds to the rotation that has actually been applied to the Frame. - - Emits the modified() signal. */ -void Frame::rotateAroundPoint(Quaternion& rotation, const Vec& point) -{ - if (constraint()) - constraint()->constrainRotation(rotation, this); - q_ *= rotation; - q_.normalize(); // Prevents numerical drift - Vec trans = point + Quaternion(inverseTransformOf(rotation.axis()), rotation.angle()).rotate(position()-point) - t_; - if (constraint()) - constraint()->constrainTranslation(trans, this); - t_ += trans; -} - -/*! Same as rotateAroundPoint(), but with a \c const \p rotation Quaternion. Note that the actual - rotation may differ since it can be filtered by the constraint(). */ -void Frame::rotateAroundPoint(const Quaternion& rotation, const Vec& point) -{ - Quaternion rot = rotation; - rotateAroundPoint(rot, point); -} - -//////////////////// SET AND GET WORLD POSITION AND ORIENTATION /////////////////////////////// - -/*! Sets the position() of the Frame, defined in the world coordinate system. Emits the modified() - signal. - -Use setTranslation() to define the \e local frame translation (with respect to the -referenceFrame()). The potential constraint() of the Frame is not taken into account, use -setPositionWithConstraint() instead. */ -void Frame::setPosition(const Vec& position) -{ - if (referenceFrame()) - setTranslation(referenceFrame()->coordinatesOf(position)); - else - setTranslation(position); -} - -/*! Same as setPosition(), but with \c float parameters. */ -void Frame::setPosition(float x, float y, float z) -{ - setPosition(Vec(x, y, z)); -} - -/*! Same as successive calls to setPosition() and then setOrientation(). - -Only one modified() signal is emitted, which is convenient if this signal is connected to a -QGLViewer::updateGL() slot. See also setTranslationAndRotation() and -setPositionAndOrientationWithConstraint(). */ -void Frame::setPositionAndOrientation(const Vec& position, const Quaternion& orientation) -{ - if (referenceFrame()) - { - t_ = referenceFrame()->coordinatesOf(position); - q_ = referenceFrame()->orientation().inverse() * orientation; - } - else - { - t_ = position; - q_ = orientation; - } -} - - -/*! Same as successive calls to setTranslation() and then setRotation(). - -Only one modified() signal is emitted, which is convenient if this signal is connected to a -QGLViewer::updateGL() slot. See also setPositionAndOrientation() and -setTranslationAndRotationWithConstraint(). */ -void Frame::setTranslationAndRotation(const Vec& translation, const Quaternion& rotation) -{ - t_ = translation; - q_ = rotation; -} - - -/*! \p x, \p y and \p z are set to the position() of the Frame. */ -void Frame::getPosition(float& x, float& y, float& z) const -{ - Vec p = position(); - x = p.x; - y = p.y; - z = p.z; -} - -/*! Sets the orientation() of the Frame, defined in the world coordinate system. Emits the modified() signal. - -Use setRotation() to define the \e local frame rotation (with respect to the referenceFrame()). The -potential constraint() of the Frame is not taken into account, use setOrientationWithConstraint() -instead. */ -void Frame::setOrientation(const Quaternion& orientation) -{ - if (referenceFrame()) - setRotation(referenceFrame()->orientation().inverse() * orientation); - else - setRotation(orientation); -} - -/*! Same as setOrientation(), but with \c float parameters. */ -void Frame::setOrientation(double q0, double q1, double q2, double q3) -{ - setOrientation(Quaternion(q0, q1, q2, q3)); -} - -/*! Get the current orientation of the frame (same as orientation()). - Parameters are the orientation Quaternion values. - See also setOrientation(). */ - -/*! The \p q are set to the orientation() of the Frame. - -See Quaternion::Quaternion(double, double, double, double) for details on \c q. */ -void Frame::getOrientation(double& q0, double& q1, double& q2, double& q3) const -{ - Quaternion o = orientation(); - q0 = o[0]; - q1 = o[1]; - q2 = o[2]; - q3 = o[3]; -} - -/*! Returns the orientation of the Frame, defined in the world coordinate system. See also - position(), setOrientation() and rotation(). */ -Quaternion Frame::orientation() const -{ - Quaternion res = rotation(); - const Frame* fr = referenceFrame(); - while (fr != NULL) - { - res = fr->rotation() * res; - fr = fr->referenceFrame(); - } - return res; -} - - -////////////////////// C o n s t r a i n t V e r s i o n s ////////////////////////// - -/*! Same as setTranslation(), but \p translation is modified so that the potential constraint() of the - Frame is satisfied. - - Emits the modified() signal. See also setRotationWithConstraint() and setPositionWithConstraint(). */ -void Frame::setTranslationWithConstraint(Vec& translation) -{ - Vec deltaT = translation - this->translation(); - if (constraint()) - constraint()->constrainTranslation(deltaT, this); - - setTranslation(this->translation() + deltaT); - translation = this->translation(); -} - -/*! Same as setRotation(), but \p rotation is modified so that the potential constraint() of the - Frame is satisfied. - - Emits the modified() signal. See also setTranslationWithConstraint() and setOrientationWithConstraint(). */ -void Frame::setRotationWithConstraint(Quaternion& rotation) -{ - Quaternion deltaQ = this->rotation().inverse() * rotation; - if (constraint()) - constraint()->constrainRotation(deltaQ, this); - - // Prevent numerical drift - deltaQ.normalize(); - - setRotation(this->rotation() * deltaQ); - q_.normalize(); - rotation = this->rotation(); -} - -/*! Same as setTranslationAndRotation(), but \p translation and \p orientation are modified to - satisfy the constraint(). Emits the modified() signal. */ -void Frame::setTranslationAndRotationWithConstraint(Vec& translation, Quaternion& rotation) -{ - Vec deltaT = translation - this->translation(); - Quaternion deltaQ = this->rotation().inverse() * rotation; - - if (constraint()) - { - constraint()->constrainTranslation(deltaT, this); - constraint()->constrainRotation(deltaQ, this); - } - - // Prevent numerical drift - deltaQ.normalize(); - - t_ += deltaT; - q_ *= deltaQ; - q_.normalize(); - - translation = this->translation(); - rotation = this->rotation(); - -} - -/*! Same as setPosition(), but \p position is modified so that the potential constraint() of the - Frame is satisfied. See also setOrientationWithConstraint() and setTranslationWithConstraint(). */ -void Frame::setPositionWithConstraint(Vec& position) -{ - if (referenceFrame()) - position = referenceFrame()->coordinatesOf(position); - - setTranslationWithConstraint(position); -} - -/*! Same as setOrientation(), but \p orientation is modified so that the potential constraint() of the Frame - is satisfied. See also setPositionWithConstraint() and setRotationWithConstraint(). */ -void Frame::setOrientationWithConstraint(Quaternion& orientation) -{ - if (referenceFrame()) - orientation = referenceFrame()->orientation().inverse() * orientation; - - setRotationWithConstraint(orientation); -} - -/*! Same as setPositionAndOrientation() but \p position and \p orientation are modified to satisfy -the constraint. Emits the modified() signal. */ -void Frame::setPositionAndOrientationWithConstraint(Vec& position, Quaternion& orientation) -{ - if (referenceFrame()) - { - position = referenceFrame()->coordinatesOf(position); - orientation = referenceFrame()->orientation().inverse() * orientation; - } - setTranslationAndRotationWithConstraint(position, orientation); -} - - -///////////////////////////// REFERENCE FRAMES /////////////////////////////////////// - -/*! Sets the referenceFrame() of the Frame. - -The Frame translation() and rotation() are then defined in the referenceFrame() coordinate system. -Use position() and orientation() to express these in the world coordinate system. - -Emits the modified() signal if \p refFrame differs from the current referenceFrame(). - -Using this method, you can create a hierarchy of Frames. This hierarchy needs to be a tree, which -root is the world coordinate system (i.e. a \c NULL referenceFrame()). A warning is printed and no -action is performed if setting \p refFrame as the referenceFrame() would create a loop in the Frame -hierarchy (see settingAsReferenceFrameWillCreateALoop()). */ -void Frame::setReferenceFrame(const Frame* const refFrame) -{ - if (settingAsReferenceFrameWillCreateALoop(refFrame)) - cout << "Frame::setReferenceFrame would create a loop in Frame hierarchy" << endl; - else - { - //bool identical = (referenceFrame_ == refFrame); - referenceFrame_ = refFrame; - } -} - -/*! Returns \c true if setting \p frame as the Frame's referenceFrame() would create a loop in the - Frame hierarchy. */ -bool Frame::settingAsReferenceFrameWillCreateALoop(const Frame* const frame) -{ - const Frame* f = frame; - while (f != NULL) - { - if (f == this) - return true; - f = f->referenceFrame(); - } - return false; -} - -///////////////////////// FRAME TRANSFORMATIONS OF 3D POINTS ////////////////////////////// - -/*! Returns the Frame coordinates of a point \p src defined in the world coordinate system (converts - from world to Frame). - - inverseCoordinatesOf() performs the inverse convertion. transformOf() converts 3D vectors instead - of 3D coordinates. - - See the <a href="../examples/frameTransform.html">frameTransform example</a> for an - illustration. */ -Vec Frame::coordinatesOf(const Vec& src) const -{ - if (referenceFrame()) - return localCoordinatesOf(referenceFrame()->coordinatesOf(src)); - else - return localCoordinatesOf(src); -} - -/*! Returns the world coordinates of the point whose position in the Frame coordinate system is \p - src (converts from Frame to world). - - coordinatesOf() performs the inverse convertion. Use inverseTransformOf() to transform 3D vectors - instead of 3D coordinates. */ -Vec Frame::inverseCoordinatesOf(const Vec& src) const -{ - const Frame* fr = this; - Vec res = src; - while (fr != NULL) - { - res = fr->localInverseCoordinatesOf(res); - fr = fr->referenceFrame(); - } - return res; -} - -/*! Returns the Frame coordinates of a point \p src defined in the referenceFrame() coordinate - system (converts from referenceFrame() to Frame). - - localInverseCoordinatesOf() performs the inverse convertion. See also localTransformOf(). */ -Vec Frame::localCoordinatesOf(const Vec& src) const -{ - return rotation().inverseRotate(src - translation()); -} - -/*! Returns the referenceFrame() coordinates of a point \p src defined in the Frame coordinate - system (converts from Frame to referenceFrame()). - - localCoordinatesOf() performs the inverse convertion. See also localInverseTransformOf(). */ -Vec Frame::localInverseCoordinatesOf(const Vec& src) const -{ - return rotation().rotate(src) + translation(); -} - -/*! Returns the Frame coordinates of the point whose position in the \p from coordinate system is \p - src (converts from \p from to Frame). - - coordinatesOfIn() performs the inverse transformation. */ -Vec Frame::coordinatesOfFrom(const Vec& src, const Frame* const from) const -{ - if (this == from) - return src; - else - if (referenceFrame()) - return localCoordinatesOf(referenceFrame()->coordinatesOfFrom(src, from)); - else - return localCoordinatesOf(from->inverseCoordinatesOf(src)); -} - -/*! Returns the \p in coordinates of the point whose position in the Frame coordinate system is \p - src (converts from Frame to \p in). - - coordinatesOfFrom() performs the inverse transformation. */ -Vec Frame::coordinatesOfIn(const Vec& src, const Frame* const in) const -{ - const Frame* fr = this; - Vec res = src; - while ((fr != NULL) && (fr != in)) - { - res = fr->localInverseCoordinatesOf(res); - fr = fr->referenceFrame(); - } - - if (fr != in) - // in was not found in the branch of this, res is now expressed in the world - // coordinate system. Simply convert to in coordinate system. - res = in->coordinatesOf(res); - - return res; -} - -////// float[3] versions - -/*! Same as coordinatesOf(), but with \c float parameters. */ -void Frame::getCoordinatesOf(const float src[3], float res[3]) const -{ - const Vec r = coordinatesOf(Vec(src)); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as inverseCoordinatesOf(), but with \c float parameters. */ -void Frame::getInverseCoordinatesOf(const float src[3], float res[3]) const -{ - const Vec r = inverseCoordinatesOf(Vec(src)); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as localCoordinatesOf(), but with \c float parameters. */ -void Frame::getLocalCoordinatesOf(const float src[3], float res[3]) const -{ - const Vec r = localCoordinatesOf(Vec(src)); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - - /*! Same as localInverseCoordinatesOf(), but with \c float parameters. */ -void Frame::getLocalInverseCoordinatesOf(const float src[3], float res[3]) const -{ - const Vec r = localInverseCoordinatesOf(Vec(src)); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as coordinatesOfIn(), but with \c float parameters. */ -void Frame::getCoordinatesOfIn(const float src[3], float res[3], const Frame* const in) const -{ - const Vec r = coordinatesOfIn(Vec(src), in); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as coordinatesOfFrom(), but with \c float parameters. */ -void Frame::getCoordinatesOfFrom(const float src[3], float res[3], const Frame* const from) const -{ - const Vec r = coordinatesOfFrom(Vec(src), from); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - - -///////////////////////// FRAME TRANSFORMATIONS OF VECTORS ////////////////////////////// - -/*! Returns the Frame transform of a vector \p src defined in the world coordinate system (converts - vectors from world to Frame). - - inverseTransformOf() performs the inverse transformation. coordinatesOf() converts 3D coordinates - instead of 3D vectors (here only the rotational part of the transformation is taken into account). - - See the <a href="../examples/frameTransform.html">frameTransform example</a> for an - illustration. */ -Vec Frame::transformOf(const Vec& src) const -{ - if (referenceFrame()) - return localTransformOf(referenceFrame()->transformOf(src)); - else - return localTransformOf(src); -} - -/*! Returns the world transform of the vector whose coordinates in the Frame coordinate - system is \p src (converts vectors from Frame to world). - - transformOf() performs the inverse transformation. Use inverseCoordinatesOf() to transform 3D - coordinates instead of 3D vectors. */ -Vec Frame::inverseTransformOf(const Vec& src) const -{ - const Frame* fr = this; - Vec res = src; - while (fr != NULL) - { - res = fr->localInverseTransformOf(res); - fr = fr->referenceFrame(); - } - return res; -} - -/*! Returns the Frame transform of a vector \p src defined in the referenceFrame() coordinate system - (converts vectors from referenceFrame() to Frame). - - localInverseTransformOf() performs the inverse transformation. See also localCoordinatesOf(). */ -Vec Frame::localTransformOf(const Vec& src) const -{ - return rotation().inverseRotate(src); -} - -/*! Returns the referenceFrame() transform of a vector \p src defined in the Frame coordinate - system (converts vectors from Frame to referenceFrame()). - - localTransformOf() performs the inverse transformation. See also localInverseCoordinatesOf(). */ -Vec Frame::localInverseTransformOf(const Vec& src) const -{ - return rotation().rotate(src); -} - -/*! Returns the Frame transform of the vector whose coordinates in the \p from coordinate system is \p - src (converts vectors from \p from to Frame). - - transformOfIn() performs the inverse transformation. */ -Vec Frame::transformOfFrom(const Vec& src, const Frame* const from) const -{ - if (this == from) - return src; - else - if (referenceFrame()) - return localTransformOf(referenceFrame()->transformOfFrom(src, from)); - else - return localTransformOf(from->inverseTransformOf(src)); -} - -/*! Returns the \p in transform of the vector whose coordinates in the Frame coordinate system is \p - src (converts vectors from Frame to \p in). - - transformOfFrom() performs the inverse transformation. */ -Vec Frame::transformOfIn(const Vec& src, const Frame* const in) const -{ - const Frame* fr = this; - Vec res = src; - while ((fr != NULL) && (fr != in)) - { - res = fr->localInverseTransformOf(res); - fr = fr->referenceFrame(); - } - - if (fr != in) - // in was not found in the branch of this, res is now expressed in the world - // coordinate system. Simply convert to in coordinate system. - res = in->transformOf(res); - - return res; -} - -///////////////// float[3] versions ////////////////////// - -/*! Same as transformOf(), but with \c float parameters. */ -void Frame::getTransformOf(const float src[3], float res[3]) const -{ - Vec r = transformOf(Vec(src)); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as inverseTransformOf(), but with \c float parameters. */ -void Frame::getInverseTransformOf(const float src[3], float res[3]) const -{ - Vec r = inverseTransformOf(Vec(src)); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as localTransformOf(), but with \c float parameters. */ -void Frame::getLocalTransformOf(const float src[3], float res[3]) const -{ - Vec r = localTransformOf(Vec(src)); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as localInverseTransformOf(), but with \c float parameters. */ -void Frame::getLocalInverseTransformOf(const float src[3], float res[3]) const -{ - Vec r = localInverseTransformOf(Vec(src)); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as transformOfIn(), but with \c float parameters. */ -void Frame::getTransformOfIn(const float src[3], float res[3], const Frame* const in) const -{ - Vec r = transformOfIn(Vec(src), in); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -/*! Same as transformOfFrom(), but with \c float parameters. */ -void Frame::getTransformOfFrom(const float src[3], float res[3], const Frame* const from) const -{ - Vec r = transformOfFrom(Vec(src), from); - for (int i=0; i<3 ; ++i) - res[i] = r[i]; -} - -///////////////////////////////// ALIGN ///////////////////////////////// - -/*! Aligns the Frame with \p frame, so that two of their axis are parallel. - -If one of the X, Y and Z axis of the Frame is almost parallel to any of the X, Y, or Z axis of \p -frame, the Frame is rotated so that these two axis actually become parallel. - -If, after this first rotation, two other axis are also almost parallel, a second alignment is -performed. The two frames then have identical orientations, up to 90 degrees rotations. - -\p threshold measures how close two axis must be to be considered parallel. It is compared with the -absolute values of the dot product of the normalized axis. - -When \p move is set to \c true, the Frame position() is also affected by the alignment. The new -Frame position() is such that the \p frame position (computed with coordinatesOf(), in the Frame -coordinates system) does not change. - -\p frame may be \c NULL and then represents the world coordinate system (same convention than for -the referenceFrame()). - -The rotation (and translation when \p move is \c true) applied to the Frame are filtered by the -possible constraint(). */ -void Frame::alignWithFrame(const Frame* const frame, bool move, float threshold) -{ - Vec directions[2][3]; - for (int d=0; d<3; ++d) - { - Vec dir((d==0)? 1.0 : 0.0, (d==1)? 1.0 : 0.0, (d==2)? 1.0 : 0.0); - if (frame) - directions[0][d] = frame->inverseTransformOf(dir); - else - directions[0][d] = dir; - directions[1][d] = inverseTransformOf(dir); - } - - float maxProj = 0.0f; - float proj; - unsigned short index[2]; - index[0] = index[1] = 0; - for (int i=0; i<3; ++i) - for (int j=0; j<3; ++j) - if ( (proj=fabs(directions[0][i]*directions[1][j])) >= maxProj ) - { - index[0] = i; - index[1] = j; - maxProj = proj; - } - - Frame old; - old=*this; - - float coef = directions[0][index[0]] * directions[1][index[1]]; - if (fabs(coef) >= threshold) - { - const Vec axis = cross(directions[0][index[0]], directions[1][index[1]]); - float angle = asin(axis.norm()); - if (coef >= 0.0) - angle = -angle; - // setOrientation(Quaternion(axis, angle) * orientation()); - rotate(rotation().inverse() * Quaternion(axis, angle) * orientation()); - - // Try to align an other axis direction - unsigned short d = (index[1]+1) % 3; - Vec dir((d==0)? 1.0 : 0.0, (d==1)? 1.0 : 0.0, (d==2)? 1.0 : 0.0); - dir = inverseTransformOf(dir); - - float max = 0.0f; - for (int i=0; i<3; ++i) - { - float proj = fabs(directions[0][i]*dir); - if (proj > max) - { - index[0] = i; - max = proj; - } - } - - if (max >= threshold) - { - const Vec axis = cross(directions[0][index[0]], dir); - float angle = asin(axis.norm()); - if (directions[0][index[0]] * dir >= 0.0) - angle = -angle; - // setOrientation(Quaternion(axis, angle) * orientation()); - rotate(rotation().inverse() * Quaternion(axis, angle) * orientation()); - } - } - - if (move) - { - Vec center; - if (frame) - center = frame->position(); - - // setPosition(center - orientation().rotate(old.coordinatesOf(center))); - translate(center - orientation().rotate(old.coordinatesOf(center)) - translation()); - } -} - -/*! Translates the Frame so that its position() lies on the line defined by \p origin and \p - direction (defined in the world coordinate system). - -Simply uses an orthogonal projection. \p direction does not need to be normalized. */ -void Frame::projectOnLine(const Vec& origin, const Vec& direction) -{ - // If you are trying to find a bug here, because of memory problems, you waste your time. - // This is a bug in the gcc 3.3 compiler. Compile the library in debug mode and test. - // Uncommenting this line also seems to solve the problem. Horrible. - // cout << "position = " << position() << endl; - // If you found a problem or are using a different compiler, please let me know. - const Vec shift = origin - position(); - Vec proj = shift; - proj.projectOnAxis(direction); - translate(shift-proj); -} diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.h deleted file mode 100644 index 30297499285..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_frame.h +++ /dev/null @@ -1,408 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#ifndef QGLVIEWER_FRAME_H -#define QGLVIEWER_FRAME_H - -#include "AppGLWidget_constraint.h" -// #include "GL/gl.h" is now included in config.h for ease of configuration - -//namespace qglviewer { - /*! \brief The Frame class represents a coordinate system, defined by a position and an - orientation. \class Frame frame.h QGLViewer/frame.h - - A Frame is a 3D coordinate system, represented by a position() and an orientation(). The order of - these transformations is important: the Frame is first translated \e and \e then rotated around - the new translated origin. - - A Frame is useful to define the position and orientation of a 3D rigid object, using its matrix() - method, as shown below: - \code - // Builds a Frame at position (0.5,0,0) and oriented such that its Y axis is along the (1,1,1) - // direction. One could also have used setPosition() and setOrientation(). - Frame fr(Vec(0.5,0,0), Quaternion(Vec(0,1,0), Vec(1,1,1))); - glPushMatrix(); - glMultMatrixd(fr.matrix()); - // Draw your object here, in the local fr coordinate system. - glPopMatrix(); - \endcode - - Many functions are provided to transform a 3D point from one coordinate system (Frame) to an - other: see coordinatesOf(), inverseCoordinatesOf(), coordinatesOfIn(), coordinatesOfFrom()... - - You may also want to transform a 3D vector (such as a normal), which corresponds to applying only - the rotational part of the frame transformation: see transformOf() and inverseTransformOf(). See - the <a href="../examples/frameTransform.html">frameTransform example</a> for an illustration. - - The translation() and the rotation() that are encapsulated in a Frame can also be used to - represent a \e rigid \e transformation of space. Such a transformation can also be interpreted as - a change of coordinate system, and the coordinate system conversion functions actually allow you - to use a Frame as a rigid transformation. Use inverseCoordinatesOf() (resp. coordinatesOf()) to - apply the transformation (resp. its inverse). Note the inversion. - - <h3>Hierarchy of Frames</h3> - - The position and the orientation of a Frame are actually defined with respect to a - referenceFrame(). The default referenceFrame() is the world coordinate system (represented by a \c - NULL referenceFrame()). If you setReferenceFrame() to a different Frame, you must then - differentiate: - - \arg the \e local translation() and rotation(), defined with respect to the referenceFrame(), - - \arg the \e global position() and orientation(), always defined with respect to the world - coordinate system. - - A Frame is actually defined by its translation() with respect to its referenceFrame(), and then by - a rotation() of the coordinate system around the new translated origin. - - This terminology for \e local (translation() and rotation()) and \e global (position() and - orientation()) definitions is used in all the methods' names and should be sufficient to prevent - ambiguities. These notions are obviously identical when the referenceFrame() is \c NULL, i.e. when - the Frame is defined in the world coordinate system (the one you are in at the beginning of the - QGLViewer::draw() method, see the <a href="../introduction.html">introduction page</a>). - - Frames can hence easily be organized in a tree hierarchy, which root is the world coordinate - system. A loop in the hierarchy would result in an inconsistent (multiple) Frame definition. - settingAsReferenceFrameWillCreateALoop() checks this and prevents setReferenceFrame() from - creating such a loop. - - This frame hierarchy is used in methods like coordinatesOfIn(), coordinatesOfFrom()... which allow - coordinates (or vector) conversions from a Frame to any other one (including the world coordinate - system). - - However, one must note that this hierarchical representation is internal to the Frame classes. - When the Frames represent OpenGL coordinates system, one should map this hierarchical - representation to the OpenGL GL_MODELVIEW matrix stack. See the matrix() documentation for - details. - - <h3>Constraints</h3> - - An interesting feature of Frames is that their displacements can be constrained. When a Constraint - is attached to a Frame, it filters the input of translate() and rotate(), and only the resulting - filtered motion is applied to the Frame. The default constraint() is \c NULL resulting in no - filtering. Use setConstraint() to attach a Constraint to a frame. - - Constraints are especially usefull for the ManipulatedFrame instances, in order to forbid some - mouse motions. See the <a href="../examples/constrainedFrame.html">constrainedFrame</a>, <a - href="../examples/constrainedCamera.html">constrainedCamera</a> and <a - href="../examples/luxo.html">luxo</a> examples for an illustration. - - Classical constraints are provided for convenience (see LocalConstraint, WorldConstraint and - CameraConstraint) and new constraints can very easily be implemented. - - <h3>Derived classes</h3> - - The ManipulatedFrame class inherits Frame and implements a mouse motion convertion, so that a - Frame (and hence an object) can be manipulated in the scene with the mouse. - - \nosubgrouping */ - class Frame - { - - public: - Frame(); - - /*! Virtual destructor. Empty. */ - virtual ~Frame() {}; - - Frame(const Frame& frame); - Frame& operator=(const Frame& frame); - - /*! This signal is emitted whenever the position() or the orientation() of the Frame is modified. - - Connect this signal to any object that must be notified: - \code - QObject::connect(myFrame, SIGNAL(modified()), myObject, SLOT(update())); - \endcode - Use the QGLViewer::QGLViewerPool() to connect the signal to all the viewers. - - \note If your Frame is part of a Frame hierarchy (see referenceFrame()), a modification of one - of the parents of this Frame will \e not emit this signal. Use code like this to change this - behavior (you can do this recursively for all the referenceFrame() until the \c NULL world root - frame is encountered): - \code - // Emits the Frame modified() signal when its referenceFrame() is modified(). - connect(myFrame->referenceFrame(), SIGNAL(modified()), myFrame, SIGNAL(modified())); - \endcode - - \attention Connecting this signal to a QGLWidget::updateGL() slot (or a method that calls it) - will prevent you from modifying the Frame \e inside your QGLViewer::draw() method as it would - result in an infinite loop. However, QGLViewer::draw() should not modify the scene. - - \note For efficiency reasons, this signal is emitted even if the Frame is not actually modified, for - instance with translate(Vec(0,0,0)) or setPosition(position()). */ - void modified(); - - /*! This signal is emitted when the Frame is interpolated by a KeyFrameInterpolator. - - See the KeyFrameInterpolator documentation for details. - - If a KeyFrameInterpolator is used to successively interpolate several Frames in your scene, - connect the KeyFrameInterpolator::interpolated() signal instead (identical, but independent of - the interpolated Frame). */ - void interpolated(); - - public: - /*! @name World coordinates position and orientation */ - //@{ - Frame(const Vec& position, const Quaternion& orientation); - - void setPosition(const Vec& position); - void setPosition(float x, float y, float z); - void setPositionWithConstraint(Vec& position); - - void setOrientation(const Quaternion& orientation); - void setOrientation(double q0, double q1, double q2, double q3); - void setOrientationWithConstraint(Quaternion& orientation); - - void setPositionAndOrientation(const Vec& position, const Quaternion& orientation); - void setPositionAndOrientationWithConstraint(Vec& position, Quaternion& orientation); - - /*! Returns the position of the Frame, defined in the world coordinate system. See also - orientation(), setPosition() and translation(). */ - Vec position() const { return inverseCoordinatesOf(Vec(0.0,0.0,0.0)); }; - Quaternion orientation() const; - - void getPosition(float& x, float& y, float& z) const; - void getOrientation(double& q0, double& q1, double& q2, double& q3) const; - //@} - - - public: - /*! @name Local translation and rotation w/r reference Frame */ - //@{ - /*! Sets the translation() of the frame, locally defined with respect to the referenceFrame(). - Emits the modified() signal. - - Use setPosition() to define the world coordinates position(). Use - setTranslationWithConstraint() to take into account the potential constraint() of the Frame. */ - void setTranslation(const Vec& translation) { t_ = translation; }; - void setTranslation(float x, float y, float z); - void setTranslationWithConstraint(Vec& translation); - - /*! Set the current rotation Quaternion. See rotation() and the different Quaternion - constructors. Emits the modified() signal. See also setTranslation() and - setRotationWithConstraint(). */ - - /*! Sets the rotation() of the Frame, locally defined with respect to the referenceFrame(). - Emits the modified() signal. - - Use setOrientation() to define the world coordinates orientation(). The potential - constraint() of the Frame is not taken into account, use setRotationWithConstraint() - instead. */ - void setRotation(const Quaternion& rotation) { q_ = rotation; }; - void setRotation(double q0, double q1, double q2, double q3); - void setRotationWithConstraint(Quaternion& rotation); - - void setTranslationAndRotation(const Vec& translation, const Quaternion& rotation); - void setTranslationAndRotationWithConstraint(Vec& translation, Quaternion& rotation); - - /*! Returns the Frame translation, defined with respect to the referenceFrame(). - - Use position() to get the result in the world coordinates. These two values are identical - when the referenceFrame() is \c NULL (default). - - See also setTranslation() and setTranslationWithConstraint(). */ - Vec translation() const { return t_; }; - /*! Returns the Frame rotation, defined with respect to the referenceFrame(). - - Use orientation() to get the result in the world coordinates. These two values are identical - when the referenceFrame() is \c NULL (default). - - See also setRotation() and setRotationWithConstraint(). */ - - /*! Returns the current Quaternion orientation. See setRotation(). */ - Quaternion rotation() const { return q_; }; - - void getTranslation(float& x, float& y, float& z) const; - void getRotation(double& q0, double& q1, double& q2, double& q3) const; - //@} - - public: - /*! @name Frame hierarchy */ - //@{ - /*! Returns the reference Frame, in which coordinates system the Frame is defined. - - The translation() and rotation() of the Frame are defined with respect to the referenceFrame() - coordinate system. A \c NULL referenceFrame() (default value) means that the Frame is defined in - the world coordinate system. - - Use position() and orientation() to recursively convert values along the referenceFrame() chain - and to get values expressed in the world coordinate system. The values match when the - referenceFrame() is \c NULL. - - Use setReferenceFrame() to set this value and create a Frame hierarchy. Convenient functions - allow you to convert 3D coordinates from one Frame to an other: see coordinatesOf(), - localCoordinatesOf(), coordinatesOfIn() and their inverse functions. - - Vectors can also be converted using transformOf(), transformOfIn, localTransformOf() and their - inverse functions. */ - const Frame* referenceFrame() const { return referenceFrame_; }; - void setReferenceFrame(const Frame* const refFrame); - bool settingAsReferenceFrameWillCreateALoop(const Frame* const frame); - //@} - - - /*! @name Frame modification */ - //@{ - void translate(Vec& t); - void translate(const Vec& t); - // Some compilers complain about "overloading cannot distinguish from previous declaration" - // Simply comment out the following method and its associated implementation - void translate(float x, float y, float z); - void translate(float& x, float& y, float& z); - - void rotate(Quaternion& q); - void rotate(const Quaternion& q); - // Some compilers complain about "overloading cannot distinguish from previous declaration" - // Simply comment out the following method and its associated implementation - void rotate(double q0, double q1, double q2, double q3); - void rotate(double& q0, double& q1, double& q2, double& q3); - - void rotateAroundPoint(Quaternion& rotation, const Vec& point); - void rotateAroundPoint(const Quaternion& rotation, const Vec& point); - - void alignWithFrame(const Frame* const frame, bool move=false, float threshold=0.85f); - void projectOnLine(const Vec& origin, const Vec& direction); - //@} - - - /*! @name Coordinate system transformation of 3D coordinates */ - //@{ - Vec coordinatesOf(const Vec& src) const; - Vec inverseCoordinatesOf(const Vec& src) const; - Vec localCoordinatesOf(const Vec& src) const; - Vec localInverseCoordinatesOf(const Vec& src) const; - Vec coordinatesOfIn(const Vec& src, const Frame* const in) const; - Vec coordinatesOfFrom(const Vec& src, const Frame* const from) const; - - void getCoordinatesOf(const float src[3], float res[3]) const; - void getInverseCoordinatesOf(const float src[3], float res[3]) const; - void getLocalCoordinatesOf(const float src[3], float res[3]) const; - void getLocalInverseCoordinatesOf(const float src[3], float res[3]) const; - void getCoordinatesOfIn(const float src[3], float res[3], const Frame* const in) const; - void getCoordinatesOfFrom(const float src[3], float res[3], const Frame* const from) const; - //@} - - /*! @name Coordinate system transformation of vectors */ - // A frame is as a new coordinate system, defined with respect to a reference frame (the world - // coordinate system by default, see the "Composition of frame" section). - - // The transformOf() (resp. inverseTransformOf()) functions transform a 3D vector from (resp. - // to) the world coordinates system. This section defines the 3D vector transformation - // functions. See the Coordinate system transformation of 3D points above for the transformation - // of 3D points. The difference between the two sets of functions is simple: for vectors, only - // the rotational part of the transformations is taken into account, while translation is also - // considered for 3D points. - - // The length of the resulting transformed vector is identical to the one of the source vector - // for all the described functions. - - // When local is prepended to the names of the functions, the functions simply transform from - // (and to) the reference frame. - - // When In (resp. From) is appended to the names, the functions transform from (resp. To) the - // frame that is given as an argument. The frame does not need to be in the same branch or the - // hierarchical tree, and can be \c NULL (the world coordinates system). - - // Combining any of these functions with its inverse (in any order) leads to the identity. - //@{ - Vec transformOf(const Vec& src) const; - Vec inverseTransformOf(const Vec& src) const; - Vec localTransformOf(const Vec& src) const; - Vec localInverseTransformOf(const Vec& src) const; - Vec transformOfIn(const Vec& src, const Frame* const in) const; - Vec transformOfFrom(const Vec& src, const Frame* const from) const; - - void getTransformOf(const float src[3], float res[3]) const; - void getInverseTransformOf(const float src[3], float res[3]) const; - void getLocalTransformOf(const float src[3], float res[3]) const; - void getLocalInverseTransformOf(const float src[3], float res[3]) const; - void getTransformOfIn(const float src[3], float res[3], const Frame* const in) const; - void getTransformOfFrom(const float src[3], float res[3], const Frame* const from) const; - //@} - - - /*! @name Constraint on the displacement */ - //@{ - /*! Returns the current constraint applied to the Frame. - - A \c NULL value (default) means that no Constraint is used to filter Frame translation and - rotation. See the Constraint class documentation for details. - - You may have to use a \c dynamic_cast to convert the result to a Constraint derived class. */ - Constraint* constraint() const { return constraint_; } - /*! Sets the constraint() attached to the Frame. - - A \c NULL value means no constraint. The previous constraint() should be deleted by the calling - method if needed. */ - void setConstraint(Constraint* const constraint) { constraint_ = constraint; } - //@} - - /*! @name Associated matrices */ - //@{ - public: - const GLdouble* matrix() const; - void getMatrix(GLdouble m[4][4]) const; - void getMatrix(GLdouble m[16]) const; - - const GLdouble* worldMatrix() const; - void getWorldMatrix(GLdouble m[4][4]) const; - void getWorldMatrix(GLdouble m[16]) const; - - void setFromMatrix(const GLdouble m[4][4]); - void setFromMatrix(const GLdouble m[16]); - //@} - - /*! @name Inversion of the transformation */ - //@{ - Frame inverse() const; - /*! Returns the inverse() of the Frame world transformation. - - The orientation() of the new Frame is the Quaternion::inverse() of the original orientation. - Its position() is the negated and inverse rotated image of the original position. - - The result Frame has a \c NULL referenceFrame() and a \c NULL constraint(). - - Use inverse() for a local (i.e. with respect to referenceFrame()) transformation inverse. */ - Frame worldInverse() const { return Frame(-(orientation().inverseRotate(position())), orientation().inverse()); } - //@} - - - private: - // P o s i t i o n a n d o r i e n t a t i o n - Vec t_; - Quaternion q_; - - // C o n s t r a i n t s - Constraint* constraint_; - - // F r a m e c o m p o s i t i o n - const Frame* referenceFrame_; - }; - -//} // namespace qglviewer - -#endif // QGLVIEWER_FRAME_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedCameraFrame.cpp b/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedCameraFrame.cpp deleted file mode 100644 index dafd64c4d19..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedCameraFrame.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#include "AppGLWidget_manipulatedCameraFrame.h" -#include "AppGLWidget_camera.h" -//#include "qglviewer.h" - -// #if QT_VERSION >= 0x040000 -// # include <QMouseEvent> -// #endif -// -// using namespace qglviewer; -using namespace std; - -/*! Default constructor. - - flySpeed() is set to 0.0 and flyUpVector() is (0,1,0). The revolveAroundPoint() is set to (0,0,0). - - \attention Created object is removeFromMouseGrabberPool(). */ -ManipulatedCameraFrame::ManipulatedCameraFrame() - : driveSpeed_(0.0), flyUpVector_(0.0, 1.0, 0.0) -{ - setFlySpeed(0.0); - //removeFromMouseGrabberPool(); - - //connect(&flyTimer_, SIGNAL(timeout()), SLOT(flyUpdate())); -} - -/*! Equal operator. Calls ManipulatedFrame::operator=() and then copy attributes. */ -ManipulatedCameraFrame& ManipulatedCameraFrame::operator=(const ManipulatedCameraFrame& mcf) -{ - ManipulatedFrame::operator=(mcf); - - setFlySpeed(mcf.flySpeed()); - setFlyUpVector(mcf.flyUpVector()); - - return *this; -} - -/*! Copy constructor. Performs a deep copy of all members using operator=(). */ -ManipulatedCameraFrame::ManipulatedCameraFrame(const ManipulatedCameraFrame& mcf) - : ManipulatedFrame(mcf) -{ - //removeFromMouseGrabberPool(); - (*this)=(mcf); -} - - -//////////////////////////////////////////////////////////////////////////////// - -/*! Returns a Quaternion that is a rotation around current camera Y, proportionnal to the horizontal mouse position. */ -Quaternion ManipulatedCameraFrame::turnQuaternion(int x, const AppGLWidget_Camera* const camera) -{ - return Quaternion(Vec(0.0, 1.0, 0.0), rotationSensitivity()*(prevPos_.x()-x)/camera->screenWidth()); -} - -/*! Returns a Quaternion that is the composition of two rotations, inferred from the - mouse pitch (X axis) and yaw (flyUpVector() axis). */ -Quaternion ManipulatedCameraFrame::pitchYawQuaternion(int x, int y, const AppGLWidget_Camera* const camera) -{ - const Quaternion rotX(Vec(1.0, 0.0, 0.0), rotationSensitivity()*(prevPos_.y()-y)/camera->screenHeight()); - const Quaternion rotY(transformOf(flyUpVector()), rotationSensitivity()*(prevPos_.x()-x)/camera->screenWidth()); - return rotY * rotX; -} diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedCameraFrame.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedCameraFrame.h deleted file mode 100644 index 334fcfeade5..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedCameraFrame.h +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#ifndef QGLVIEWER_MANIPULATED_CAMERA_FRAME_H -#define QGLVIEWER_MANIPULATED_CAMERA_FRAME_H - -#include "AppGLWidget_manipulatedFrame.h" - -//namespace qglviewer { - /*! \brief The ManipulatedCameraFrame class represents a ManipulatedFrame with Camera specific mouse bindings. - \class ManipulatedCameraFrame manipulatedCameraFrame.h QGLViewer/manipulatedCameraFrame.h - - A ManipulatedCameraFrame is a specialization of a ManipulatedFrame, designed to be set as the - Camera::frame(). Mouse motions are basically interpreted in a negated way: when the mouse goes to - the right, the ManipulatedFrame translation goes to the right, while the ManipulatedCameraFrame - has to go to the \e left, so that the \e scene seems to move to the right. - - A ManipulatedCameraFrame rotates around its revolveAroundPoint(), which corresponds to the - associated Camera::revolveAroundPoint(). - - A ManipulatedCameraFrame can also "fly" in the scene. It basically moves forward, and turns - according to the mouse motion. See flySpeed(), flyUpVector() and the QGLViewer::MOVE_FORWARD and - QGLViewer::MOVE_BACKWARD QGLViewer::MouseAction. - - See the <a href="../mouse.html">mouse page</a> for a description of the possible actions that can - be performed using the mouse and their bindings. - \nosubgrouping */ - class ManipulatedCameraFrame : public ManipulatedFrame - { -#ifndef DOXYGEN - friend class AppGLWidget_Camera; - //friend class ::QGLViewer; -#endif - - //Q_OBJECT - - public: - ManipulatedCameraFrame(); - /*! Virtual destructor. Empty. */ - virtual ~ManipulatedCameraFrame() {}; - - ManipulatedCameraFrame(const ManipulatedCameraFrame& mcf); - ManipulatedCameraFrame& operator=(const ManipulatedCameraFrame& mcf); - - /*! @name Revolve around point */ - //@{ - public: - /*! Returns the point the ManipulatedCameraFrame revolves around when rotated. - - It is defined in the world coordinate system. Default value is (0,0,0). - - When the ManipulatedCameraFrame is associated to a Camera, Camera::revolveAroundPoint() also - returns this value. This point can interactively be changed using the mouse (see - QGLViewer::RAP_FROM_PIXEL and QGLViewer::RAP_IS_CENTER in the <a href="../mouse.html">mouse - page</a>). */ - Vec revolveAroundPoint() const { return revolveAroundPoint_; } - /*! Sets the revolveAroundPoint(), defined in the world coordinate system. */ - void setRevolveAroundPoint(const Vec& revolveAroundPoint) { revolveAroundPoint_ = revolveAroundPoint; } - //@} - - /*! @name Fly parameters */ - //@{ - public: //slots: - /*! Sets the flySpeed(), defined in OpenGL units. - - Default value is 0.0, but it is modified according to the QGLViewer::sceneRadius() when the - ManipulatedCameraFrame is set as the Camera::frame(). */ - void setFlySpeed(float speed) { flySpeed_ = speed; }; - - /*! Sets the flyUpVector(), defined in the world coordinate system. - - Default value is (0,1,0), but it is updated by the Camera when set as its Camera::frame(). Use - Camera::setUpVector() instead in that case. */ - void setFlyUpVector(const Vec& up) { flyUpVector_ = up; }; - - public: - /*! Returns the fly speed, expressed in OpenGL units. - - It corresponds to the incremental displacement that is periodically applied to the - ManipulatedCameraFrame position when a QGLViewer::MOVE_FORWARD or QGLViewer::MOVE_BACKWARD - QGLViewer::MouseAction is proceeded. - - \attention When the ManipulatedCameraFrame is set as the Camera::frame(), this value is set - according to the QGLViewer::sceneRadius() by QGLViewer::setSceneRadius(). */ - float flySpeed() const { return flySpeed_; }; - - /*! Returns the up vector used in fly mode, expressed in the world coordinate system. - - Fly mode corresponds to the QGLViewer::MOVE_FORWARD and QGLViewer::MOVE_BACKWARD - QGLViewer::MouseAction bindings. In these modes, horizontal displacements of the mouse rotate - the ManipulatedCameraFrame around this vector. Vertical displacements rotate always around the - Camera \c X axis. - - Default value is (0,1,0), but it is updated by the Camera when set as its Camera::frame(). - Camera::setOrientation() and Camera::setUpVector()) modify this value and should be used - instead. */ - Vec flyUpVector() const { return flyUpVector_; }; - //@} - - /*! @name Mouse event handlers */ - //@{ - // protected: - // virtual void mouseReleaseEvent(QMouseEvent* const event, Camera* const camera); - // virtual void mouseMoveEvent (QMouseEvent* const event, Camera* const camera); - // virtual void wheelEvent (QWheelEvent* const event, Camera* const camera); - // //@} - - /*! @name Spinning */ - //@{ - // protected slots: - // virtual void spin(); - //@} - - /*! @name XML representation */ - //@{ - // public: - // virtual QDomElement domElement(const QString& name, QDomDocument& document) const; - // public slots: - // virtual void initFromDOMElement(const QDomElement& element); - // //@} - -// #ifndef DOXYGEN -// protected: -// virtual void startAction(int ma, bool withConstraint=true); // int is really a QGLViewer::MouseAction -// #endif - - private: //slots: - //virtual void flyUpdate(); - - private: - void updateFlyUpVector(); - Quaternion turnQuaternion(int x, const AppGLWidget_Camera* const camera); - Quaternion pitchYawQuaternion(int x, int y, const AppGLWidget_Camera* const camera); - - private: - // Fly mode data - float flySpeed_; - float driveSpeed_; - Vec flyUpVector_; - //QTimer flyTimer_; - - Vec revolveAroundPoint_; - }; - -//} // namespace qglviewer - -#endif // QGLVIEWER_MANIPULATED_CAMERA_FRAME_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedFrame.cpp b/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedFrame.cpp deleted file mode 100644 index 3ec5e83bf50..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedFrame.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#include "AppGLWidget_manipulatedFrame.h" -//#include "qglviewer.h" -#include "AppGLWidget_camera.h" - -//using namespace qglviewer; -using namespace std; - -/*! Default constructor. - - The translation is set to (0,0,0), with an identity rotation (0,0,0,1) (see Frame constructor - for details). - - The different sensitivities are set to their default values (see rotationSensitivity(), - translationSensitivity(), spinningSensitivity() and wheelSensitivity()). */ -ManipulatedFrame::ManipulatedFrame() -{ - // #CONNECTION# initFromDOMElement and accessor docs - setRotationSensitivity(1.0f); - setTranslationSensitivity(1.0f); - setSpinningSensitivity(0.3f); - setWheelSensitivity(1.0f); - - isSpinning_ = false; - previousConstraint_ = false; - - //connect(&spinningTimer_, SIGNAL(timeout()), SLOT(spinUpdate())); -} - -/*! Equal operator. Calls Frame::operator=() and then copy attributes. */ -ManipulatedFrame& ManipulatedFrame::operator=(const ManipulatedFrame& mf) -{ - Frame::operator=(mf); - - setRotationSensitivity(mf.rotationSensitivity()); - setTranslationSensitivity(mf.translationSensitivity()); - setSpinningSensitivity(mf.spinningSensitivity()); - setWheelSensitivity(mf.wheelSensitivity()); - - mouseSpeed_ = 0.0; - dirIsFixed_ = false; - keepsGrabbingMouse_ = false; - - return *this; -} - -/*! Copy constructor. Performs a deep copy of all attributes using operator=(). */ -ManipulatedFrame::ManipulatedFrame(const ManipulatedFrame& mf) - : Frame(mf) -{ - (*this)=mf; -} - - - -//////////////////////////////////////////////////////////////////////////////// - -/*! Returns "pseudo-distance" from (x,y) to ball of radius size. -\arg for a point inside the ball, it is proportional to the euclidean distance to the ball -\arg for a point outside the ball, it is proportional to the inverse of this distance (tends to -zero) on the ball, the function is continuous. */ -static float projectOnBall(float x, float y) -{ - // If you change the size value, change angle computation in deformedBallQuaternion(). - const float size = 1.0f; - const float size2 = size*size; - const float size_limit = size2*0.5; - - const float d = x*x + y*y; - return d < size_limit ? sqrt(size2 - d) : size_limit/sqrt(d); -} - -#ifndef DOXYGEN -/*! Returns a quaternion computed according to the mouse motion. Mouse positions are projected on a -deformed ball, centered on (\p cx,\p cy). */ -Quaternion ManipulatedFrame::deformedBallQuaternion(int x, int y, float cx, float cy, const AppGLWidget_Camera* const camera) -{ - // Points on the deformed ball - float px = rotationSensitivity() * (prevPos_.x() - cx) / camera->screenWidth(); - float py = rotationSensitivity() * (cy - prevPos_.y()) / camera->screenHeight(); - float dx = rotationSensitivity() * (x - cx) / camera->screenWidth(); - float dy = rotationSensitivity() * (cy - y) / camera->screenHeight(); - - const Vec p1(px, py, projectOnBall(px, py)); - const Vec p2(dx, dy, projectOnBall(dx, dy)); - // Approximation of rotation angle - // Should be divided by the projectOnBall size, but it is 1.0 - const Vec axis = cross(p2,p1); - const float angle = 2.0 * asin(sqrt(axis.squaredNorm() / p1.squaredNorm() / p2.squaredNorm())); - return Quaternion(axis, angle); -} -#endif // DOXYGEN diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedFrame.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedFrame.h deleted file mode 100644 index e57dd9fc756..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_manipulatedFrame.h +++ /dev/null @@ -1,256 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#ifndef QGLVIEWER_MANIPULATED_FRAME_H -#define QGLVIEWER_MANIPULATED_FRAME_H - -#include "AppGLWidget_frame.h" - -//namespace qglviewer { - /*! \brief A ManipulatedFrame is a Frame that can be rotated and translated using the mouse. - \class ManipulatedFrame manipulatedFrame.h QGLViewer/manipulatedFrame.h - - It converts the mouse motion into a translation and an orientation updates. A ManipulatedFrame is - used to move an object in the scene. Combined with object selection, its MouseGrabber properties - and a dynamic update of the scene, the ManipulatedFrame introduces a great reactivity in your - applications. - - A ManipulatedFrame is attached to a QGLViewer using QGLViewer::setManipulatedFrame(): - \code - init() { setManipulatedFrame( new ManipulatedFrame() ); } - - draw() - { - glPushMatrix(); - glMultMatrixd(manipulatedFrame()->matrix()); - // draw the manipulated object here - glPopMatrix(); - } - \endcode - See the <a href="../examples/manipulatedFrame.html">manipulatedFrame example</a> for a complete - application. - - Mouse events are normally sent to the QGLViewer::camera(). You have to press the QGLViewer::FRAME - state key (default is \c Control) to move the QGLViewer::manipulatedFrame() instead. See the <a - href="../mouse.html">mouse page</a> for a description of mouse button bindings. - - <h3>Inherited functionalities</h3> - - A ManipulatedFrame is an overloaded instance of a Frame. The powerful coordinate system - transformation functions (Frame::coordinatesOf(), Frame::transformOf(), ...) can hence be applied - to a ManipulatedFrame. - - A ManipulatedFrame is also a MouseGrabber. If the mouse cursor gets within a distance of 10 pixels - from the projected position of the ManipulatedFrame, the ManipulatedFrame becomes the new - QGLViewer::mouseGrabber(). It can then be manipulated directly, without any specific state key, - object selection or GUI intervention. This is very convenient to directly move some objects in the - scene (typically a light). See the <a href="../examples/mouseGrabber.html">mouseGrabber - example</a> as an illustration. Note that QWidget::setMouseTracking() needs to be enabled in order - to use this feature (see the MouseGrabber documentation). - - <h3>Advanced functionalities</h3> - - A QGLViewer can handle at most one ManipulatedFrame at a time. If you want to move several objects - in the scene, you simply have to keep a list of the different ManipulatedFrames, and to activate - the right one (using QGLViewer::setManipulatedFrame()) when needed. This can for instance be done - according to an object selection: see the <a href="../examples/luxo.html">luxo example</a> for an - illustration. - - When the ManipulatedFrame is being manipulated using the mouse (mouse pressed and not yet - released), isManipulated() returns \c true. This might be used to trigger a specific action or - display (as is done with QGLViewer::fastDraw()). - - The ManipulatedFrame also emits a manipulated() signal each time its state is modified by the - mouse. This signal is automatically connected to the QGLViewer::updateGL() slot when the - ManipulatedFrame is attached to a viewer using QGLViewer::setManipulatedFrame(). - - You can make the ManipulatedFrame spin() if you release the rotation mouse button while moving the - mouse fast enough (see spinningSensitivity()). See also translationSensitivity() and - rotationSensitivity() for sensitivity tuning. \nosubgrouping */ - class ManipulatedFrame : public Frame - { - - public: - ManipulatedFrame(); - /*! Virtual destructor. Empty. */ - virtual ~ManipulatedFrame() {}; - - ManipulatedFrame(const ManipulatedFrame& mf); - ManipulatedFrame& operator=(const ManipulatedFrame& mf); - - /*! This signal is emitted when ever the ManipulatedFrame is manipulated (i.e. rotated or - translated) using the mouse. Connect this signal to any object that should be notified. - - Note that this signal is automatically connected to the QGLViewer::updateGL() slot, when the - ManipulatedFrame is attached to a viewer using QGLViewer::setManipulatedFrame(), which is - probably all you need. - - Use the QGLViewer::QGLViewerPool() if you need to connect this signal to all the viewers. - - See also the spun(), modified(), interpolated() and KeyFrameInterpolator::interpolated() - signals' documentations. */ - void manipulated(); - - /*! This signal is emitted when the ManipulatedFrame isSpinning(). - - Note that for the QGLViewer::manipulatedFrame(), this signal is automatically connected to the - QGLViewer::updateGL() slot. - - Connect this signal to any object that should be notified. Use the QGLViewer::QGLViewerPool() if - you need to connect this signal to all the viewers. - - See also the manipulated(), modified(), interpolated() and KeyFrameInterpolator::interpolated() - signals' documentations. */ - void spun(); - - /*! @name Manipulation sensitivity */ - //@{ - public: - /*! Defines the rotationSensitivity(). */ - void setRotationSensitivity(float sensitivity) { rotSensitivity_ = sensitivity; }; - /*! Defines the translationSensitivity(). */ - void setTranslationSensitivity(float sensitivity) { transSensitivity_ = sensitivity; }; - /*! Defines the spinningSensitivity(), in pixels per milliseconds. */ - void setSpinningSensitivity(float sensitivity) { spinningSensitivity_ = sensitivity; }; - /*! Defines the wheelSensitivity(). */ - void setWheelSensitivity(float sensitivity) { wheelSensitivity_ = sensitivity; }; - public: - /*! Returns the influence of a mouse displacement on the ManipulatedFrame rotation. - - Default value is 1.0. With an identical mouse displacement, a higher value will generate a - larger rotation (and inversely for lower values). A 0.0 value will forbid ManipulatedFrame mouse - rotation (see also constraint()). - - See also setRotationSensitivity(), translationSensitivity(), spinningSensitivity() and - wheelSensitivity(). */ - float rotationSensitivity() const { return rotSensitivity_; }; - /*! Returns the influence of a mouse displacement on the ManipulatedFrame translation. - - Default value is 1.0. You should not have to modify this value, since with 1.0 the - ManipulatedFrame precisely stays under the mouse cursor. - - With an identical mouse displacement, a higher value will generate a larger translation (and - inversely for lower values). A 0.0 value will forbid ManipulatedFrame mouse translation (see - also constraint()). - - \note When the ManipulatedFrame is used to move a \e Camera (see the ManipulatedCameraFrame - class documentation), after zooming on a small region of your scene, the camera may translate - too fast. For a camera, it is the Camera::revolveAroundPoint() that exactly matches the mouse - displacement. Hence, instead of changing the translationSensitivity(), solve the problem by - (temporarily) setting the Camera::revolveAroundPoint() to a point on the zoomed region (see the - QGLViewer::RAP_FROM_PIXEL mouse binding in the <a href="../mouse.html">mouse page</a>). - - See also setTranslationSensitivity(), rotationSensitivity(), spinningSensitivity() and - wheelSensitivity(). */ - float translationSensitivity() const { return transSensitivity_; }; - /*! Returns the minimum mouse speed required (at button release) to make the ManipulatedFrame - spin(). - - See spin(), spinningQuaternion() and startSpinning() for details. - - Mouse speed is expressed in pixels per milliseconds. Default value is 0.3 (300 pixels per - second). Use setSpinningSensitivity() to tune this value. A higher value will make spinning more - difficult (a value of 100.0 forbids spinning in practice). - - See also setSpinningSensitivity(), translationSensitivity(), rotationSensitivity() and - wheelSensitivity(). */ - float spinningSensitivity() const { return spinningSensitivity_; }; - /*! Returns the mouse wheel sensitivity. - - Default value is 1.0. A higher value will make the wheel action more efficient (usually meaning - a faster zoom). Use a negative value to invert the zoom in and out directions. - - See also setWheelSensitivity(), translationSensitivity(), rotationSensitivity() and - spinningSensitivity(). */ - float wheelSensitivity() const { return wheelSensitivity_; }; - //@} - - - /*! @name Spinning */ - //@{ - public: - /*! Returns \c true when the ManipulatedFrame is spinning. - - During spinning, spin() rotates the ManipulatedFrame by its spinningQuaternion() at a frequency - defined when the ManipulatedFrame startSpinning(). - - Use startSpinning() and stopSpinning() to change this state. Default value is \c false. */ - bool isSpinning() const { return isSpinning_; }; - /*! Returns the incremental rotation that is applied by spin() to the ManipulatedFrame - orientation when it isSpinning(). - - Default value is a null rotation (identity Quaternion). Use setSpinningQuaternion() to change - this value. - - The spinningQuaternion() axis is defined in the ManipulatedFrame coordinate system. You can use - Frame::transformOfFrom() to convert this axis from an other Frame coordinate system. */ - Quaternion spinningQuaternion() const { return spinningQuaternion_; } - public: - /*! Defines the spinningQuaternion(). Its axis is defined in the ManipulatedFrame coordinate - system. */ - void setSpinningQuaternion(const Quaternion& spinningQuaternion) { spinningQuaternion_ = spinningQuaternion; } - protected: - //virtual void spin(); - private: - void spinUpdate(); - //@} - - -#ifndef DOXYGEN - protected: - Quaternion deformedBallQuaternion(int x, int y, float cx, float cy, const AppGLWidget_Camera* const camera); - - int action_; // Should be a QGLViewer::MouseAction, but include loop - Constraint* previousConstraint_; // When manipulation is without Contraint. - - //virtual void startAction(int ma, bool withConstraint=true); // int is really a QGLViewer::MouseAction - - // Previous mouse position (used for incremental updates) and mouse press position. - Point prevPos_, pressPos_; -#endif // DOXYGEN - - private: - // Sensitivity - float rotSensitivity_; - float transSensitivity_; - float spinningSensitivity_; - float wheelSensitivity_; - - // Mouse speed and spinning - float mouseSpeed_; - int delay_; - bool isSpinning_; - Quaternion spinningQuaternion_; - - // Whether the SCREEN_TRANS direction (horizontal or vertical) is fixed or not. - bool dirIsFixed_; - - // MouseGrabber - bool keepsGrabbingMouse_; - }; - -//} // namespace qglviewer - -#endif // QGLVIEWER_MANIPULATED_FRAME_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_point.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_point.h deleted file mode 100644 index 4250922239d..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_point.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef POINT_H -#define POINT_H - -typedef int QCOORD; - -class Point -{ -public: - Point(); - Point( int xpos, int ypos ); - - bool isNull() const; - - int x() const; - int y() const; - void setX( int x ); - void setY( int y ); - - int manhattanLength() const; - - QCOORD &rx(); - QCOORD &ry(); - - Point &operator+=( const Point &p ); - Point &operator-=( const Point &p ); - Point &operator*=( int c ); - Point &operator*=( double c ); - Point &operator/=( int c ); - Point &operator/=( double c ); - - friend inline bool operator==( const Point &, const Point & ); - friend inline bool operator!=( const Point &, const Point & ); - friend inline const Point operator+( const Point &, const Point & ); - friend inline const Point operator-( const Point &, const Point & ); - friend inline const Point operator*( const Point &, int ); - friend inline const Point operator*( int, const Point & ); - friend inline const Point operator*( const Point &, double ); - friend inline const Point operator*( double, const Point & ); - friend inline const Point operator-( const Point & ); - friend inline const Point operator/( const Point &, int ); - friend inline const Point operator/( const Point &, double ); - -private: - QCOORD xp; - QCOORD yp; -}; - -static void warningDivByZero() { - // cout << "warning: dividing by zero" -} - - -/***************************************************************************** - Point inline functions - *****************************************************************************/ - -inline Point::Point() -{ xp=0; yp=0; } - -inline Point::Point( int xpos, int ypos ) -{ xp=(QCOORD)xpos; yp=(QCOORD)ypos; } - -inline bool Point::isNull() const -{ return xp == 0 && yp == 0; } - -inline int Point::x() const -{ return xp; } - -inline int Point::y() const -{ return yp; } - -inline void Point::setX( int x ) -{ xp = (QCOORD)x; } - -inline void Point::setY( int y ) -{ yp = (QCOORD)y; } - -inline QCOORD &Point::rx() -{ return xp; } - -inline QCOORD &Point::ry() -{ return yp; } - -inline Point &Point::operator+=( const Point &p ) -{ xp+=p.xp; yp+=p.yp; return *this; } - -inline Point &Point::operator-=( const Point &p ) -{ xp-=p.xp; yp-=p.yp; return *this; } - -inline Point &Point::operator*=( int c ) -{ xp*=(QCOORD)c; yp*=(QCOORD)c; return *this; } - -inline Point &Point::operator*=( double c ) -{ xp=(QCOORD)(xp*c); yp=(QCOORD)(yp*c); return *this; } - -inline bool operator==( const Point &p1, const Point &p2 ) -{ return p1.xp == p2.xp && p1.yp == p2.yp; } - -inline bool operator!=( const Point &p1, const Point &p2 ) -{ return p1.xp != p2.xp || p1.yp != p2.yp; } - -inline const Point operator+( const Point &p1, const Point &p2 ) -{ return Point(p1.xp+p2.xp, p1.yp+p2.yp); } - -inline const Point operator-( const Point &p1, const Point &p2 ) -{ return Point(p1.xp-p2.xp, p1.yp-p2.yp); } - -inline const Point operator*( const Point &p, int c ) -{ return Point(p.xp*c, p.yp*c); } - -inline const Point operator*( int c, const Point &p ) -{ return Point(p.xp*c, p.yp*c); } - -inline const Point operator*( const Point &p, double c ) -{ return Point((QCOORD)(p.xp*c), (QCOORD)(p.yp*c)); } - -inline const Point operator*( double c, const Point &p ) -{ return Point((QCOORD)(p.xp*c), (QCOORD)(p.yp*c)); } - -inline const Point operator-( const Point &p ) -{ return Point(-p.xp, -p.yp); } - -inline Point &Point::operator/=( int c ) -{ - if ( c == 0 ) - warningDivByZero(); - - xp/=(QCOORD)c; - yp/=(QCOORD)c; - return *this; -} - -inline Point &Point::operator/=( double c ) -{ - if ( c == 0.0 ) - warningDivByZero(); - - xp=(QCOORD)(xp/c); - yp=(QCOORD)(yp/c); - return *this; -} - -inline const Point operator/( const Point &p, int c ) -{ - if ( c == 0 ) - warningDivByZero(); - - return Point(p.xp/c, p.yp/c); -} - -inline const Point operator/( const Point &p, double c ) -{ - if ( c == 0.0 ) - warningDivByZero(); - - return Point((QCOORD)(p.xp/c), (QCOORD)(p.yp/c)); -} - -#endif // POINT_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_quaternion.cpp b/source/blender/freestyle/intern/app_blender/AppGLWidget_quaternion.cpp deleted file mode 100644 index 77219cdce1a..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_quaternion.cpp +++ /dev/null @@ -1,502 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#include "AppGLWidget_quaternion.h" -#include <stdlib.h> // RAND_MAX - -// All the methods are declared inline in Quaternion.h -using namespace std; - -/*! Constructs a Quaternion that will rotate from the \p from direction to the \p to direction. - -Note that this rotation is not uniquely defined. The selected axis is usually orthogonal to \p from -and \p to. However, this method is robust and can handle small or almost identical vectors. */ -Quaternion::Quaternion(const Vec& from, const Vec& to) -{ - const float epsilon = 1E-10f; - - const float fromSqNorm = from.squaredNorm(); - const float toSqNorm = to.squaredNorm(); - // Identity Quaternion when one vector is null - if ((fromSqNorm < epsilon) || (toSqNorm < epsilon)) - { - q[0]=q[1]=q[2]=0.0; - q[3]=1.0; - } - else - { - Vec axis = cross(from, to); - const float axisSqNorm = axis.squaredNorm(); - - // Aligned vectors, pick any axis, not aligned with from or to - if (axisSqNorm < epsilon) - axis = from.orthogonalVec(); - - double angle = asin(sqrt(axisSqNorm / (fromSqNorm * toSqNorm))); - - if (from*to < 0.0) - angle = M_PI-angle; - - setAxisAngle(axis, angle); - } -} - -/*! Returns the image of \p v by the Quaternion inverse() rotation. - -rotate() performs an inverse transformation. Same as inverse().rotate(v). */ -Vec Quaternion::inverseRotate(const Vec& v) const -{ - return inverse().rotate(v); -} - -/*! Returns the image of \p v by the Quaternion rotation. - -See also inverseRotate() and operator*(const Quaternion&, const Vec&). */ -Vec Quaternion::rotate(const Vec& v) const -{ - const double q00 = 2.0l * q[0] * q[0]; - const double q11 = 2.0l * q[1] * q[1]; - const double q22 = 2.0l * q[2] * q[2]; - - const double q01 = 2.0l * q[0] * q[1]; - const double q02 = 2.0l * q[0] * q[2]; - const double q03 = 2.0l * q[0] * q[3]; - - const double q12 = 2.0l * q[1] * q[2]; - const double q13 = 2.0l * q[1] * q[3]; - - const double q23 = 2.0l * q[2] * q[3]; - - return Vec((1.0 - q11 - q22)*v[0] + ( q01 - q23)*v[1] + ( q02 + q13)*v[2], - ( q01 + q23)*v[0] + (1.0 - q22 - q00)*v[1] + ( q12 - q03)*v[2], - ( q02 - q13)*v[0] + ( q12 + q03)*v[1] + (1.0 - q11 - q00)*v[2] ); -} - -/*! Set the Quaternion from a (supposedly correct) 3x3 rotation matrix. - - The matrix is expressed in European format: its three \e columns are the images by the rotation of - the three vectors of an orthogonal basis. Note that OpenGL uses a symmetric representation for its - matrices. - - setFromRotatedBasis() sets a Quaternion from the three axis of a rotated frame. It actually fills - the three columns of a matrix with these rotated basis vectors and calls this method. */ -void Quaternion::setFromRotationMatrix(const double m[3][3]) -{ - // Compute one plus the trace of the matrix - const double onePlusTrace = 1.0 + m[0][0] + m[1][1] + m[2][2]; - - if (onePlusTrace > 1E-5) - { - // Direct computation - const double s = sqrt(onePlusTrace) * 2.0; - q[0] = (m[2][1] - m[1][2]) / s; - q[1] = (m[0][2] - m[2][0]) / s; - q[2] = (m[1][0] - m[0][1]) / s; - q[3] = 0.25 * s; - } - else - { - // Computation depends on major diagonal term - if ((m[0][0] > m[1][1])&(m[0][0] > m[2][2])) - { - const double s = sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]) * 2.0; - q[0] = 0.25 * s; - q[1] = (m[0][1] + m[1][0]) / s; - q[2] = (m[0][2] + m[2][0]) / s; - q[3] = (m[1][2] - m[2][1]) / s; - } - else - if (m[1][1] > m[2][2]) - { - const double s = sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]) * 2.0; - q[0] = (m[0][1] + m[1][0]) / s; - q[1] = 0.25 * s; - q[2] = (m[1][2] + m[2][1]) / s; - q[3] = (m[0][2] - m[2][0]) / s; - } - else - { - const double s = sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]) * 2.0; - q[0] = (m[0][2] + m[2][0]) / s; - q[1] = (m[1][2] + m[2][1]) / s; - q[2] = 0.25 * s; - q[3] = (m[0][1] - m[1][0]) / s; - } - } - normalize(); -} - -#ifndef DOXYGEN -void Quaternion::setFromRotationMatrix(const float m[3][3]) -{ - cout << "setFromRotationMatrix now waits for a double[3][3] parameter" << endl; - - double mat[3][3]; - for (int i=0; i<3; ++i) - for (int j=0; j<3; ++j) - mat[i][j] = double(m[i][j]); - - setFromRotationMatrix(mat); -} - -void Quaternion::setFromRotatedBase(const Vec& X, const Vec& Y, const Vec& Z) -{ - cout << "setFromRotatedBase is deprecated, use setFromRotatedBasis instead" << endl; - setFromRotatedBasis(X,Y,Z); -} -#endif - -/*! Sets the Quaternion from the three rotated vectors of an orthogonal basis. - - The three vectors do not have to be normalized but must be orthogonal and direct (X^Y=k*Z, with k>0). - - \code - Quaternion q; - q.setFromRotatedBasis(X, Y, Z); - // Now q.rotate(Vec(1,0,0)) == X and q.inverseRotate(X) == Vec(1,0,0) - // Same goes for Y and Z with Vec(0,1,0) and Vec(0,0,1). - \endcode - - See also setFromRotationMatrix() and Quaternion(const Vec&, const Vec&). */ -void Quaternion::setFromRotatedBasis(const Vec& X, const Vec& Y, const Vec& Z) -{ - double m[3][3]; - double normX = X.norm(); - double normY = Y.norm(); - double normZ = Z.norm(); - - for (int i=0; i<3; ++i) - { - m[i][0] = X[i] / normX; - m[i][1] = Y[i] / normY; - m[i][2] = Z[i] / normZ; - } - - setFromRotationMatrix(m); -} - -/*! Returns the axis vector and the angle (in radians) of the rotation represented by the Quaternion. - See the axis() and angle() documentations. */ -void Quaternion::getAxisAngle(Vec& axis, float& angle) const -{ - angle = 2.0*acos(q[3]); - axis = Vec(q[0], q[1], q[2]); - const float sinus = axis.norm(); - if (sinus > 1E-8) - axis /= sinus; - - if (angle > M_PI) - { - angle = 2.0*M_PI - angle; - axis = -axis; - } -} - -/*! Returns the normalized axis direction of the rotation represented by the Quaternion. - -It is null for an identity Quaternion. See also angle() and getAxisAngle(). */ -Vec Quaternion::axis() const -{ - Vec res = Vec(q[0], q[1], q[2]); - const float sinus = res.norm(); - if (sinus > 1E-8) - res /= sinus; - return (acos(q[3]) <= M_PI/2.0) ? res : -res; -} - -/*! Returns the angle (in radians) of the rotation represented by the Quaternion. - - This value is always in the range [0-pi]. Larger rotational angles are obtained by inverting the - axis() direction. - - See also axis() and getAxisAngle(). */ -float Quaternion::angle() const -{ - const float angle = 2.0 * acos(q[3]); - return (angle <= M_PI) ? angle : 2.0*M_PI - angle; -} - - - - -/*! Returns the Quaternion associated 4x4 OpenGL rotation matrix. - - Use \c glMultMatrixd(q.matrix()) to apply the rotation represented by Quaternion \c q to the - current OpenGL matrix. - - See also getMatrix(), getRotationMatrix() and inverseMatrix(). - - \attention The result is only valid until the next call to matrix(). Use it immediately (as shown - above) or consider using getMatrix() instead. - - \attention The matrix is given in OpenGL format (row-major order) and is the transpose of the - actual mathematical European representation. Consider using getRotationMatrix() instead. */ -const GLdouble* Quaternion::matrix() const -{ - static GLdouble m[4][4]; - getMatrix(m); - return (const GLdouble*)(m); -} - -/*! Fills \p m with the OpenGL representation of the Quaternion rotation. - -Use matrix() if you do not need to store this matrix and simply want to alter the current OpenGL -matrix. See also getInverseMatrix() and Frame::getMatrix(). */ -void Quaternion::getMatrix(GLdouble m[4][4]) const -{ - const double q00 = 2.0l * q[0] * q[0]; - const double q11 = 2.0l * q[1] * q[1]; - const double q22 = 2.0l * q[2] * q[2]; - - const double q01 = 2.0l * q[0] * q[1]; - const double q02 = 2.0l * q[0] * q[2]; - const double q03 = 2.0l * q[0] * q[3]; - - const double q12 = 2.0l * q[1] * q[2]; - const double q13 = 2.0l * q[1] * q[3]; - - const double q23 = 2.0l * q[2] * q[3]; - - m[0][0] = 1.0l - q11 - q22; - m[1][0] = q01 - q23; - m[2][0] = q02 + q13; - - m[0][1] = q01 + q23; - m[1][1] = 1.0l - q22 - q00; - m[2][1] = q12 - q03; - - m[0][2] = q02 - q13; - m[1][2] = q12 + q03; - m[2][2] = 1.0l - q11 - q00; - - m[0][3] = 0.0l; - m[1][3] = 0.0l; - m[2][3] = 0.0l; - - m[3][0] = 0.0l; - m[3][1] = 0.0l; - m[3][2] = 0.0l; - m[3][3] = 1.0l; -} - -/*! Same as getMatrix(), but with a \c GLdouble[16] parameter. See also getInverseMatrix() and Frame::getMatrix(). */ -void Quaternion::getMatrix(GLdouble m[16]) const -{ - static GLdouble mat[4][4]; - getMatrix(mat); - int count = 0; - for (int i=0; i<4; ++i) - for (int j=0; j<4; ++j) - m[count++] = mat[i][j]; -} - -/*! Fills \p m with the 3x3 rotation matrix associated with the Quaternion. - - See also getInverseRotationMatrix(). - - \attention \p m uses the European mathematical representation of the rotation matrix. Use matrix() - and getMatrix() to retrieve the OpenGL transposed version. */ -void Quaternion::getRotationMatrix(float m[3][3]) const -{ - static GLdouble mat[4][4]; - getMatrix(mat); - for (int i=0; i<3; ++i) - for (int j=0; j<3; ++j) - // Beware of transposition - m[i][j] = mat[j][i]; -} - -/*! Returns the associated 4x4 OpenGL \e inverse rotation matrix. This is simply the matrix() of the - inverse(). - - \attention The result is only valid until the next call to inverseMatrix(). Use it immediately (as - in \c glMultMatrixd(q.inverseMatrix())) or use getInverseMatrix() instead. - - \attention The matrix is given in OpenGL format (row-major order) and is the transpose of the - actual mathematical European representation. Consider using getInverseRotationMatrix() instead. */ -const GLdouble* Quaternion::inverseMatrix() const -{ - static GLdouble m[4][4]; - getInverseMatrix(m); - return (const GLdouble*)(m); -} - -/*! Fills \p m with the OpenGL matrix corresponding to the inverse() rotation. - -Use inverseMatrix() if you do not need to store this matrix and simply want to alter the current -OpenGL matrix. See also getMatrix(). */ -void Quaternion::getInverseMatrix(GLdouble m[4][4]) const -{ - inverse().getMatrix(m); -} - -/*! Same as getInverseMatrix(), but with a \c GLdouble[16] parameter. See also getMatrix(). */ -void Quaternion::getInverseMatrix(GLdouble m[16]) const -{ - inverse().getMatrix(m); -} - -/*! \p m is set to the 3x3 \e inverse rotation matrix associated with the Quaternion. - - \attention This is the classical mathematical rotation matrix. The OpenGL format uses its - transposed version. See inverseMatrix() and getInverseMatrix(). */ -void Quaternion::getInverseRotationMatrix(float m[3][3]) const -{ - static GLdouble mat[4][4]; - getInverseMatrix(mat); - for (int i=0; i<3; ++i) - for (int j=0; j<3; ++j) - // Beware of transposition - m[i][j] = mat[j][i]; -} - - -/*! Returns the slerp interpolation of Quaternions \p a and \p b, at time \p t. - - \p t should range in [0,1]. Result is \p a when \p t=0 and \p b when \p t=1. - - When \p allowFlip is \c true (default) the slerp interpolation will always use the "shortest path" - between the Quaternions' orientations, by "flipping" the source Quaternion if needed (see - negate()). */ -Quaternion Quaternion::slerp(const Quaternion& a, const Quaternion& b, float t, bool allowFlip) -{ - float cosAngle = Quaternion::dot(a, b); - - float c1, c2; - // Linear interpolation for close orientations - if ((1.0 - fabs(cosAngle)) < 0.01) - { - c1 = 1.0 - t; - c2 = t; - } - else - { - // Spherical interpolation - float angle = acos(fabs(cosAngle)); - float sinAngle = sin(angle); - c1 = sin(angle * (1.0 - t)) / sinAngle; - c2 = sin(angle * t) / sinAngle; - } - - // Use the shortest path - if (allowFlip && (cosAngle < 0.0)) - c1 = -c1; - - return Quaternion(c1*a[0] + c2*b[0], c1*a[1] + c2*b[1], c1*a[2] + c2*b[2], c1*a[3] + c2*b[3]); -} - -/*! Returns the slerp interpolation of the two Quaternions \p a and \p b, at time \p t, using - tangents \p tgA and \p tgB. - - The resulting Quaternion is "between" \p a and \p b (result is \p a when \p t=0 and \p b for \p - t=1). - - Use squadTangent() to define the Quaternion tangents \p tgA and \p tgB. */ -Quaternion Quaternion::squad(const Quaternion& a, const Quaternion& tgA, const Quaternion& tgB, const Quaternion& b, float t) -{ - Quaternion ab = Quaternion::slerp(a, b, t); - Quaternion tg = Quaternion::slerp(tgA, tgB, t, false); - return Quaternion::slerp(ab, tg, 2.0*t*(1.0-t), false); -} - -/*! Returns the logarithm of the Quaternion. See also exp(). */ -Quaternion Quaternion::log() -{ - float len = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2]); - - if (len < 1E-6) - return Quaternion(q[0], q[1], q[2], 0.0); - else - { - float coef = acos(q[3]) / len; - return Quaternion(q[0]*coef, q[1]*coef, q[2]*coef, 0.0); - } -} - -/*! Returns the exponential of the Quaternion. See also log(). */ -Quaternion Quaternion::exp() -{ - float theta = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2]); - - if (theta < 1E-6) - return Quaternion(q[0], q[1], q[2], cos(theta)); - else - { - float coef = sin(theta) / theta; - return Quaternion(q[0]*coef, q[1]*coef, q[2]*coef, cos(theta)); - } -} - -/*! Returns log(a. inverse() * b). Useful for squadTangent(). */ -Quaternion Quaternion::lnDif(const Quaternion& a, const Quaternion& b) -{ - Quaternion dif = a.inverse()*b; - dif.normalize(); - return dif.log(); -} - -/*! Returns a tangent Quaternion for \p center, defined by \p before and \p after Quaternions. - - Useful for smooth spline interpolation of Quaternion with squad() and slerp(). */ -Quaternion Quaternion::squadTangent(const Quaternion& before, const Quaternion& center, const Quaternion& after) -{ - Quaternion l1 = Quaternion::lnDif(center,before); - Quaternion l2 = Quaternion::lnDif(center,after); - Quaternion e; - for (int i=0; i<4; ++i) - e.q[i] = -0.25 * (l1.q[i] + l2.q[i]); - e = center*(e.exp()); - - // if (Quaternion::dot(e,b) < 0.0) - // e.negate(); - - return e; -} - -ostream& operator<<(ostream& o, const Quaternion& Q) -{ - return o << Q[0] << '\t' << Q[1] << '\t' << Q[2] << '\t' << Q[3]; -} - -/*! Returns a random unit Quaternion. - -You can create a randomly directed unit vector using: -\code -Vec randomDir = Quaternion::randomQuaternion() * Vec(1.0, 0.0, 0.0); // or any other Vec -\endcode - -\note This function uses rand() to create pseudo-random numbers and the random number generator can -be initialized using srand().*/ -Quaternion Quaternion::randomQuaternion() -{ - // The rand() function is not very portable and may not be available on your system. - // Add the appropriate include or replace by an other random function in case of problem. - double seed = rand()/(float)RAND_MAX; - double r1 = sqrt(1.0 - seed); - double r2 = sqrt(seed); - double t1 = 2.0 * M_PI * (rand()/(float)RAND_MAX); - double t2 = 2.0 * M_PI * (rand()/(float)RAND_MAX); - return Quaternion(sin(t1)*r1, cos(t1)*r1, sin(t2)*r2, cos(t2)*r2); -} diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_quaternion.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_quaternion.h deleted file mode 100644 index e6242e908b1..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_quaternion.h +++ /dev/null @@ -1,304 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#ifndef QGLVIEWER_QUATERNION_H -#define QGLVIEWER_QUATERNION_H - -#include "AppGLWidget_config.h" -#include "AppGLWidget_vec.h" - - /*! \brief The Quaternion class represents 3D rotations and orientations. - \class Quaternion quaternion.h QGLViewer/quaternion.h - - The Quaternion is an appropriate (although not very intuitive) representation for 3D rotations and - orientations. Many tools are provided to ease the definition of a Quaternion: see constructors, - setAxisAngle(), setFromRotationMatrix(), setFromRotatedBasis(). - - You can apply the rotation represented by the Quaternion to 3D points using rotate() and - inverseRotate(). See also the Frame class that represents a coordinate system and provides other - conversion functions like Frame::coordinatesOf() and Frame::transformOf(). - - You can apply the Quaternion \c q rotation to the OpenGL matrices using: - \code - glMultMatrixd(q.matrix()); - // equvalent to glRotate(q.angle()*180.0/M_PI, q.axis().x, q.axis().y, q.axis().z); - \endcode - - Quaternion is part of the \c qglviewer namespace, specify \c qglviewer::Quaternion or use the qglviewer - namespace: \code using namespace qglviewer; \endcode - - <h3>Internal representation</h3> - - The internal representation of a Quaternion corresponding to a rotation around axis \c axis, with an angle - \c alpha is made of four doubles q[i]: - \code - {q[0],q[1],q[2]} = sin(alpha/2) * {axis[0],axis[1],axis[2]} - q[3] = cos(alpha/2) - \endcode - - Note that certain implementations place the cosine term in first position (instead of last here). - - The Quaternion is always normalized, so that its inverse() is actually its conjugate. - - See also the Vec and Frame classes' documentations. - \nosubgrouping */ -class Quaternion -{ -public: - /*! @name Defining a Quaternion */ - //@{ - /*! Default constructor, builds an identity rotation. */ - Quaternion() - { q[0]=q[1]=q[2]=0.0; q[3]=1.0; } - - /*! Constructor from rotation axis (non null) and angle (in radians). See also setAxisAngle(). */ - Quaternion(const Vec& axis, double angle) - { - setAxisAngle(axis, angle); - } - - Quaternion(const Vec& from, const Vec& to); - - /*! Constructor from the four values of a Quaternion. First three values are axis*sin(angle/2) and - last one is cos(angle/2). - - \attention The identity Quaternion is Quaternion(0,0,0,1) and \e not Quaternion(0,0,0,0) (which is - not unitary). The default Quaternion() creates such identity Quaternion. */ - Quaternion(double q0, double q1, double q2, double q3) - { q[0]=q0; q[1]=q1; q[2]=q2; q[3]=q3; } - - /*! Copy constructor. */ - Quaternion(const Quaternion& Q) - { for (int i=0; i<4; ++i) q[i] = Q.q[i]; } - - /*! Equal operator. */ - Quaternion& operator=(const Quaternion& Q) - { - for (int i=0; i<4; ++i) - q[i] = Q.q[i]; - return (*this); - } - - /*! Sets the Quaternion as a rotation of axis \p axis and angle \p angle (in radians). - - \p axis does not need to be normalized. A null \p axis will result in an identity Quaternion. */ - void setAxisAngle(const Vec& axis, double angle) - { - const double norm = axis.norm(); - if (norm < 1E-8) - { - // Null rotation - q[0] = 0.0; q[1] = 0.0; q[2] = 0.0; q[3] = 1.0; - } - else - { - const double sin_half_angle = sin(angle / 2.0); - q[0] = sin_half_angle*axis[0]/norm; - q[1] = sin_half_angle*axis[1]/norm; - q[2] = sin_half_angle*axis[2]/norm; - q[3] = cos(angle / 2.0); - } - } - - /*! Sets the Quaternion value. See the Quaternion(double, double, double, double) constructor documentation. */ - void setValue(double q0, double q1, double q2, double q3) - { q[0]=q0; q[1]=q1; q[2]=q2; q[3]=q3; } - -#ifndef DOXYGEN - void setFromRotationMatrix(const float m[3][3]); - void setFromRotatedBase(const Vec& X, const Vec& Y, const Vec& Z); -#endif - void setFromRotationMatrix(const double m[3][3]); - void setFromRotatedBasis(const Vec& X, const Vec& Y, const Vec& Z); - //@} - - - /*! @name Accessing values */ - //@{ - Vec axis() const; - float angle() const; - void getAxisAngle(Vec& axis, float& angle) const; - - /*! Bracket operator, with a constant return value. \p i must range in [0..3]. See the Quaternion(double, double, double, double) documentation. */ - double operator[](int i) const { return q[i]; } - - /*! Bracket operator returning an l-value. \p i must range in [0..3]. See the Quaternion(double, double, double, double) documentation. */ - double& operator[](int i) { return q[i]; } - //@} - - - /*! @name Rotation computations */ - //@{ - /*! Returns the composition of the \p a and \p b rotations. - - The order is important. When applied to a Vec \c v (see operator*(const Quaternion&, const Vec&) - and rotate()) the resulting Quaternion acts as if \p b was applied first and then \p a was - applied. This is obvious since the image \c v' of \p v by the composited rotation satisfies: \code - v'= (a*b) * v = a * (b*v) \endcode - - Note that a*b usually differs from b*a. - - \attention For efficiency reasons, the resulting Quaternion is not normalized. Use normalize() in - case of numerical drift with small rotation composition. */ - friend Quaternion operator*(const Quaternion& a, const Quaternion& b) - { - return Quaternion(a.q[3]*b.q[0] + b.q[3]*a.q[0] + a.q[1]*b.q[2] - a.q[2]*b.q[1], - a.q[3]*b.q[1] + b.q[3]*a.q[1] + a.q[2]*b.q[0] - a.q[0]*b.q[2], - a.q[3]*b.q[2] + b.q[3]*a.q[2] + a.q[0]*b.q[1] - a.q[1]*b.q[0], - a.q[3]*b.q[3] - b.q[0]*a.q[0] - a.q[1]*b.q[1] - a.q[2]*b.q[2]); - } - - /*! Quaternion rotation is composed with \p q. - - See operator*(), since this is equivalent to \c this = \c this * \p q. - - \note For efficiency reasons, the resulting Quaternion is not normalized. - You may normalize() it after each application in case of numerical drift. */ - Quaternion& operator*=(const Quaternion &q) - { - *this = (*this)*q; - return *this; - } - - /*! Returns the image of \p v by the rotation \p q. - - Same as q.rotate(v). See rotate() and inverseRotate(). */ - friend Vec operator*(const Quaternion& q, const Vec& v) - { - return q.rotate(v); - } - - Vec rotate(const Vec& v) const; - Vec inverseRotate(const Vec& v) const; - //@} - - - /*! @name Inversion */ - //@{ - /*! Returns the inverse Quaternion (inverse rotation). - - Result has a negated axis() direction and the same angle(). A composition (see operator*()) of a - Quaternion and its inverse() results in an identity function. - - Use invert() to actually modify the Quaternion. */ - Quaternion inverse() const { return Quaternion(-q[0], -q[1], -q[2], q[3]); } - - /*! Inverses the Quaternion (same rotation angle(), but negated axis()). - - See also inverse(). */ - void invert() { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; } - - /*! Negates all the coefficients of the Quaternion. - - This results in an other representation of the \e same rotation (opposite rotation angle, but with - a negated axis direction: the two cancel out). However, note that the results of axis() and - angle() are unchanged after a call to this method since angle() always returns a value in [0,pi]. - - This method is mainly useful for Quaternion interpolation, so that the spherical - interpolation takes the shortest path on the unit sphere. See slerp() for details. */ - void negate() { invert(); q[3] = -q[3]; } - - /*! Normalizes the Quaternion coefficients. - - This method should not need to be called since we only deal with unit Quaternions. This is however - useful to prevent numerical drifts, especially with small rotational increments. See also - normalized(). */ - double normalize() - { - const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]); - for (int i=0; i<4; ++i) - q[i] /= norm; - return norm; - } - - /*! Returns a normalized version of the Quaternion. - - See also normalize(). */ - Quaternion normalized() const - { - double Q[4]; - const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]); - for (int i=0; i<4; ++i) - Q[i] = q[i] / norm; - return Quaternion(Q[0], Q[1], Q[2], Q[3]); - } -//@} - - - /*! @name Associated matrix */ - //@{ - const GLdouble* matrix() const; - void getMatrix(GLdouble m[4][4]) const; - void getMatrix(GLdouble m[16]) const; - - void getRotationMatrix(float m[3][3]) const; - - const GLdouble* inverseMatrix() const; - void getInverseMatrix(GLdouble m[4][4]) const; - void getInverseMatrix(GLdouble m[16]) const; - - void getInverseRotationMatrix(float m[3][3]) const; - //@} - - - /*! @name Slerp interpolation */ - //@{ - static Quaternion slerp(const Quaternion& a, const Quaternion& b, float t, bool allowFlip=true); - static Quaternion squad(const Quaternion& a, const Quaternion& tgA, const Quaternion& tgB, const Quaternion& b, float t); - /*! Returns the "dot" product of \p a and \p b: a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]. */ - static double dot(const Quaternion& a, const Quaternion& b) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]; } - - Quaternion log(); - Quaternion exp(); - static Quaternion lnDif(const Quaternion& a, const Quaternion& b); - static Quaternion squadTangent(const Quaternion& before, const Quaternion& center, const Quaternion& after); - //@} - - /*! @name Random Quaternion */ - //@{ - static Quaternion randomQuaternion(); - //@} - -#ifdef DOXYGEN - /*! @name Output stream */ - //@{ - /*! Output stream operator. Enables debugging code like: - \code - Quaternion rot(...); - cout << "Rotation=" << rot << endl; - \endcode */ - std::ostream& operator<<(std::ostream& o, const Vec&); - //@} -#endif - -private: - /*! The internal data representation is private, use operator[] to access values. */ - double q[4]; -}; - - -std::ostream& operator<<(std::ostream& o, const Quaternion&); - -#endif // QGLVIEWER_QUATERNION_H diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_vec.cpp b/source/blender/freestyle/intern/app_blender/AppGLWidget_vec.cpp deleted file mode 100644 index 2fad849238d..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_vec.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#include "AppGLWidget_vec.h" - -// Most of the methods are declared inline in vec.h -using namespace std; - -/*! Projects the Vec on the axis of direction \p direction that passes through the origin. - -\p direction does not need to be normalized (but must be non null). */ -void Vec::projectOnAxis(const Vec& direction) -{ -#ifndef QT_NO_DEBUG - if (direction.squaredNorm() < 1.0E-10) - cout << "Vec::projectOnAxis: axis direction is not normalized (norm=" << direction.norm() << ")." << endl; -#endif - - *this = (((*this)*direction) / direction.squaredNorm()) * direction; -} - -/*! Projects the Vec on the plane whose normal is \p normal that passes through the origin. - -\p normal does not need to be normalized (but must be non null). */ -void Vec::projectOnPlane(const Vec& normal) -{ -#ifndef QT_NO_DEBUG - if (normal.squaredNorm() < 1.0E-10) - cout << "Vec::projectOnPlane: plane normal is not normalized (norm=" << normal.norm() << ")." << endl; -#endif - - *this -= (((*this)*normal) / normal.squaredNorm()) * normal; -} - -/*! Returns a Vec orthogonal to the Vec. Its norm() depends on the Vec, but is zero only for a - null Vec. Note that the function that associates an orthogonalVec() to a Vec is not continous. */ -Vec Vec::orthogonalVec() const -{ - // Find smallest component. Keep equal case for null values. - if ((fabs(y) >= 0.9*fabs(x)) && (fabs(z) >= 0.9*fabs(x))) - return Vec(0.0, -z, y); - else - if ((fabs(x) >= 0.9*fabs(y)) && (fabs(z) >= 0.9*fabs(y))) - return Vec(-z, 0.0, x); - else - return Vec(-y, x, 0.0); -} - -ostream& operator<<(ostream& o, const Vec& v) -{ - return o << v.x << '\t' << v.y << '\t' << v.z; -} - diff --git a/source/blender/freestyle/intern/app_blender/AppGLWidget_vec.h b/source/blender/freestyle/intern/app_blender/AppGLWidget_vec.h deleted file mode 100644 index 47643a19e8e..00000000000 --- a/source/blender/freestyle/intern/app_blender/AppGLWidget_vec.h +++ /dev/null @@ -1,366 +0,0 @@ -/**************************************************************************** - - Copyright (C) 2002-2007 Gilles Debunne (Gilles.Debunne@imag.fr) - - This file is part of the QGLViewer library. - Version 2.2.6-3, released on August 28, 2007. - - http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer - - libQGLViewer is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - libQGLViewer is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libQGLViewer; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -#ifndef QGLVIEWER_VEC_H -#define QGLVIEWER_VEC_H - -#include "AppGLWidget_config.h" - -// #include <qapplication.h> - -// Included by all files as vec.h is at the end of the include hierarchy -//soc #include "config.h" // Specific configuration options. - -/*! \brief The Vec class represents 3D positions and 3D vectors. - \class Vec vec.h QGLViewer/vec.h - - Vec is used as a parameter and return type by many methods of the library. It provides classical - algebraic computational methods and is compatible with OpenGL: - - \code - // Draws a point located at 3.0 OpenGL units in front of the camera - Vec pos = camera()->position() + 3.0 * camera()->viewDirection(); - glBegin(GL_POINTS); - glVertex3fv(pos); - glEnd(); - \endcode - - This makes of Vec a good candidate for representing positions and vectors in your programs. Since - it is part of the \c qglviewer namespace, specify \c qglviewer::Vec or use the qglviewer - namespace: - \code - using namespace qglviewer; - \endcode - - <h3>Interface with other vector classes</h3> - - Vec implements a universal explicit converter, based on the \c [] \c operator. - Everywhere a \c const \c Vec& argument is expected, you can use your own vector type - instead, as long as it implements this operator (see the Vec(const C& c) documentation). - - See also the Quaternion and the Frame documentations. - \nosubgrouping */ -class Vec -{ - - // If your compiler complains the "The class "qglviewer::Vec" has no member "x"." - // Add your architecture Q_OS_XXXX flag (see qglobal.h) in this list. -#if defined (Q_OS_IRIX) || defined (Q_OS_AIX) || defined (Q_OS_HPUX) -# define QGLVIEWER_UNION_NOT_SUPPORTED -#endif - -public: - /*! The internal data representation is public. One can use v.x, v.y, v.z. See also operator[](). */ -#if defined (DOXYGEN) || defined (QGLVIEWER_UNION_NOT_SUPPORTED) - float x, y, z; -#else - union - { - struct { float x, y, z; }; - float v_[3]; - }; -#endif - - /*! @name Setting the value */ - //@{ - /*! Default constructor. Value is set to (0,0,0). */ - Vec() : x(0.0), y(0.0), z(0.0) {} - - /*! Standard constructor with the x, y and z values. */ - Vec(float X, float Y, float Z) : x(X), y(Y), z(Z) {} - - /*! Universal explicit converter from any class to Vec. You can use your own vector class everywhere - a \c const \c Vec& parameter is required, as long as it implements the \c operator[ ]: - - \code - class MyVec - { - // ... - float operator[](int i) const { returns x, y or z when i=0, 1 or 2; } - } - - MyVec v(...); - camera()->setPosition(v); - \endcode - - Note that standard vector types (stl, \c float[3], ...) implement this operator and can hence - be used in place of Vec. See also operator const float*() .*/ - template <class C> - explicit Vec(const C& c) : x(c[0]), y(c[1]), z(c[2]) {} - // Should NOT be explicit to prevent conflicts with operator<<. - - // ! Copy constructor - // Vec(const Vec& v) : x(v.x), y(v.y), z(v.z) {} - - /*! Equal operator. */ - Vec& operator=(const Vec& v) - { - x = v.x; y = v.y; z = v.z; - return *this; - } - - /*! Set the current value. Maybe faster than using operator=() with a temporary Vec(x,y,z). */ - void setValue(float X, float Y, float Z) - { x=X; y=Y; z=Z; } - - // Universal equal operator which allows the use of any type in place of Vec, - // as long as the [] operator is implemented (v[0]=v.x, v[1]=v.y, v[2]=v.z). - // template <class C> - // Vec& operator=(const C& c) - // { - // x=c[0]; y=c[1]; z=c[2]; - // return *this; - // } - //@} - - /*! @name Accessing the value */ - //@{ - /*! Bracket operator, with a constant return value. \p i must range in [0..2]. */ - float operator[](int i) const { -#ifdef QGLVIEWER_UNION_NOT_SUPPORTED - return (&x)[i]; -#else - return v_[i]; -#endif - } - - /*! Bracket operator returning an l-value. \p i must range in [0..2]. */ - float& operator[](int i) { -#ifdef QGLVIEWER_UNION_NOT_SUPPORTED - return (&x)[i]; -#else - return v_[i]; -#endif - } - -#ifndef DOXYGEN - /*! This method is deprecated since version 2.0. Use operator const float* instead. */ - const float* address() const { cout << "Vec::address() is deprecated, use operator const float* instead." << endl; return operator const float*(); }; -#endif - - /*! Conversion operator returning the memory address of the vector. - - Very convenient to pass a Vec pointer as a parameter to OpenGL functions: - \code - Vec pos, normal; - glNormal3fv(normal); - glVertex3fv(pos); - \endcode */ - operator const float*() const { -#ifdef QGLVIEWER_UNION_NOT_SUPPORTED - return &x; -#else - return v_; -#endif - } - - /*! Non const conversion operator returning the memory address of the vector. - - Useful to pass a Vec to a method that requires and fills a \c float*, as provided by certain libraries. */ - operator float*() { -#ifdef QGLVIEWER_UNION_NOT_SUPPORTED - return &x; -#else - return v_; -#endif - } - //@} - - /*! @name Algebraic computations */ - //@{ - /*! Returns the sum of the two vectors. */ - friend Vec operator+(const Vec &a, const Vec &b) - { - return Vec(a.x+b.x, a.y+b.y, a.z+b.z); - } - - /*! Returns the difference of the two vectors. */ - friend Vec operator-(const Vec &a, const Vec &b) - { - return Vec(a.x-b.x, a.y-b.y, a.z-b.z); - } - - /*! Unary minus operator. */ - friend Vec operator-(const Vec &a) - { - return Vec(-a.x, -a.y, -a.z); - } - - /*! Returns the product of the vector with a scalar. */ - friend Vec operator*(const Vec &a, float k) - { - return Vec(a.x*k, a.y*k, a.z*k); - } - - /*! Returns the product of the vector with a scalar. */ - friend Vec operator*(float k, const Vec &a) - { - return a*k; - } - - /*! Returns the division of the vector with a scalar. - - Too small \p k values are \e not tested (unless the library was compiled with the "debug" Qt \c - CONFIG flag) and may result in \c NaN values. */ - friend Vec operator/(const Vec &a, float k) - { -#ifndef QT_NO_DEBUG - if (fabs(k) < 1.0E-10) - cout << "Vec::operator / : dividing by a null value" << endl; -#endif - return Vec(a.x/k, a.y/k, a.z/k); - } - - /*! Returns \c true only when the two vector are not equal (see operator==()). */ - friend bool operator!=(const Vec &a, const Vec &b) - { - return !(a==b); - } - - /*! Returns \c true when the squaredNorm() of the difference vector is lower than 1E-10. */ - friend bool operator==(const Vec &a, const Vec &b) - { - const float epsilon = 1.0E-10f; - return (a-b).squaredNorm() < epsilon; - } - - /*! Adds \p a to the vector. */ - Vec& operator+=(const Vec &a) - { - x += a.x; y += a.y; z += a.z; - return *this; - } - - /*! Subtracts \p a to the vector. */ - Vec& operator-=(const Vec &a) - { - x -= a.x; y -= a.y; z -= a.z; - return *this; - } - - /*! Multiply the vector by a scalar \p k. */ - Vec& operator*=(float k) - { - x *= k; y *= k; z *= k; - return *this; - } - - /*! Divides the vector by a scalar \p k. - - An absolute \p k value lower than 1E-10 will print a warning if the library was compiled with the - "debug" Qt \c CONFIG flag. Otherwise, no test is performed for efficiency reasons. */ - Vec& operator/=(float k) - { -#ifndef QT_NO_DEBUG - if (fabs(k)<1.0E-10) - cout << "Vec::operator /= : dividing by a null value" << endl; -#endif - x /= k; y /= k; z /= k; - return *this; - } - - /*! Dot product of the two Vec. */ - friend float operator*(const Vec &a, const Vec &b) - { - return a.x*b.x + a.y*b.y + a.z*b.z; - } - - /*! Cross product of the two vectors. Same as cross(). */ - friend Vec operator^(const Vec &a, const Vec &b) - { - return cross(a,b); - } - - /*! Cross product of the two Vec. Mind the order ! */ - friend Vec cross(const Vec &a, const Vec &b) - { - return Vec(a.y*b.z - a.z*b.y, - a.z*b.x - a.x*b.z, - a.x*b.y - a.y*b.x); - } - - Vec orthogonalVec() const; - //@} - - /*! @name Norm of the vector */ - //@{ -#ifndef DOXYGEN - /*! This method is deprecated since version 2.0. Use squaredNorm() instead. */ - float sqNorm() const { return x*x + y*y + z*z; } -#endif - - /*! Returns the \e squared norm of the Vec. */ - float squaredNorm() const { return x*x + y*y + z*z; } - - /*! Returns the norm of the vector. */ - float norm() const { return sqrt(x*x + y*y + z*z); } - - /*! Normalizes the Vec and returns its original norm. - - Normalizing a null vector will result in \c NaN values. */ - float normalize() - { - const float n = norm(); -#ifndef QT_NO_DEBUG - if (n < 1.0E-10) - cout << "Vec::normalize: normalizing a null vector" << endl; -#endif - *this /= n; - return n; - } - - /*! Returns a unitary (normalized) \e representation of the vector. The original Vec is not modified. */ - Vec unit() const - { - Vec v = *this; - v.normalize(); - return v; - } - //@} - - /*! @name Projection */ - //@{ - void projectOnAxis(const Vec& direction); - void projectOnPlane(const Vec& normal); - //@} - - -#ifdef DOXYGEN - /*! @name Output stream */ - //@{ - /*! Output stream operator. Enables debugging code like: - \code - Vec pos(...); - cout << "Position=" << pos << endl; - \endcode */ - std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&); - //@} -#endif -}; - - -std::ostream& operator<<(std::ostream& o, const Vec&); - -#endif // QGLVIEWER_VEC_H diff --git a/source/blender/freestyle/intern/app_blender/AppView.cpp b/source/blender/freestyle/intern/app_blender/AppView.cpp new file mode 100644 index 00000000000..8f918e64038 --- /dev/null +++ b/source/blender/freestyle/intern/app_blender/AppView.cpp @@ -0,0 +1,176 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <iostream> +#include "../stroke/Canvas.h" +#include "AppView.h" +#include "../scene_graph/NodeLight.h" +#include "Controller.h" +#include "../view_map/Silhouette.h" +#include "../view_map/ViewMap.h" +#include "../scene_graph/LineRep.h" +#include "../scene_graph/NodeShape.h" +#include "../scene_graph/VertexRep.h" +#include "AppConfig.h" + +#include "../system/StringUtils.h" + +extern "C" { +#include "BLI_blenlib.h" +#include "BLI_jitter.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#if 1 // FRS_antialiasing +#include "BKE_global.h" +#include "DNA_scene_types.h" +#endif + +#include "../../FRS_freestyle.h" + +} + +AppView::AppView(const char *iName) +{ + _Fovy = 30.f * M_PI / 180.0; + _ModelRootNode = new NodeDrawingStyle; + _SilhouetteRootNode = new NodeDrawingStyle; + _DebugRootNode = new NodeDrawingStyle; + + _RootNode.AddChild(_ModelRootNode); + _SilhouetteRootNode->setStyle(DrawingStyle::LINES); + _SilhouetteRootNode->setLightingEnabled(false); + _SilhouetteRootNode->setLineWidth(2.f); + _SilhouetteRootNode->setPointSize(3.f); + + _RootNode.AddChild(_SilhouetteRootNode); + + _DebugRootNode->setStyle(DrawingStyle::LINES); + _DebugRootNode->setLightingEnabled(false); + _DebugRootNode->setLineWidth(1.f); + + _RootNode.AddChild(_DebugRootNode); + + _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], + _ModelRootNode->bbox().getMin()[1]), + _ModelRootNode->bbox().getMin()[2]); + _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], + _ModelRootNode->bbox().getMax()[1]), + _ModelRootNode->bbox().getMax()[2]); + + _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); + _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); + + _p2DSelectionNode = new NodeDrawingStyle; + _p2DSelectionNode->setLightingEnabled(false); + _p2DSelectionNode->setStyle(DrawingStyle::LINES); + _p2DSelectionNode->setLineWidth(5.f); + + _p2DNode.AddChild(_p2DSelectionNode); + + + NodeLight *light = new NodeLight; + _Light.AddChild(light); +} + +AppView::~AppView() +{ + int ref = _RootNode.destroy(); + + _Light.destroy(); + ref = _p2DNode.destroy(); + +} + +real AppView::distanceToSceneCenter() { + BBox<Vec3r> bbox = _ModelRootNode->bbox(); + + Vec3r v( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]); + v -= 0.5 * (bbox.getMin() + bbox.getMax()); + + return v.norm(); +} + + +real AppView::znear() { + + BBox<Vec3r> bbox = _ModelRootNode->bbox(); + Vec3r u = bbox.getMin(); + Vec3r v = bbox.getMax(); + Vec3r cameraCenter( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]); + + Vec3r w1( u[0], u[1], u[2] ); + Vec3r w2( v[0], u[1], u[2] ); + Vec3r w3( u[0], v[1], u[2] ); + Vec3r w4( v[0], v[1], u[2] ); + Vec3r w5( u[0], u[1], v[2] ); + Vec3r w6( v[0], u[1], v[2] ); + Vec3r w7( u[0], v[1], v[2] ); + Vec3r w8( v[0], v[1], v[2] ); + + real _znear = __min( (w1-cameraCenter).norm(), + __min( (w2-cameraCenter).norm(), + __min( (w3-cameraCenter).norm(), + __min( (w4-cameraCenter).norm(), + __min( (w5-cameraCenter).norm(), + __min( (w6-cameraCenter).norm(), + __min( (w7-cameraCenter).norm(), + (w8-cameraCenter).norm() ))))))); + + return __max(_znear, 0.001); + + } + + real AppView::zfar() { + + BBox<Vec3r> bbox = _ModelRootNode->bbox(); + Vec3r u = bbox.getMin(); + Vec3r v = bbox.getMax(); + Vec3r cameraCenter( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]); + + Vec3r w1( u[0], u[1], u[2] ); + Vec3r w2( v[0], u[1], u[2] ); + Vec3r w3( u[0], v[1], u[2] ); + Vec3r w4( v[0], v[1], u[2] ); + Vec3r w5( u[0], u[1], v[2] ); + Vec3r w6( v[0], u[1], v[2] ); + Vec3r w7( u[0], v[1], v[2] ); + Vec3r w8( v[0], v[1], v[2] ); + + real _zfar = __max( (w1-cameraCenter).norm(), + __max( (w2-cameraCenter).norm(), + __max( (w3-cameraCenter).norm(), + __max( (w4-cameraCenter).norm(), + __max( (w5-cameraCenter).norm(), + __max( (w6-cameraCenter).norm(), + __max( (w7-cameraCenter).norm(), + (w8-cameraCenter).norm() ))))))); + + return _zfar; + + } + + real AppView::GetFocalLength() + { + real Near = __max(0.1,(real)(-2.f*_maxAbs+ distanceToSceneCenter() )); + return Near; + } + + diff --git a/source/blender/freestyle/intern/app_blender/AppView.h b/source/blender/freestyle/intern/app_blender/AppView.h new file mode 100644 index 00000000000..4b7207da1fd --- /dev/null +++ b/source/blender/freestyle/intern/app_blender/AppView.h @@ -0,0 +1,221 @@ +#ifndef APPVIEW_H +# define APPVIEW_H + +# ifndef WIN32 +# include <algorithm> +using namespace std; +# define __min(x,y) (min(x,y)) +# define __max(x,y) (max(x,y)) +# endif // WIN32 + +# include "../geometry/Geom.h" +# include "../geometry/BBox.h" +# include "../scene_graph/NodeDrawingStyle.h" +# include "../system/Precision.h" +# include "AppConfig.h" + +using namespace Geometry; + +class AppView +{ + +public: + + AppView(const char *iName = 0); + virtual ~AppView(); + +public: + + //inherited + inline unsigned int width() { return _width; } + inline unsigned int height() { return _height; } + inline void setWidth( unsigned int width ) { _width = width; } + inline void setHeight( unsigned int height ) { _height = height; } + +protected: + unsigned int _width, _height; + +public: + + /*! Sets the model to draw in the viewer + * iModel + * The Root Node of the model + */ + inline void setModel(NodeGroup *iModel) + { + if(0 != _ModelRootNode->numberOfChildren()) + { + _ModelRootNode->DetachChildren(); + _ModelRootNode->clearBBox(); + } + + AddModel(iModel); + } + + /*! Adds a model for displaying in the viewer */ + inline void AddModel(NodeGroup *iModel) + { + _ModelRootNode->AddChild(iModel); + + _ModelRootNode->UpdateBBox(); + + _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], + _ModelRootNode->bbox().getMin()[1]), + _ModelRootNode->bbox().getMin()[2]); + _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], + _ModelRootNode->bbox().getMax()[1]), + _ModelRootNode->bbox().getMax()[2]); + + _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); + + _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); + + } + + inline void AddSilhouette(NodeGroup* iSilhouette) + { + _SilhouetteRootNode->AddChild(iSilhouette); + } + + inline void Add2DSilhouette(NodeGroup *iSilhouette) + { + //_pFENode->AddChild(iSilhouette); + } + + inline void Add2DVisibleSilhouette(NodeGroup *iVSilhouette) + { + //_pVisibleSilhouetteNode->AddChild(iVSilhouette); + } + + inline void setDebug(NodeGroup* iDebug) + { + if(0 != _DebugRootNode->numberOfChildren()) + { + _DebugRootNode->DetachChildren(); + _DebugRootNode->clearBBox(); + } + + AddDebug(iDebug); + } + + inline void AddDebug(NodeGroup* iDebug) + { + _DebugRootNode->AddChild(iDebug); + } + + inline void DetachModel(Node *iModel) + { + _ModelRootNode->DetachChild(iModel); + _ModelRootNode->UpdateBBox(); + + _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], + _ModelRootNode->bbox().getMin()[1]), + _ModelRootNode->bbox().getMin()[2]); + _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], + _ModelRootNode->bbox().getMax()[1]), + _ModelRootNode->bbox().getMax()[2]); + + _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); + _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); + } + + inline void DetachModel() + { + _ModelRootNode->DetachChildren(); + _ModelRootNode->clearBBox(); + + // 2D Scene + //_p2DNode.DetachChildren(); + //_pFENode->DetachChildren(); + //_pVisibleSilhouetteNode->DetachChildren(); + + } + + inline void DetachSilhouette() + { + _SilhouetteRootNode->DetachChildren(); + //_pFENode->DetachChildren(); + //_pVisibleSilhouetteNode->DetachChildren(); + _p2DSelectionNode->destroy(); + } + + inline void DetachVisibleSilhouette() + { + //_pVisibleSilhouetteNode->DetachChildren(); + _p2DSelectionNode->destroy(); + } + + inline void DetachDebug() + { + _DebugRootNode->DetachChildren(); + } + + + + real distanceToSceneCenter(); + real GetFocalLength(); + + inline real GetAspect() const + { + return ((real) _width/(real) _height); + } + + void setHorizontalFov( float hfov ) +{ + _Fovy = 2.0 * atan (tan(hfov / 2.0) / GetAspect()); +} + inline real GetFovyRadian() const + { + return _Fovy; + } + + inline real GetFovyDegrees() const + { + return _Fovy * 180.0 / M_PI; + } + + BBox<Vec3r> scene3DBBox() const { return _ModelRootNode->bbox(); } + + real znear(); + real zfar(); + + +public: + /*! Core scene drawing */ + void DrawScene(SceneVisitor *iRenderer); + + /*! 2D Scene Drawing */ + void Draw2DScene(SceneVisitor *iRenderer); + + +protected: + + /*! fabs or abs */ + inline int rabs(int x) {return abs(x);} + inline real rabs(real x) {return fabs(x);} + + +protected: + float _Fovy; + + //The root node container + NodeGroup _RootNode; + NodeDrawingStyle *_ModelRootNode; + NodeDrawingStyle *_SilhouetteRootNode; + NodeDrawingStyle *_DebugRootNode; + + NodeGroup _Light; + + real _minBBox; + real _maxBBox; + real _maxAbs; + real _minAbs; + + // 2D Scene + bool _Draw2DScene; + bool _Draw3DScene; NodeGroup _p2DNode; + NodeDrawingStyle *_p2DSelectionNode; + +}; + +#endif // APPVIEW_H diff --git a/source/blender/freestyle/intern/app_blender/Controller.cpp b/source/blender/freestyle/intern/app_blender/Controller.cpp index 64bcdd5acb8..9595f1c51de 100755 --- a/source/blender/freestyle/intern/app_blender/Controller.cpp +++ b/source/blender/freestyle/intern/app_blender/Controller.cpp @@ -26,7 +26,7 @@ #include <fstream> #include <float.h> -#include "AppGLWidget.h" +#include "AppView.h" #include "AppCanvas.h" #include "AppConfig.h" @@ -57,8 +57,19 @@ #include "../system/StringUtils.h" #include "../scene_graph/BlenderFileLoader.h" +#include "../stroke/BlenderStrokeRenderer.h" + +#ifdef __cplusplus +extern "C" { +#endif + + #include "../../FRS_freestyle.h" + +#ifdef __cplusplus +} +#endif + -#include "../../FRS_freestyle.h" Controller::Controller() { @@ -155,7 +166,7 @@ Controller::~Controller() //delete _current_dirs; } -void Controller::setView(AppGLWidget *iView) +void Controller::setView(AppView *iView) { if(NULL == iView) return; @@ -166,8 +177,6 @@ void Controller::setView(AppGLWidget *iView) int Controller::LoadMesh(Render *re) { - if (_pView) - _pView->setUpdateMode(false); BlenderFileLoader loader(re); @@ -341,194 +350,7 @@ void Controller::CloseFile() } -// static const streamsize buffer_size = 512 * 1024; - -void Controller::SaveViewMapFile(const char *oFileName) -{ - if (!_ViewMap) - return; - - ofstream ofs(oFileName, ios::binary); - if (!ofs.is_open()) { - cerr << "Error: Cannot save this file" << endl; - return; - } -// char buffer[buffer_size]; -// #if defined(__GNUC__) && (__GNUC__ < 3) -// ofs.rdbuf()->setbuf(buffer, buffer_size); -// # else -// ofs.rdbuf()->pubsetbuf(buffer, buffer_size); -// #endif - _Chrono.start(); - ofs << Config::VIEWMAP_MAGIC << endl << Config::VIEWMAP_VERSION << endl; - - // Write the models filenames - ofs << _ListOfModels.size() << endl; - for (vector<string>::const_iterator i = _ListOfModels.begin(); i != _ListOfModels.end(); i++) - ofs << *i << "\n"; - - // Save the camera position - float position[3]; - float orientation[4]; - _pView->getCameraState(position, orientation); - ofs.write((char*)position, 3 * sizeof(*position)); - ofs.write((char*)orientation, 4 * sizeof(*orientation)); - - // Write ViewMap - if (ViewMapIO::save(ofs, _ViewMap, 0)) { - _Chrono.stop(); - cerr << "Error: Cannot save this file" << endl; - return; - } - - real d = _Chrono.stop(); - cout << "ViewMap saving : " << d << endl; -} - -// void Controller::LoadViewMapFile(const char *iFileName, bool only_camera) -// { -// ifstream ifs(iFileName, ios::binary); -// if (!ifs.is_open()) { -// cerr << "Error: Cannot load this file" << endl; -// return; -// } -// // char buffer[buffer_size]; -// // #if defined(__GNUC__) && (__GNUC__ < 3) -// // ifs.rdbuf()->setbuf(buffer, buffer_size); -// // # else -// // ifs.rdbuf()->pubsetbuf(buffer, buffer_size); -// // #endif -// -// // Test File Magic and version -// char tmp_buffer[256]; -// string test; -// -// ifs.getline(tmp_buffer, 255); -// test = tmp_buffer; -// if (test != Config::VIEWMAP_MAGIC) { -// cerr << "Error: This is not a valid ." << Config::VIEWMAP_EXTENSION << " file" << endl; -// return; -// } -// ifs.getline(tmp_buffer, 255); -// test = tmp_buffer; -// if (test != Config::VIEWMAP_VERSION && !only_camera) { -// cerr << "Error: This version of the ." << Config::VIEWMAP_EXTENSION << " file format is no longer supported" << endl; -// return; -// } -// -// // Read the models filenames and open them (if not already done) -// string tmp; -// vector<string> tmp_vec; -// unsigned models_nb, i; -// -// ifs.getline(tmp_buffer, 255); -// models_nb = atoi(tmp_buffer); -// for (i = 0; i < models_nb; i++) { -// ifs.getline(tmp_buffer, 255); -// tmp = tmp_buffer; -// tmp_vec.push_back(tmp); -// } -// if (_ListOfModels != tmp_vec && !only_camera) { -// CloseFile(); -// vector<string> pathnames; -// int err = 0; -// for (vector<string>::const_iterator i = tmp_vec.begin(); i != tmp_vec.end(); i++) -// { -// pathnames.clear(); -// StringUtils::getPathName(ViewMapIO::Options::getModelsPath(), *i, pathnames); -// for (vector<string>::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) -// if (!(err = Load3DSFile(j->c_str()))) -// break; -// if (err) { -// cerr << "Error: cannot find model \"" << *i << "\" - check the path in the Options" << endl; -// return; -// } -// } -// } -// -// // set the camera position -// float position[3]; -// float orientation[4]; -// ifs.read((char*)position, 3 * sizeof(*position)); -// ifs.read((char*)orientation, 4 * sizeof(*orientation)); -// _pView->setCameraState(position, orientation); -// _pView->saveCameraState(); -// -// if (only_camera) { -// return; -// } -// -// // Reset ViewMap -// if(NULL != _ViewMap) -// { -// delete _ViewMap; -// _ViewMap = 0; -// } -// _pView->DetachSilhouette(); -// if (NULL != _SilhouetteNode) -// { -// int ref = _SilhouetteNode->destroy(); -// if(0 == ref) -// delete _SilhouetteNode; -// } -// // if(NULL != _ProjectedSilhouette) -// // { -// // int ref = _ProjectedSilhouette->destroy(); -// // if(0 == ref) -// // delete _ProjectedSilhouette; -// // } -// // if(NULL != _VisibleProjectedSilhouette) -// // { -// // int ref = _VisibleProjectedSilhouette->destroy(); -// // if(0 == ref) -// // { -// // delete _VisibleProjectedSilhouette; -// // _VisibleProjectedSilhouette = 0; -// // } -// // } -// _ViewMap = new ViewMap(); -// -// // Read ViewMap -// _Chrono.start(); -// if (ViewMapIO::load(ifs, _ViewMap, 0)) { -// _Chrono.stop(); -// -// cerr << "Error: This is not a valid ." << Config::VIEWMAP_EXTENSION << " file" << endl; -// return; -// } -// -// // Update display -// ViewMapTesselator3D sTesselator3d; -// //ViewMapTesselator2D sTesselator2d; -// //sTesselator2d.setNature(_edgeTesselationNature); -// sTesselator3d.setNature(_edgeTesselationNature); -// -// // Tesselate the 3D edges: -// _SilhouetteNode = sTesselator3d.Tesselate(_ViewMap); -// _SilhouetteNode->addRef(); -// -// // Tesselate 2D edges -// // _ProjectedSilhouette = sTesselator2d.Tesselate(_ViewMap); -// // _ProjectedSilhouette->addRef(); -// // -// _pView->AddSilhouette(_SilhouetteNode); -// //_pView->Add2DSilhouette(_ProjectedSilhouette); -// -// // Update options window -// //_pOptionsWindow->updateViewMapFormat(); -// -// real d = _Chrono.stop(); -// cout << "ViewMap loading : " << d << endl; -// -// // Compute the Directional ViewMap: -// if(_ComputeSteerableViewMap){ -// ComputeSteerableViewMap(); -// } -// -// // Reset Style modules modification flags -// resetModified(true); -// } void Controller::ComputeViewMap() { @@ -578,12 +400,10 @@ void Controller::ComputeViewMap() //---------------------------------------------------------- // Save the viewpoint context at the view level in order // to be able to restore it later: - _pView->saveCameraState(); // Restore the context of view: // we need to perform all these operations while the // 3D context is on. - _pView->set3DContext(); Vec3r vp( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]); real mv[4][4]; @@ -602,12 +422,10 @@ void Controller::ComputeViewMap() for( int i= 0; i < 4; i++) viewport[i] = freestyle_viewport[i]; - - real focalLength = _pView->GetFocalLength(); - // Flag the WXEdge structure for silhouette edge detection: //---------------------------------------------------------- + cout << "\n=== Detecting silhouette edges ===" << endl; _Chrono.start(); edgeDetector.setViewpoint(Vec3r(vp)); @@ -625,17 +443,8 @@ void Controller::ComputeViewMap() ViewMapBuilder vmBuilder; vmBuilder.setEnableQI(_EnableQI); vmBuilder.setViewpoint(Vec3r(vp)); - -cout << "focalLength: " << focalLength << endl; -cout << "aspect: " << _pView->GetAspect() << endl; -cout << "fovyradian: " << _pView->GetFovyRadian() << endl; - -cout << "znear: " << _pView->znear() << endl; -cout << "zfar: " << _pView->zfar() << endl; - - vmBuilder.setTransform( mv, proj,viewport, focalLength, _pView->GetAspect(), _pView->GetFovyRadian()); - vmBuilder.setFrustum(_pView->znear(), _pView->zfar()); - + vmBuilder.setTransform( mv, proj,viewport, _pView->GetFocalLength(), _pView->GetAspect(), _pView->GetFovyRadian()); + vmBuilder.setFrustum(_pView->znear(), _pView->zfar()); vmBuilder.setGrid(&_Grid); // Builds a tesselated form of the silhouette for display purpose: @@ -645,6 +454,7 @@ cout << "zfar: " << _pView->zfar() << endl; //sTesselator2d.setNature(_edgeTesselationNature); sTesselator3d.setNature(_edgeTesselationNature); + cout << "\n=== Building the view map ===" << endl; _Chrono.start(); // Build View Map _ViewMap = vmBuilder.BuildViewMap(*_winged_edge, _VisibilityAlgo, _EPSILON); @@ -816,25 +626,6 @@ void Controller::setComputeSteerableViewMapFlag(bool iBool){ bool Controller::getComputeSteerableViewMapFlag() const { return _ComputeSteerableViewMap; } -void Controller::setFrontBufferFlag(bool iBool) -{ - AppGLWidget::setFrontBufferFlag(iBool); -} - -bool Controller::getFrontBufferFlag() const -{ - return AppGLWidget::getFrontBufferFlag(); -} - -void Controller::setBackBufferFlag(bool iBool) -{ - AppGLWidget::setBackBufferFlag(iBool); -} - -bool Controller::getBackBufferFlag() const -{ - return AppGLWidget::getBackBufferFlag(); -} void Controller::DrawStrokes() { @@ -930,30 +721,6 @@ void Controller::resetModified(bool iMod) _Canvas->resetModified(iMod); } -FEdge* Controller::SelectFEdge(real x, real y) -{ - if (!_ViewMap) - return NULL; - - FEdge *fedge = (FEdge*)_ViewMap->getClosestFEdge(x,y); - //ViewEdge *selection = fedge->viewedge(); - _pView->setSelectedFEdge(fedge); - _Canvas->setSelectedFEdge(fedge); - return fedge; -} - -ViewEdge* Controller::SelectViewEdge(real x, real y) -{ - if (!_ViewMap) - return NULL; - - FEdge *fedge = (FEdge*)_ViewMap->getClosestFEdge(x,y); - ViewEdge *selection = fedge->viewedge(); - _pView->setSelectedFEdge(fedge); - _Canvas->setSelectedFEdge(fedge); - return selection; -} - NodeGroup * Controller::BuildRep(vector<ViewEdge*>::iterator vedges_begin, vector<ViewEdge*>::iterator vedges_end) { @@ -1070,10 +837,6 @@ void Controller::init_options(){ // Visibility setQuantitativeInvisibility(true); - // Drawing Buffers - setFrontBufferFlag(false); - setBackBufferFlag(true); - // soc: initialize canvas _Canvas->init(); } diff --git a/source/blender/freestyle/intern/app_blender/Controller.h b/source/blender/freestyle/intern/app_blender/Controller.h index 8521cdc7f68..84c50061d7c 100755 --- a/source/blender/freestyle/intern/app_blender/Controller.h +++ b/source/blender/freestyle/intern/app_blender/Controller.h @@ -41,7 +41,7 @@ # include "../system/Interpreter.h" # include "../view_map/FEdgeXDetector.h" -class AppGLWidget; +class AppView; class NodeGroup; class WShape; class SShape; @@ -68,7 +68,7 @@ public: Controller() ; ~Controller() ; - void setView(AppGLWidget *iView); + void setView(AppView *iView); //soc void init_options(); @@ -76,8 +76,6 @@ public: int LoadMesh( Render *re ); int Load3DSFile(const char *iFileName); void CloseFile(); - void LoadViewMapFile(const char *iFileName, bool only_camera = false); - void SaveViewMapFile(const char *iFileName); void ComputeViewMap(); void ComputeSteerableViewMap(); void saveSteerableViewMapImages(); @@ -103,7 +101,7 @@ public: vector<ViewEdge*>::iterator vedges_end) ; NodeGroup* debugNode() {return _DebugNode;} - AppGLWidget * view() {return _pView;} + AppView * view() {return _pView;} NodeGroup* debugScene() {return _DebugNode;} Grid& grid() {return _Grid;} @@ -112,11 +110,6 @@ public: void setQuantitativeInvisibility(bool iBool); // if true, we compute quantitativeInvisibility bool getQuantitativeInvisibility() const; - void setFrontBufferFlag(bool b); - bool getFrontBufferFlag() const; - void setBackBufferFlag(bool b); - bool getBackBufferFlag() const; - void setComputeRidgesAndValleysFlag(bool b); bool getComputeRidgesAndValleysFlag() const ; void setComputeSuggestiveContoursFlag(bool b); @@ -144,6 +137,9 @@ public: // Viewmap data structure ViewMap * _ViewMap; + // Canvas + AppCanvas *_Canvas; + private: // Main Window: @@ -155,12 +151,11 @@ private: // Current directories //ConfigIO* _current_dirs; - // Canvas - AppCanvas *_Canvas; + //View // 3D - AppGLWidget *_pView; + AppView *_pView; // 2D //Viewer2DWindow *_pView2DWindow; diff --git a/source/blender/freestyle/intern/app_blender/api.cpp b/source/blender/freestyle/intern/app_blender/api.cpp index c91efa89466..95045cccfdd 100644 --- a/source/blender/freestyle/intern/app_blender/api.cpp +++ b/source/blender/freestyle/intern/app_blender/api.cpp @@ -1,6 +1,7 @@ -#include "AppGLWidget.h" +#include "AppView.h" #include "Controller.h" #include "AppConfig.h" +#include "AppCanvas.h" #include <iostream> @@ -9,7 +10,6 @@ extern "C" { #endif #include "../../FRS_freestyle.h" -#include "AppCanvas.h" #include "DNA_camera_types.h" #include "DNA_scene_types.h" @@ -33,7 +33,7 @@ extern "C" { static Config::Path *pathconfig = NULL; static Controller *controller = NULL; - static AppGLWidget *view = NULL; + static AppView *view = NULL; char style_module[255] = ""; int freestyle_flags; @@ -54,7 +54,7 @@ extern "C" { controller = new Controller; if( view == NULL ) { - view = new AppGLWidget; + view = new AppView; controller->setView(view); } @@ -76,30 +76,13 @@ extern "C" { view->setWidth( width ); view->setHeight( height ); - view->_camera->setScreenWidthAndHeight( width , height ); } void FRS_init_camera(Render* re){ Object* maincam_obj = re->scene->camera; Camera *cam = (Camera*) maincam_obj->data; - if(cam->type == CAM_PERSP){ - view->_camera->setType(AppGLWidget_Camera::PERSPECTIVE); - view->_camera->setHorizontalFieldOfView( M_PI / 180.0f * cam->angle ); - } - else if (cam->type == CAM_ORTHO){ - view->_camera->setType(AppGLWidget_Camera::ORTHOGRAPHIC); - // view->_camera->setFocusDistance does not seem to work - // integrate cam->ortho_scale parameter - } - - Vec camPosition(maincam_obj->obmat[3][0], maincam_obj->obmat[3][1], maincam_obj->obmat[3][2]); - Vec camUp( re->viewmat[0][1], re->viewmat[1][1], re->viewmat[2][1]); - Vec camDirection( -re->viewmat[0][2], -re->viewmat[1][2], -re->viewmat[2][2]); - - view->_camera->setPosition(camPosition); - view->_camera->setUpVector(camUp); - view->_camera->setViewDirection(camDirection); + view->setHorizontalFov( cam->angle ); freestyle_viewpoint[0] = maincam_obj->obmat[3][0]; freestyle_viewpoint[1] = maincam_obj->obmat[3][1]; @@ -144,6 +127,7 @@ extern "C" { return; // add style module + cout << "\n=== Rendering options ===" << endl; cout << "Module: " << style_module << endl; controller->InsertStyleModule( 0, style_module ); controller->toggleLayer(0, true); @@ -169,12 +153,13 @@ extern "C" { // build strokes controller->DrawStrokes(); - cout << "Rendering Freestyle with Blender's internal renderer" << endl; + cout << "\n=== Rendering Freestyle with Blender's internal renderer ===" << endl; controller->RenderBlender(re); controller->CloseFile(); } else { cout << "Freestyle cannot be used because the view map is not available" << endl; } + cout << "###################################################################" << endl; } #ifdef __cplusplus |