glc_reptrackballmover.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021  *****************************************************************************/
00022 
00024 
00025 #include "glc_reptrackballmover.h"
00026 #include "glc_viewport.h"
00027 #include "../glc_factory.h"
00028 #include <QGLContext>
00029 
00030 using namespace glc;
00032 #define ARCANGLE (30 * PI / 180)
00033 
00034 GLC_RepTrackBallMover::GLC_RepTrackBallMover(GLC_Viewport* pViewport)
00035 : GLC_RepMover(pViewport)
00036 , m_Radius(1.0)
00037 , m_MainCircle(m_Radius)
00038 , m_Arc1(GLC_Factory::instance()->createCircle(m_Radius, ARCANGLE))
00039 , m_MatArc1()
00040 , m_Arc2(GLC_Factory::instance()->createCircle(m_Radius, ARCANGLE))
00041 , m_MatArc2()
00042 , m_Ratio(0.95)
00043 {
00044         m_MainCircle.setWireColor(GLC_RepMover::m_MainColor);
00045         m_Arc1.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor);
00046         m_Arc2.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor);
00047 
00048         // 2 circle arcs position
00049         GLC_Matrix4x4 MatRot(Z_AXIS, -ARCANGLE / 2);
00050         GLC_Matrix4x4 MatInt(Y_AXIS, -PI / 2);
00051         MatRot= MatInt * MatRot;
00052 
00053         m_MatArc1= MatRot;
00054 
00055         MatInt.setMatRot(Z_AXIS, PI/2);
00056         MatRot= MatInt * MatRot;
00057 
00058         m_MatArc2= MatRot;
00059 
00060 }
00061 
00062 // Copy constructor
00063 GLC_RepTrackBallMover::GLC_RepTrackBallMover(const GLC_RepTrackBallMover& repMover)
00064 : GLC_RepMover(repMover)
00065 , m_Radius(repMover.m_Radius)
00066 , m_MainCircle(repMover.m_MainCircle)
00067 , m_Arc1(repMover.m_Arc1.deepCopy())
00068 , m_MatArc1(repMover.m_MatArc1)
00069 , m_Arc2(repMover.m_Arc2.deepCopy())
00070 , m_MatArc2(repMover.m_MatArc2)
00071 , m_Ratio(repMover.m_Ratio)
00072 {
00073 
00074 }
00075 
00076 GLC_RepTrackBallMover::~GLC_RepTrackBallMover()
00077 {
00078 
00079 }
00080 
00081 
00083 // Get Functions
00085 
00086 // Return a clone of the repmover
00087 GLC_RepMover* GLC_RepTrackBallMover::clone() const
00088 {
00089         return new GLC_RepTrackBallMover(*this);
00090 }
00091 
00093 // Set Functions
00095 
00096 // Set Arcs orientation and position in concordance with mouse position
00097 void GLC_RepTrackBallMover::init()
00098 {
00099         Q_ASSERT(NULL != m_pRepMoverInfo);
00100         Q_ASSERT(!m_pRepMoverInfo->m_VectorInfo.isEmpty());
00101         Q_ASSERT(!m_pRepMoverInfo->m_MatrixInfo.isEmpty());
00102 
00103         GLC_Vector3d VectAngle(m_pRepMoverInfo->m_VectorInfo.first());
00104         VectAngle.setZ(0);
00105         VectAngle.setLength(1);
00106 
00107         GLC_Matrix4x4 MatRot;
00108         double Angle;
00109 
00110         // Compute the 2 arcs orientation
00111         if (VectAngle.y() > 0)
00112         {       // Angle entre 0 et PI
00113                 Angle= acos(VectAngle.x());
00114                 MatRot.setMatRot(Z_AXIS, Angle);
00115         }
00116         else
00117         {       // Angle between 0 et -PI
00118                 Angle= -acos(VectAngle.x());
00119                 MatRot.setMatRot(Z_AXIS, Angle);
00120         }
00121 
00122         // Composition of orientation matrix and mapping matrix
00123         MatRot= m_pRepMoverInfo->m_MatrixInfo.first() * MatRot;
00124 
00125         m_Arc1.setMatrix(MatRot * m_MatArc1);
00126         m_Arc2.setMatrix(MatRot * m_MatArc2);
00127 }
00128 
00129 // Set Arcs position in concordance with mouse position
00130 void GLC_RepTrackBallMover::update()
00131 {
00132         Q_ASSERT(NULL != m_pRepMoverInfo);
00133         Q_ASSERT(!m_pRepMoverInfo->m_MatrixInfo.isEmpty());
00134         const GLC_Matrix4x4 matrix(m_pRepMoverInfo->m_MatrixInfo.first());
00135         m_Arc1.multMatrix(matrix);
00136         m_Arc2.multMatrix(matrix);
00137 }
00138 
00139 // overload function setColor(color);
00140 void GLC_RepTrackBallMover::setMainColor(const QColor& color)
00141 {
00142         GLC_RepMover::setMainColor(color);
00143         m_MainCircle.setWireColor(GLC_RepMover::m_MainColor);
00144         m_Arc1.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor);
00145         m_Arc2.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor);
00146 }
00147 
00149 // OpenGL Functions
00151 
00152 // Virtual interface for OpenGL Geometry set up.
00153 void GLC_RepTrackBallMover::glDraw()
00154 {
00155         computeRadius();
00156         const double aspectRatio= static_cast<double>(m_pViewport->viewHSize())/static_cast<double>(m_pViewport->viewVSize());
00157 
00158         // Save current state
00159         GLboolean depthTest, blend;
00160         glGetBooleanv(GL_DEPTH_TEST, &depthTest);
00161         glGetBooleanv(GL_BLEND, &blend);
00162 
00163         // orbit circle must be shown
00164         if (depthTest) glDisable(GL_DEPTH_TEST);
00165 
00166         glMatrixMode(GL_PROJECTION);
00167         glPushMatrix();
00168         glLoadIdentity();
00169         glOrtho(aspectRatio * -1.0 ,aspectRatio * 1.0 ,-1.0 ,1.0 ,-1.0 ,1.0);
00170         glMatrixMode(GL_MODELVIEW);
00171         glPushMatrix();
00172         glLoadIdentity();
00173 
00174         if (blend) glDisable(GL_BLEND);
00175         m_RenderProperties.setRenderingFlag(glc::WireRenderFlag);
00176         // Display arcs
00177         m_Arc1.render(glc::WireRenderFlag);
00178         m_Arc2.render(glc::WireRenderFlag);
00179         // Display base class (Main circle)
00180         m_MainCircle.render(m_RenderProperties);
00181 
00182     glEnable(GL_BLEND);
00183     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00184         m_RenderProperties.setRenderingFlag(glc::TransparentRenderFlag);
00185         // Display arcs
00186         m_Arc1.render(glc::TransparentRenderFlag);
00187         m_Arc2.render(glc::TransparentRenderFlag);
00188         // Display base class (Main circle)
00189         m_MainCircle.render(m_RenderProperties);
00190 
00191         glPopMatrix();
00192         glMatrixMode(GL_PROJECTION);
00193         glPopMatrix();
00194         glMatrixMode(GL_MODELVIEW);
00195 
00196         if (depthTest) glEnable(GL_DEPTH_TEST);
00197         if (!blend)  glEnable(GL_BLEND);
00198 
00199 }
00200 
00202 // Private services Functions
00204 
00205 // Compute trackball radius
00206 void GLC_RepTrackBallMover::computeRadius()
00207 {
00208         int nRayonSph;
00209         const double winHSize= static_cast<double>(m_pViewport->viewHSize());
00210         const double winVSize= static_cast<double>(m_pViewport->viewVSize());
00211 
00212         if (winHSize > winVSize)
00213         {
00214                 nRayonSph = static_cast<int>(m_Ratio * winVSize / 2.0);
00215         }
00216         else
00217         {
00218                 nRayonSph = static_cast<int>(m_Ratio * winHSize / 2.0);
00219         }
00220 
00221         // Compute the length of camera's field of view
00222         const double ChampsVision = 2.0;
00223 
00224         // the side of camera's square is mapped on Vertical length of window
00225         // Circle radius in OpenGL unit = Radius(Pixel) * (dimend GL / dimens Pixel)
00226         const double RayonSph= fabs((static_cast<double>(nRayonSph) * ChampsVision / winVSize));
00227 
00228         if ((!qFuzzyCompare(RayonSph, 0.0) && !qFuzzyCompare(RayonSph - m_Radius, 0.0)) || (RayonSph < 2.0))
00229         {
00230                 // Main circle radius
00231                 m_MainCircle.setRadius(RayonSph);
00232 
00233                 GLC_Circle* pCircle;
00234                 // Arc 1 radius
00235                 pCircle= static_cast<GLC_Circle*>(m_Arc1.geomAt(0));
00236                 pCircle->setRadius(RayonSph);
00237                 // Arc 2 radius
00238                 pCircle= static_cast<GLC_Circle*>(m_Arc2.geomAt(0));
00239                 pCircle->setRadius(RayonSph);
00240         }
00241 
00242 }

SourceForge.net Logo

©2005-2011 Laurent Ribon