00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00025
00026 #include "glc_camera.h"
00027
00028 #include <QtDebug>
00029
00030 using namespace glc;
00032
00034 GLC_Camera::GLC_Camera()
00035 : GLC_Object("Camera")
00036 , m_Eye(0,0,1)
00037 , m_Target()
00038 , m_VectUp(Y_AXIS)
00039 , m_ModelViewMatrix()
00040 , m_DefaultVectUp(Y_AXIS)
00041 {
00042
00043 }
00044
00045 GLC_Camera::GLC_Camera(const GLC_Point3d &Eye, const GLC_Point3d &Target, const GLC_Vector3d &Up)
00046 : GLC_Object("Camera")
00047 , m_Eye()
00048 , m_Target()
00049 , m_VectUp()
00050 , m_ModelViewMatrix()
00051 , m_DefaultVectUp(Y_AXIS)
00052 {
00053 setCam(Eye, Target, Up);
00054 createMatComp();
00055 }
00056
00057
00058 GLC_Camera::GLC_Camera(const GLC_Camera& cam)
00059 : GLC_Object(cam)
00060 , m_Eye(cam.m_Eye)
00061 , m_Target(cam.m_Target)
00062 , m_VectUp(cam.m_VectUp)
00063 , m_ModelViewMatrix(cam.m_ModelViewMatrix)
00064 , m_DefaultVectUp(cam.m_DefaultVectUp)
00065 {
00066
00067 }
00068
00070
00072
00073
00074 bool GLC_Camera::operator==(const GLC_Camera& cam) const
00075 {
00076 return (m_Eye == cam.m_Eye) && (m_Target == cam.m_Target)
00077 && (m_VectUp == cam.m_VectUp) && (m_DefaultVectUp == cam.m_DefaultVectUp);
00078 }
00079
00080
00082
00084 GLC_Camera& GLC_Camera::orbit(GLC_Vector3d VectOldPoss, GLC_Vector3d VectCurPoss)
00085 {
00086
00087 GLC_Matrix4x4 invMat(m_ModelViewMatrix);
00088 invMat.invert();
00089 VectOldPoss= invMat * VectOldPoss;
00090 VectCurPoss= invMat * VectCurPoss;
00091
00092
00093 const GLC_Vector3d VectAxeRot(VectCurPoss ^ VectOldPoss);
00094
00095 if (!VectAxeRot.isNull())
00096 {
00097 const double Angle= acos(VectCurPoss * VectOldPoss);
00098 const GLC_Matrix4x4 MatOrbit(VectAxeRot, Angle);
00099
00100
00101 m_Eye= (MatOrbit * (m_Eye - m_Target)) + m_Target;
00102 m_VectUp= MatOrbit * m_VectUp;
00103 createMatComp();
00104 }
00105
00106 return *this;
00107 }
00108
00109 GLC_Camera& GLC_Camera::pan(GLC_Vector3d VectDep)
00110 {
00111
00112 GLC_Matrix4x4 invMat(m_ModelViewMatrix);
00113 invMat.invert();
00114 VectDep= invMat * VectDep;
00115
00116
00117 m_Eye= m_Eye + VectDep;
00118 m_Target= m_Target + VectDep;
00119
00120 return *this;
00121 }
00122
00123 GLC_Camera& GLC_Camera::zoom(double factor)
00124 {
00125 Q_ASSERT(factor > 0);
00126
00127 GLC_Vector3d VectCam(m_Eye - m_Target);
00128
00129
00130 const double Norme= VectCam.length() * 1 / factor;
00131 VectCam.setLength(Norme);
00132
00133 m_Eye= VectCam + m_Target;
00134
00135 return *this;
00136 }
00137
00138
00139 GLC_Camera& GLC_Camera::move(const GLC_Matrix4x4 &MatMove)
00140 {
00141 m_Eye= MatMove * m_Eye;
00142 m_Target= MatMove * m_Target;
00143 m_VectUp= MatMove.rotationMatrix() * m_VectUp;
00144 createMatComp();
00145
00146 return *this;
00147 }
00148
00149
00150 GLC_Camera& GLC_Camera::rotateAround(const GLC_Vector3d& axis, const double& angle, const GLC_Point3d& point)
00151 {
00152 const GLC_Matrix4x4 rotationMatrix(axis, angle);
00153 translate(-point);
00154 move(rotationMatrix);
00155 translate(point);
00156
00157 return *this;
00158 }
00159
00160
00161 GLC_Camera& GLC_Camera::rotateAroundTarget(const GLC_Vector3d& axis, const double& angle)
00162 {
00163 GLC_Point3d target(m_Target);
00164 rotateAround(axis, angle, target);
00165
00166 return *this;
00167 }
00168
00169 GLC_Camera& GLC_Camera::translate(const GLC_Vector3d &VectTrans)
00170 {
00171 m_Eye= m_Eye + VectTrans;
00172 m_Target= m_Target + VectTrans;
00173
00174 return *this;
00175 }
00176
00177 GLC_Camera& GLC_Camera::setEyeCam(const GLC_Point3d &Eye)
00178 {
00179
00180 GLC_Vector3d VectOldCam(m_Eye - m_Target);
00181
00182 GLC_Vector3d VectCam(Eye - m_Target);
00183 if ( !(VectOldCam - VectCam).isNull() )
00184 {
00185 VectOldCam.setLength(1);
00186 VectCam.setLength(1);
00187 const double Angle= acos(VectOldCam * VectCam);
00188 if ( !qFuzzyCompare(Angle, 0.0) && !qFuzzyCompare(PI - Angle, 0.0))
00189 {
00190 const GLC_Vector3d VectAxeRot(VectOldCam ^ VectCam);
00191 const GLC_Matrix4x4 MatRot(VectAxeRot, Angle);
00192 m_VectUp= MatRot * m_VectUp;
00193 }
00194 else
00195 {
00196 if ( qFuzzyCompare(PI - Angle, 0.0))
00197 {
00198 m_VectUp.invert();
00199 }
00200 }
00201
00202 setCam(Eye, m_Target, m_VectUp);
00203 }
00204
00205 return *this;
00206 }
00207
00208 GLC_Camera& GLC_Camera::setTargetCam(const GLC_Point3d &Target)
00209 {
00210
00211 GLC_Vector3d VectOldCam(m_Eye - m_Target);
00212
00213 GLC_Vector3d VectCam(m_Eye - Target);
00214 if ( !(VectOldCam - VectCam).isNull() )
00215 {
00216 VectOldCam.setLength(1);
00217 VectCam.setLength(1);
00218 const double Angle= acos(VectOldCam * VectCam);
00219 if ( !qFuzzyCompare(Angle, 0.0) && !qFuzzyCompare(PI - Angle, 0.0))
00220 {
00221 const GLC_Vector3d VectAxeRot(VectOldCam ^ VectCam);
00222 const GLC_Matrix4x4 MatRot(VectAxeRot, Angle);
00223 m_VectUp= MatRot * m_VectUp;
00224 }
00225 else
00226 {
00227 if ( qFuzzyCompare(PI - Angle, 0.0))
00228 {
00229 m_VectUp.invert();
00230 }
00231 }
00232
00233 setCam(m_Eye, Target, m_VectUp);
00234 }
00235
00236 return *this;
00237 }
00238
00239 GLC_Camera& GLC_Camera::setUpCam(const GLC_Vector3d &Up)
00240 {
00241 if ( !(m_VectUp - Up).isNull() )
00242 {
00243 if (!qFuzzyCompare(forward().angleWithVect(Up), 0.0))
00244 {
00245 setCam(m_Eye, m_Target, Up);
00246 }
00247 }
00248
00249 return *this;
00250 }
00251
00252 GLC_Camera& GLC_Camera::setCam(GLC_Point3d Eye, GLC_Point3d Target, GLC_Vector3d Up)
00253 {
00254 Up.setLength(1);
00255
00256 const GLC_Vector3d VectCam((Eye - Target).setLength(1));
00257 const double Angle= acos(VectCam * Up);
00258
00259
00260
00261
00262
00263
00264 if ( !qFuzzyCompare(Angle - (PI / 2), 0.0))
00265 {
00266 const GLC_Vector3d AxeRot(VectCam ^ Up);
00267 GLC_Matrix4x4 MatRot(AxeRot, PI / 2);
00268 Up= MatRot * VectCam;
00269 }
00270
00271 m_Eye= Eye;
00272 m_Target= Target;
00273 m_VectUp= Up;
00274 createMatComp();
00275
00276 return *this;
00277 }
00278
00280 GLC_Camera& GLC_Camera::setCam(const GLC_Camera& cam)
00281 {
00282 m_Eye= cam.m_Eye;
00283 m_Target= cam.m_Target;
00284 m_VectUp= cam.m_VectUp;
00285 m_ModelViewMatrix= cam.m_ModelViewMatrix;
00286
00287 return *this;
00288 }
00289
00290
00291 GLC_Camera& GLC_Camera::setDistEyeTarget(double Longueur)
00292 {
00293 GLC_Vector3d VectCam(forward());
00294 VectCam.setLength(Longueur);
00295 m_Eye= m_Target - VectCam;
00296
00297 return *this;
00298 }
00299 GLC_Camera& GLC_Camera::setDistTargetEye(double Longueur)
00300 {
00301 GLC_Vector3d VectCam(forward());
00302 VectCam.setLength(Longueur);
00303 m_Target= m_Eye + VectCam;
00304
00305 return *this;
00306 }
00307
00308
00309 GLC_Camera &GLC_Camera::operator=(const GLC_Camera& cam)
00310 {
00311 GLC_Object::operator=(cam);
00312 m_Eye= cam.m_Eye;
00313 m_Target= cam.m_Target;
00314 m_VectUp= cam.m_VectUp;
00315 m_ModelViewMatrix= cam.m_ModelViewMatrix;
00316 m_DefaultVectUp= cam.m_DefaultVectUp;
00317
00318 return *this;
00319 }
00320
00321 bool GLC_Camera::isAlmostEqualTo(const GLC_Camera& cam, const double distanceAccuracy) const
00322 {
00323 GLC_Vector3d incident1 = m_Target - m_Eye;
00324 GLC_Vector3d incident2 = cam.m_Target - cam.m_Eye;
00325
00326 double allowedGap = incident1.length() * distanceAccuracy;
00327 GLC_Point3d left1 = incident1 ^ m_VectUp;
00328 GLC_Point3d left2 = incident2 ^ cam.m_VectUp;
00329
00330 return ((m_Eye - cam.m_Eye).length() < allowedGap ) && ( (m_Target - cam.m_Target).length() < allowedGap)
00331 && ((left1 - left2).length() < allowedGap) ;
00332 }
00333
00334
00335 GLC_Camera GLC_Camera::frontView() const
00336 {
00337 GLC_Vector3d eye;
00338
00339 if (m_DefaultVectUp == glc::Z_AXIS)
00340 {
00341 eye.setVect(0.0, -1.0, 0.0);
00342 }
00343 else
00344 {
00345 eye.setVect(0.0, 0.0, 1.0);
00346 }
00347 eye= eye + m_Target;
00348
00349 GLC_Camera newCam(eye, m_Target, m_DefaultVectUp);
00350 newCam.setDistEyeTarget(distEyeTarget());
00351 newCam.setDefaultUpVector(m_DefaultVectUp);
00352 return newCam;
00353 }
00354
00355
00356 GLC_Camera GLC_Camera::rearView() const
00357 {
00358 return frontView().rotateAroundTarget(m_DefaultVectUp, glc::PI);
00359 }
00360
00361
00362 GLC_Camera GLC_Camera::rightView() const
00363 {
00364 return frontView().rotateAroundTarget(m_DefaultVectUp, glc::PI / 2.0);}
00365
00366
00367 GLC_Camera GLC_Camera::leftView() const
00368 {
00369 return frontView().rotateAroundTarget(m_DefaultVectUp, - glc::PI / 2.0);
00370 }
00371
00372
00373 GLC_Camera GLC_Camera::topView() const
00374 {
00375 GLC_Vector3d eye= m_DefaultVectUp;
00376 eye= eye + m_Target;
00377 GLC_Vector3d up;
00378
00379 if (m_DefaultVectUp == glc::Y_AXIS)
00380 {
00381 up.setVect(0.0, 0.0, -1.0);
00382 }
00383 else
00384 {
00385 up.setVect(0.0, 1.0, 0.0);
00386 }
00387
00388 GLC_Camera newCam(eye, m_Target, up);
00389 newCam.setDistEyeTarget(distEyeTarget());
00390 newCam.setDefaultUpVector(m_DefaultVectUp);
00391
00392 return newCam;
00393 }
00394
00395
00396 GLC_Camera GLC_Camera::bottomView() const
00397 {
00398 GLC_Camera newCam(topView());
00399 newCam.rotateAroundTarget(newCam.upVector(), glc::PI);
00400
00401 return newCam;
00402 }
00403
00404
00405 GLC_Camera GLC_Camera::isoView() const
00406 {
00407 GLC_Vector3d eye;
00408 if (m_DefaultVectUp == glc::Z_AXIS)
00409 {
00410 eye.setVect(-1.0, -1.0, 1.0);
00411 }
00412 else if (m_DefaultVectUp == glc::Y_AXIS)
00413 {
00414 eye.setVect(-1.0, 1.0, 1.0);
00415 }
00416 else
00417 {
00418 eye.setVect(1.0, 1.0, 1.0);
00419 }
00420
00421 eye= eye + m_Target;
00422
00423 GLC_Camera newCam(eye, m_Target, m_DefaultVectUp);
00424 newCam.setDistEyeTarget(distEyeTarget());
00425 newCam.setDefaultUpVector(m_DefaultVectUp);
00426 return newCam;
00427 }
00428
00430
00432 void GLC_Camera::glExecute()
00433 {
00434 gluLookAt(m_Eye.x(), m_Eye.y(), m_Eye.z(),
00435 m_Target.x(), m_Target.y(), m_Target.z(),
00436 m_VectUp.x(), m_VectUp.y(), m_VectUp.z());
00437 }
00438
00440
00442
00443 void GLC_Camera::createMatComp(void)
00444 {
00445 const GLC_Vector3d forward((m_Target - m_Eye).normalize());
00446 const GLC_Vector3d side((forward ^ m_VectUp).normalize());
00447
00448
00449 m_ModelViewMatrix.setData()[0]= side.x();
00450 m_ModelViewMatrix.setData()[4]= side.y();
00451 m_ModelViewMatrix.setData()[8]= side.z();
00452 m_ModelViewMatrix.setData()[12]= 0.0;
00453
00454
00455 m_ModelViewMatrix.setData()[1]= m_VectUp.x();
00456 m_ModelViewMatrix.setData()[5]= m_VectUp.y();
00457 m_ModelViewMatrix.setData()[9]= m_VectUp.z();
00458 m_ModelViewMatrix.setData()[13]= 0.0;
00459
00460
00461 m_ModelViewMatrix.setData()[2]= - forward.x();
00462 m_ModelViewMatrix.setData()[6]= - forward.y();
00463 m_ModelViewMatrix.setData()[10]= - forward.z();
00464 m_ModelViewMatrix.setData()[14]= 0.0;
00465
00466 m_ModelViewMatrix.setData()[3]= 0.0;
00467 m_ModelViewMatrix.setData()[7]= 0.0;
00468 m_ModelViewMatrix.setData()[11]= 0.0;
00469 m_ModelViewMatrix.setData()[15]= 1.0;
00470
00471 }