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