glc_reptrackballmover.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
00085
00086
00087 GLC_RepMover* GLC_RepTrackBallMover::clone() const
00088 {
00089 return new GLC_RepTrackBallMover(*this);
00090 }
00091
00093
00095
00096
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
00111 if (VectAngle.y() > 0)
00112 {
00113 Angle= acos(VectAngle.x());
00114 MatRot.setMatRot(Z_AXIS, Angle);
00115 }
00116 else
00117 {
00118 Angle= -acos(VectAngle.x());
00119 MatRot.setMatRot(Z_AXIS, Angle);
00120 }
00121
00122
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
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
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
00151
00152
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
00159 GLboolean depthTest, blend;
00160 glGetBooleanv(GL_DEPTH_TEST, &depthTest);
00161 glGetBooleanv(GL_BLEND, &blend);
00162
00163
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
00177 m_Arc1.render(glc::WireRenderFlag);
00178 m_Arc2.render(glc::WireRenderFlag);
00179
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
00186 m_Arc1.render(glc::TransparentRenderFlag);
00187 m_Arc2.render(glc::TransparentRenderFlag);
00188
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
00204
00205
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
00222 const double ChampsVision = 2.0;
00223
00224
00225
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
00231 m_MainCircle.setRadius(RayonSph);
00232
00233 GLC_Circle* pCircle;
00234
00235 pCircle= static_cast<GLC_Circle*>(m_Arc1.geomAt(0));
00236 pCircle->setRadius(RayonSph);
00237
00238 pCircle= static_cast<GLC_Circle*>(m_Arc2.geomAt(0));
00239 pCircle->setRadius(RayonSph);
00240 }
00241
00242 }