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

SourceForge.net Logo

©2005 Laurent Ribon