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 "../glc_context.h"
00029 #include <QGLContext>
00030 
00031 using namespace glc;
00033 #define ARCANGLE (30 * PI / 180)
00034 
00035 GLC_RepTrackBallMover::GLC_RepTrackBallMover(GLC_Viewport* pViewport)
00036 : GLC_RepMover(pViewport)
00037 , m_Radius(1.0)
00038 , m_MainCircle(m_Radius)
00039 , m_Arc1(GLC_Factory::instance()->createCircle(m_Radius, ARCANGLE))
00040 , m_MatArc1()
00041 , m_Arc2(GLC_Factory::instance()->createCircle(m_Radius, ARCANGLE))
00042 , m_MatArc2()
00043 , m_Ratio(0.95)
00044 {
00045         m_MainCircle.setWireColor(GLC_RepMover::m_MainColor);
00046         m_Arc1.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor);
00047         m_Arc2.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor);
00048 
00049         // 2 circle arcs position
00050         GLC_Matrix4x4 MatRot(Z_AXIS, -ARCANGLE / 2);
00051         GLC_Matrix4x4 MatInt(Y_AXIS, -PI / 2);
00052         MatRot= MatInt * MatRot;
00053 
00054         m_MatArc1= MatRot;
00055 
00056         MatInt.setMatRot(Z_AXIS, PI/2);
00057         MatRot= MatInt * MatRot;
00058 
00059         m_MatArc2= MatRot;
00060 
00061 }
00062 
00063 // Copy constructor
00064 GLC_RepTrackBallMover::GLC_RepTrackBallMover(const GLC_RepTrackBallMover& repMover)
00065 : GLC_RepMover(repMover)
00066 , m_Radius(repMover.m_Radius)
00067 , m_MainCircle(repMover.m_MainCircle)
00068 , m_Arc1(repMover.m_Arc1.deepCopy())
00069 , m_MatArc1(repMover.m_MatArc1)
00070 , m_Arc2(repMover.m_Arc2.deepCopy())
00071 , m_MatArc2(repMover.m_MatArc2)
00072 , m_Ratio(repMover.m_Ratio)
00073 {
00074 
00075 }
00076 
00077 GLC_RepTrackBallMover::~GLC_RepTrackBallMover()
00078 {
00079 
00080 }
00081 
00082 
00084 // Get Functions
00086 
00087 // Return a clone of the repmover
00088 GLC_RepMover* GLC_RepTrackBallMover::clone() const
00089 {
00090         return new GLC_RepTrackBallMover(*this);
00091 }
00092 
00094 // Set Functions
00096 
00097 // Set Arcs orientation and position in concordance with mouse position
00098 void GLC_RepTrackBallMover::init()
00099 {
00100         Q_ASSERT(NULL != m_pRepMoverInfo);
00101         Q_ASSERT(!m_pRepMoverInfo->m_VectorInfo.isEmpty());
00102         Q_ASSERT(!m_pRepMoverInfo->m_MatrixInfo.isEmpty());
00103 
00104         GLC_Vector3d VectAngle(m_pRepMoverInfo->m_VectorInfo.first());
00105         VectAngle.setZ(0);
00106         VectAngle.setLength(1);
00107 
00108         GLC_Matrix4x4 MatRot;
00109         double Angle;
00110 
00111         // Compute the 2 arcs orientation
00112         if (VectAngle.y() > 0)
00113         {       // Angle entre 0 et PI
00114                 Angle= acos(VectAngle.x());
00115                 MatRot.setMatRot(Z_AXIS, Angle);
00116         }
00117         else
00118         {       // Angle between 0 et -PI
00119                 Angle= -acos(VectAngle.x());
00120                 MatRot.setMatRot(Z_AXIS, Angle);
00121         }
00122 
00123         // Composition of orientation matrix and mapping matrix
00124         MatRot= m_pRepMoverInfo->m_MatrixInfo.first() * MatRot;
00125 
00126         m_Arc1.setMatrix(MatRot * m_MatArc1);
00127         m_Arc2.setMatrix(MatRot * m_MatArc2);
00128 }
00129 
00130 // Set Arcs position in concordance with mouse position
00131 void GLC_RepTrackBallMover::update()
00132 {
00133         Q_ASSERT(NULL != m_pRepMoverInfo);
00134         Q_ASSERT(!m_pRepMoverInfo->m_MatrixInfo.isEmpty());
00135         const GLC_Matrix4x4 matrix(m_pRepMoverInfo->m_MatrixInfo.first());
00136         m_Arc1.multMatrix(matrix);
00137         m_Arc2.multMatrix(matrix);
00138 }
00139 
00140 // overload function setColor(color);
00141 void GLC_RepTrackBallMover::setMainColor(const QColor& color)
00142 {
00143         GLC_RepMover::setMainColor(color);
00144         m_MainCircle.setWireColor(GLC_RepMover::m_MainColor);
00145         m_Arc1.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor);
00146         m_Arc2.geomAt(0)->setWireColor(GLC_RepMover::m_MainColor);
00147 }
00148 
00150 // OpenGL Functions
00152 
00153 // Virtual interface for OpenGL Geometry set up.
00154 void GLC_RepTrackBallMover::glDraw()
00155 {
00156         computeRadius();
00157         const double aspectRatio= static_cast<double>(m_pViewport->viewHSize())/static_cast<double>(m_pViewport->viewVSize());
00158 
00159         // orbit circle must be shown
00160         glDisable(GL_DEPTH_TEST);
00161 
00162         GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
00163         GLC_Context::current()->glcPushMatrix();
00164         GLC_Context::current()->glcLoadIdentity();
00165         GLC_Context::current()->glcOrtho(aspectRatio * -1.0 ,aspectRatio * 1.0 ,-1.0 ,1.0 ,-1.0 ,1.0);
00166         GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);
00167         GLC_Context::current()->glcPushMatrix();
00168         GLC_Context::current()->glcLoadIdentity();
00169 
00170         glDisable(GL_BLEND);
00171         m_RenderProperties.setRenderingFlag(glc::WireRenderFlag);
00172         // Display arcs
00173         m_Arc1.render(glc::WireRenderFlag);
00174         m_Arc2.render(glc::WireRenderFlag);
00175         // Display base class (Main circle)
00176         m_MainCircle.render(m_RenderProperties);
00177 
00178     glEnable(GL_BLEND);
00179     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00180         m_RenderProperties.setRenderingFlag(glc::TransparentRenderFlag);
00181         // Display arcs
00182         m_Arc1.render(glc::TransparentRenderFlag);
00183         m_Arc2.render(glc::TransparentRenderFlag);
00184         // Display base class (Main circle)
00185         m_MainCircle.render(m_RenderProperties);
00186 
00187         GLC_Context::current()->glcPopMatrix();
00188         GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
00189         GLC_Context::current()->glcPopMatrix();
00190         GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);
00191 
00192 }
00193 
00195 // Private services Functions
00197 
00198 // Compute trackball radius
00199 void GLC_RepTrackBallMover::computeRadius()
00200 {
00201         int nRayonSph;
00202         const double winHSize= static_cast<double>(m_pViewport->viewHSize());
00203         const double winVSize= static_cast<double>(m_pViewport->viewVSize());
00204 
00205         if (winHSize > winVSize)
00206         {
00207                 nRayonSph = static_cast<int>(m_Ratio * winVSize / 2.0);
00208         }
00209         else
00210         {
00211                 nRayonSph = static_cast<int>(m_Ratio * winHSize / 2.0);
00212         }
00213 
00214         // Compute the length of camera's field of view
00215         const double ChampsVision = 2.0;
00216 
00217         // the side of camera's square is mapped on Vertical length of window
00218         // Circle radius in OpenGL unit = Radius(Pixel) * (dimend GL / dimens Pixel)
00219         const double RayonSph= fabs((static_cast<double>(nRayonSph) * ChampsVision / winVSize));
00220 
00221         if ((!qFuzzyCompare(RayonSph, 0.0) && !qFuzzyCompare(RayonSph - m_Radius, 0.0)) || (RayonSph < 2.0))
00222         {
00223                 // Main circle radius
00224                 m_MainCircle.setRadius(RayonSph);
00225 
00226                 GLC_Circle* pCircle;
00227                 // Arc 1 radius
00228                 pCircle= static_cast<GLC_Circle*>(m_Arc1.geomAt(0));
00229                 pCircle->setRadius(RayonSph);
00230                 // Arc 2 radius
00231                 pCircle= static_cast<GLC_Circle*>(m_Arc2.geomAt(0));
00232                 pCircle->setRadius(RayonSph);
00233         }
00234 
00235 }

SourceForge.net Logo

©2005-2011 Laurent Ribon