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
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
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
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
00087
00088
00089 GLC_RepMover* GLC_RepTrackBallMover::clone() const
00090 {
00091 return new GLC_RepTrackBallMover(*this);
00092 }
00093
00095
00097
00098
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
00113 if (VectAngle.y() > 0)
00114 {
00115 Angle= acos(VectAngle.x());
00116 MatRot.setMatRot(Z_AXIS, Angle);
00117 }
00118 else
00119 {
00120 Angle= -acos(VectAngle.x());
00121 MatRot.setMatRot(Z_AXIS, Angle);
00122 }
00123
00124
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
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
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
00153
00154
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
00161 GLboolean depthTest, blend;
00162 glGetBooleanv(GL_DEPTH_TEST, &depthTest);
00163 glGetBooleanv(GL_BLEND, &blend);
00164
00165
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
00179 m_Arc1.render(glc::WireRenderFlag);
00180 m_Arc2.render(glc::WireRenderFlag);
00181
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
00188 m_Arc1.render(glc::TransparentRenderFlag);
00189 m_Arc2.render(glc::TransparentRenderFlag);
00190
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
00206
00207
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
00224 const double ChampsVision = 2.0;
00225
00226
00227
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
00233 m_MainCircle.setRadius(RayonSph);
00234
00235 GLC_Circle* pCircle;
00236
00237 pCircle= static_cast<GLC_Circle*>(m_Arc1.geomAt(0));
00238 pCircle->setRadius(RayonSph);
00239
00240 pCircle= static_cast<GLC_Circle*>(m_Arc2.geomAt(0));
00241 pCircle->setRadius(RayonSph);
00242 }
00243
00244 }