Camera.cc

Go to the documentation of this file.
00001 #include <gra/camera/Camera.h>
00002 #include <gra/camera/OrthoProj.h>
00003 #include <assert.h>
00004 
00005 using namespace gra;
00006 
00007 Camera::Camera(AutoPtr<Projection> * pAP)
00008     : _pTrMat(NULL), _pAProjection(pAP)
00009 {
00010     assert(_pAProjection);
00011     _pAProjection->registerReferer(this);
00012     _pProjection = _pAProjection->origObject();
00013     assert(_pProjection);
00014 }
00015 
00016 Camera::Camera()
00017     : _pTrMat(NULL), _pAProjection(NULL)
00018 {
00019     _pAProjection = new AutoPtr<Projection>(new OrthoProj(-1.0, 1.0,
00020                                                           -1.0, 1.0,
00021                                                           -1.0, 1.0));
00022     _pAProjection->registerReferer(this);
00023     _pProjection = _pAProjection->origObject();
00024     assert(_pProjection);
00025 }
00026 
00027 Camera::Camera(const Camera& src)
00028     : _pTrMat(NULL)
00029 {
00030     assert(src._pProjection);
00031     _pProjection = src._pProjection->clone();
00032     _pAProjection = new AutoPtr<Projection>(_pProjection);
00033     _pAProjection->registerReferer(this);
00034 
00035     if (src._pTrMat) _pTrMat = new Matrix4(*(src._pTrMat));
00036 }
00037 
00038 Camera::~Camera()
00039 {
00040     if (_pTrMat) delete _pTrMat;
00041     (void) AutoPtr<Projection>::destroy(_pAProjection, this);
00042 }
00043 
00044 void Camera::setTransform(const Matrix4& trMat)
00045 {
00046     if (_pTrMat) _pTrMat->set(trMat);
00047     else _pTrMat = new Matrix4(trMat);
00048 }
00049 
00050 void Camera::unsetTransform()
00051 {
00052     if (_pTrMat) { delete _pTrMat; _pTrMat = NULL; }
00053 }
00054 
00055 void Camera::rotateX(float a)
00056 {
00057     Matrix4 trMat;
00058     trMat.rotX(a);
00059     if (_pTrMat) _pTrMat->mul(trMat, *_pTrMat);
00060     else _pTrMat = new Matrix4(trMat);
00061 }
00062 
00063 void Camera::rotateY(float a)
00064 {
00065     Matrix4 trMat;
00066     trMat.rotY(a);
00067     if (_pTrMat) _pTrMat->mul(trMat, *_pTrMat);
00068     else _pTrMat = new Matrix4(trMat);
00069 }
00070 
00071 void Camera::rotateZ(float a)
00072 {
00073     Matrix4 trMat;
00074     trMat.rotZ(a);
00075     if (_pTrMat) _pTrMat->mul(trMat, *_pTrMat);
00076     else _pTrMat = new Matrix4(trMat);
00077 }
00078 
00079 void Camera::rotate(float a, const Vector3& axis)
00080 {
00081     Matrix4 trMat;
00082     trMat.rotationGL(a, axis);
00083     if (_pTrMat) _pTrMat->mul(trMat, *_pTrMat);
00084     else _pTrMat = new Matrix4(trMat);
00085 }
00086 
00087 void Camera::translate(float x, float y, float z)
00088 {
00089     Matrix4 trMat;
00090     trMat.setScaleTranslate(1, x, y, z);
00091     if (_pTrMat) _pTrMat->mul(trMat, *_pTrMat);
00092     else _pTrMat = new Matrix4(trMat);
00093 }
00094 
00095 bool Camera::isTransformed(Matrix4* pTrMat) const
00096 {
00097     if (_pTrMat) {
00098         if (pTrMat) pTrMat->set(*_pTrMat);
00099         return true;
00100     } else 
00101         return false;
00102 }
00103 
00104 void Camera::setProjection(AutoPtr<Projection> * pProj)
00105 {
00106     assert(pProj);
00107     AutoPtr<Projection>::destroy(_pAProjection, this);
00108     _pAProjection = pProj;
00109     _pAProjection->registerReferer(this);
00110     _pProjection = _pAProjection->origObject();
00111     assert(_pProjection);
00112 }
00113 
00114 Vector2 Camera::getPixelSize(unsigned resX, unsigned resY) const
00115 {
00116     return Vector2((_pProjection->getRightPlane() - _pProjection->getLeftPlane()) / resX,
00117                    (_pProjection->getTopPlane() - _pProjection->getBottomPlane()) / resY);
00118 }
00119 
00120 void Camera::getProjectionPlane(Vector3& ll,
00121                                 Vector3& ul,
00122                                 Vector3& ur,
00123                                 Vector3& lr) const
00124 {
00125     _pProjection->getProjectionArea(ll, ul, ur, lr);
00126     if (_pTrMat) {
00127         _pTrMat->transform(ll);
00128         _pTrMat->transform(ul);
00129         _pTrMat->transform(ur);
00130         _pTrMat->transform(lr);
00131     }
00132 }
00133 
00134 Vector2 Camera::mapPixelToProjPlane(unsigned    posX,
00135                                     unsigned    posY,
00136                                     unsigned    resX,
00137                                     unsigned    resY,
00138                                     PixelSample sample) const
00139 {
00140     double xSize =
00141         (_pProjection->getRightPlane() - _pProjection->getLeftPlane()) / resX;
00142     double ySize =
00143         (_pProjection->getTopPlane() - _pProjection->getBottomPlane()) / resY;
00144 
00145     Vector2 ret(xSize * posX, ySize * posY);
00146 
00147     switch (sample) {
00148     case PS_CENTROID:
00149         ret.x += .5 * xSize;
00150         ret.y += .5 * ySize;
00151         break;
00152     case PS_UPPER_LEFT_CORNER:
00153         ret.y += ySize;
00154         break;
00155     case PS_UPPER_RIGHT_CORNER:
00156         ret.x += xSize;
00157         ret.y += ySize;
00158         break;
00159     case PS_LOWER_RIGHT_CORNER:
00160         ret.x += xSize;
00161         break;
00162     case PS_LOWER_LEFT_CORNER:
00163         break;
00164     case PS_RANDOM:
00165         ret.x += ESG_DBL_RAND * xSize;
00166         ret.x += ESG_DBL_RAND * ySize;
00167         break;
00168     default:
00169         break;
00170     }
00171 
00172     return ret;
00173 }
00174 
00175 Vector3 Camera::getProjectionDirection(const Vector2& point)
00176 {
00177     Vector3 dir = _pProjection->getProjectionDirection(point);
00178     if (_pTrMat) {
00179         Matrix3 rMat;
00180         _pTrMat->get(rMat);
00181         rMat.transform(dir);
00182     }
00183     return dir;
00184 }
00185 
00186 Vector3 Camera::getDirection()
00187 {
00188     Vector3 dir(0.0, 0.0, -1.0);
00189     if (_pTrMat) {
00190         Matrix3 rMat;
00191         _pTrMat->get(rMat);
00192         rMat.transform(dir);
00193     }
00194     return dir;
00195 }
00196 
00197 Vector3 Camera::getZenith()
00198 {
00199     Vector3 zenith(0.0, 1.0, 0.0);
00200     if (_pTrMat) {
00201         Matrix3 rMat;
00202         _pTrMat->get(rMat);
00203         rMat.transform(zenith);
00204     }
00205     return zenith;
00206 }
00207 
00208 Vector2 Camera::project(const Vector3& point) const
00209 {
00210     if (_pTrMat) { // transform @point to local coord. system
00211         Matrix3 rMat;
00212         Vector3 tVec, sVec, p;
00213         _pTrMat->get(rMat, tVec, sVec);
00214         ESG_INVERSE_TR_POINT(rMat, tVec, sVec, point, p);
00215         Vector3 v(_pProjection->project(p)); // apply projection matrix
00216         return Vector2(v.x - _pProjection->getLeftPlane(),
00217                        v.y - _pProjection->getBottomPlane()); // project to plane end return
00218     } else {
00219         Vector3 v(_pProjection->project(point)); // apply projection matrix
00220         return Vector2(v.x - _pProjection->getLeftPlane(),
00221                        v.y - _pProjection->getBottomPlane()); // project to plane end return
00222     }
00223 }
00224 
00225 bool Camera::projectAndClip(const Vector3& point, Vector2* res) const
00226 {
00227     Vector3 v;
00228     
00229     if (_pTrMat) { // transform @point to local coord. system
00230         Matrix3 rMat;
00231         Vector3 tVec, sVec, p;
00232         _pTrMat->get(rMat, tVec, sVec);
00233         ESG_INVERSE_TR_POINT(rMat, tVec, sVec, point, p);
00234         bool in = _pProjection->projectAndClip(p, &v);
00235         if (in && res) 
00236             res->set(v.x - _pProjection->getLeftPlane(),
00237                      v.y - _pProjection->getBottomPlane());
00238         return in;
00239     } else {
00240         bool in = _pProjection->projectAndClip(point, &v);
00241         if (in && res) 
00242             res->set(v.x - _pProjection->getLeftPlane(),
00243                      v.y - _pProjection->getBottomPlane());
00244         return in;
00245     }
00246 }

Generated on Tue Nov 21 15:11:42 2006 for gra by  doxygen 1.4.6