Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgreCamera.cpp

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://ogre.sourceforge.net/
    00006
    00007 Copyright © 2000-2002 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025 #include "OgreStableHeaders.h"
    00026 #include "OgreCamera.h"
    00027
    00028 #include "OgreMath.h"
    00029 #include "OgreMatrix3.h"
    00030 #include "OgreSceneManager.h"
    00031 #include "OgreSceneNode.h"
    00032 #include "OgreAxisAlignedBox.h"
    00033 #include "OgreSphere.h"
    00034 #include "OgreLogManager.h"
    00035 #include "OgreException.h"
    00036 #include "OgreRoot.h"
    00037 #include "OgreRenderSystem.h"
    00038
    00039 namespace Ogre {
    00040
    00041     String Camera::msMovableType = "Camera";
    00042     //-----------------------------------------------------------------------
    00043     Camera::Camera( const String& name, SceneManager* sm)
    00044         : mName( name )
    00045     {
    00046         // Init camera location & direction
    00047
    00048         // Locate at (0,0,0)
    00049         mPosition.x = mPosition.y = mPosition.z = 0;
    00050         // Point down -Z axis
    00051         mOrientation = Quaternion::IDENTITY;
    00052
    00053
    00054         // Reasonable defaults to camera params
    00055         mFOVy = Radian(Math::PI/4.0);
    00056         mNearDist = 100.0f;
    00057         mFarDist = 100000.0f;
    00058         mAspect = 1.33333333333333f;
    00059         mProjType = PT_PERSPECTIVE;
    00060         mSceneDetail = SDL_SOLID;
    00061         setFixedYawAxis(true);    // Default to fixed yaw, like freelook since most people expect this
    00062
    00063         invalidateFrustum();
    00064         invalidateView();
    00065
    00066         // Init matrices
    00067         mViewMatrix = Matrix4::ZERO;
    00068         mProjMatrix = Matrix4::ZERO;
    00069
    00070         mParentNode = 0;
    00071
    00072         // Record SceneManager
    00073         mSceneMgr = sm;
    00074
    00075         // Init no tracking
    00076         mAutoTrackTarget = 0;
    00077
    00078         // Init lod
    00079         mSceneLodFactor = mSceneLodFactorInv =  1.0f;
    00080
    00081         // no reflection
    00082         mReflect = false;
    00083
    00084         mVisible = false;
    00085
    00086
    00087         mWindowSet = false;
    00088         mAutoAspectRatio = false;
    00089     }
    00090
    00091     //-----------------------------------------------------------------------
    00092     Camera::~Camera()
    00093     {
    00094         // Do nothing
    00095     }
    00096
    00097     //-----------------------------------------------------------------------
    00098     SceneManager* Camera::getSceneManager(void) const
    00099     {
    00100         return mSceneMgr;
    00101     }
    00102     //-----------------------------------------------------------------------
    00103     const String& Camera::getName(void) const
    00104     {
    00105         return mName;
    00106     }
    00107
    00108
    00109     //-----------------------------------------------------------------------
    00110     void Camera::setDetailLevel(SceneDetailLevel sd)
    00111     {
    00112         mSceneDetail = sd;
    00113     }
    00114
    00115     //-----------------------------------------------------------------------
    00116     SceneDetailLevel Camera::getDetailLevel(void) const
    00117     {
    00118         return mSceneDetail;
    00119     }
    00120
    00121     //-----------------------------------------------------------------------
    00122     void Camera::setPosition(Real x, Real y, Real z)
    00123     {
    00124         mPosition.x = x;
    00125         mPosition.y = y;
    00126         mPosition.z = z;
    00127         invalidateView();
    00128     }
    00129
    00130     //-----------------------------------------------------------------------
    00131     void Camera::setPosition(const Vector3& vec)
    00132     {
    00133         mPosition = vec;
    00134         invalidateView();
    00135     }
    00136
    00137     //-----------------------------------------------------------------------
    00138     const Vector3& Camera::getPosition(void) const
    00139     {
    00140         return mPosition;
    00141     }
    00142
    00143     //-----------------------------------------------------------------------
    00144     void Camera::move(const Vector3& vec)
    00145     {
    00146         mPosition = mPosition + vec;
    00147         invalidateView();
    00148     }
    00149
    00150     //-----------------------------------------------------------------------
    00151     void Camera::moveRelative(const Vector3& vec)
    00152     {
    00153         // Transform the axes of the relative vector by camera's local axes
    00154         Vector3 trans = mOrientation * vec;
    00155
    00156         mPosition = mPosition + trans;
    00157         invalidateView();
    00158     }
    00159
    00160     //-----------------------------------------------------------------------
    00161     void Camera::setDirection(Real x, Real y, Real z)
    00162     {
    00163         setDirection(Vector3(x,y,z));
    00164     }
    00165
    00166     //-----------------------------------------------------------------------
    00167     void Camera::setDirection(const Vector3& vec)
    00168     {
    00169         // Do nothing if given a zero vector
    00170         // (Replaced assert since this could happen with auto tracking camera and
    00171         //  camera passes through the lookAt point)
    00172         if (vec == Vector3::ZERO) return;
    00173
    00174         // Remember, camera points down -Z of local axes!
    00175         // Therefore reverse direction of direction vector before determining local Z
    00176         Vector3 zAdjustVec = -vec;
    00177         zAdjustVec.normalise();
    00178
    00179
    00180         if( mYawFixed )
    00181         {
    00182             Vector3 xVec = mYawFixedAxis.crossProduct( zAdjustVec );
    00183             xVec.normalise();
    00184
    00185             Vector3 yVec = zAdjustVec.crossProduct( xVec );
    00186             yVec.normalise();
    00187
    00188             mOrientation.FromAxes( xVec, yVec, zAdjustVec );
    00189         }
    00190         else
    00191         {
    00192
    00193             // Get axes from current quaternion
    00194             Vector3 axes[3];
    00195             updateView();
    00196             mDerivedOrientation.ToAxes(axes);
    00197             Quaternion rotQuat;
    00198             if (-zAdjustVec == axes[2])
    00199             {
    00200                 // Oops, a 180 degree turn (infinite possible rotation axes)
    00201                 // Default to yaw i.e. use current UP
    00202                 rotQuat.FromAngleAxis(Radian(Math::PI), axes[1]);
    00203             }
    00204             else
    00205             {
    00206                 // Derive shortest arc to new direction
    00207                 rotQuat = axes[2].getRotationTo(zAdjustVec);
    00208
    00209             }
    00210             mOrientation = rotQuat * mOrientation;
    00211         }
    00212
    00213
    00214         // TODO If we have a fixed yaw axis, we mustn't break it by using the
    00215         // shortest arc because this will sometimes cause a relative yaw
    00216         // which will tip the camera
    00217
    00218         invalidateView();
    00219
    00220     }
    00221
    00222     //-----------------------------------------------------------------------
    00223     Vector3 Camera::getDirection(void) const
    00224     {
    00225         // Direction points down -Z by default
    00226         return mOrientation * -Vector3::UNIT_Z;
    00227     }
    00228
    00229     //-----------------------------------------------------------------------
    00230     Vector3 Camera::getUp(void) const
    00231     {
    00232         return mOrientation * Vector3::UNIT_Y;
    00233     }
    00234
    00235     //-----------------------------------------------------------------------
    00236     Vector3 Camera::getRight(void) const
    00237     {
    00238         return mOrientation * Vector3::UNIT_X;
    00239     }
    00240
    00241     //-----------------------------------------------------------------------
    00242     void Camera::lookAt(const Vector3& targetPoint)
    00243     {
    00244         updateView();
    00245         this->setDirection(targetPoint - mDerivedPosition);
    00246     }
    00247
    00248     //-----------------------------------------------------------------------
    00249     void Camera::lookAt( Real x, Real y, Real z )
    00250     {
    00251         Vector3 vTemp( x, y, z );
    00252         this->lookAt(vTemp);
    00253     }
    00254
    00255     //-----------------------------------------------------------------------
    00256     void Camera::roll(const Radian& angle)
    00257     {
    00258         // Rotate around local Z axis
    00259         Vector3 zAxis = mOrientation * Vector3::UNIT_Z;
    00260         rotate(zAxis, angle);
    00261
    00262         invalidateView();
    00263     }
    00264
    00265     //-----------------------------------------------------------------------
    00266     void Camera::yaw(const Radian& angle)
    00267     {
    00268         Vector3 yAxis;
    00269
    00270         if (mYawFixed)
    00271         {
    00272             // Rotate around fixed yaw axis
    00273             yAxis = mYawFixedAxis;
    00274         }
    00275         else
    00276         {
    00277             // Rotate around local Y axis
    00278             yAxis = mOrientation * Vector3::UNIT_Y;
    00279         }
    00280
    00281         rotate(yAxis, angle);
    00282
    00283         invalidateView();
    00284     }
    00285
    00286     //-----------------------------------------------------------------------
    00287     void Camera::pitch(const Radian& angle)
    00288     {
    00289         // Rotate around local X axis
    00290         Vector3 xAxis = mOrientation * Vector3::UNIT_X;
    00291         rotate(xAxis, angle);
    00292
    00293         invalidateView();
    00294
    00295     }
    00296
    00297     //-----------------------------------------------------------------------
    00298     void Camera::rotate(const Vector3& axis, const Radian& angle)
    00299     {
    00300         Quaternion q;
    00301         q.FromAngleAxis(angle,axis);
    00302         rotate(q);
    00303     }
    00304
    00305     //-----------------------------------------------------------------------
    00306     void Camera::rotate(const Quaternion& q)
    00307     {
    00308         // Note the order of the mult, i.e. q comes after
    00309         mOrientation = q * mOrientation;
    00310         invalidateView();
    00311
    00312     }
    00313
    00314     //-----------------------------------------------------------------------
    00315     void Camera::updateFrustum(void) const
    00316     {
    00317         Frustum::updateFrustum();
    00318         // Set the clipping planes
    00319         setWindowImpl();
    00320     }
    00321
    00322     //-----------------------------------------------------------------------
    00323     bool Camera::isViewOutOfDate(void) const
    00324     {
    00325         bool returnVal = false;
    00326         // Overridden from Frustum to use local orientation / position offsets
    00327         // Attached to node?
    00328         if (mParentNode != 0)
    00329         {
    00330             if (!mRecalcView && mParentNode->_getDerivedOrientation() == mLastParentOrientation &&
    00331                 mParentNode->_getDerivedPosition() == mLastParentPosition)
    00332             {
    00333                 returnVal = false;
    00334             }
    00335             else
    00336             {
    00337                 // Ok, we're out of date with SceneNode we're attached to
    00338                 mLastParentOrientation = mParentNode->_getDerivedOrientation();
    00339                 mLastParentPosition = mParentNode->_getDerivedPosition();
    00340                 mDerivedOrientation = mLastParentOrientation * mOrientation;
    00341                 mDerivedPosition = (mLastParentOrientation * mPosition) + mLastParentPosition;
    00342                 returnVal = true;
    00343             }
    00344         }
    00345         else
    00346         {
    00347             // Rely on own updates
    00348             mDerivedOrientation = mOrientation;
    00349             mDerivedPosition = mPosition;
    00350         }
    00351
    00352         // Deriving reflection from linked plane?
    00353         if (mReflect && mLinkedReflectPlane &&
    00354             !(mLastLinkedReflectionPlane == mLinkedReflectPlane->_getDerivedPlane()))
    00355         {
    00356             mReflectPlane = mLinkedReflectPlane->_getDerivedPlane();
    00357             mReflectMatrix = Math::buildReflectionMatrix(mReflectPlane);
    00358             mLastLinkedReflectionPlane = mLinkedReflectPlane->_getDerivedPlane();
    00359             returnVal = true;
    00360         }
    00361
    00362         return returnVal || mRecalcView;
    00363
    00364     }
    00365
    00366
    00367     //-----------------------------------------------------------------------
    00368     void Camera::updateView(void) const
    00369     {
    00370         Frustum::updateView();
    00371         setWindowImpl();
    00372
    00373     }
    00374     // -------------------------------------------------------------------
    00375     void Camera::invalidateView() const
    00376     {
    00377         mRecalcView = true;
    00378         mRecalcWindow = true;
    00379     }
    00380     // -------------------------------------------------------------------
    00381     void Camera::invalidateFrustum(void) const
    00382     {
    00383         mRecalcFrustum = true;
    00384         mRecalcWindow = true;
    00385     }
    00386     //-----------------------------------------------------------------------
    00387     void Camera::_renderScene(Viewport *vp, bool includeOverlays)
    00388     {
    00389
    00390         mSceneMgr->_renderScene(this, vp, includeOverlays);
    00391     }
    00392
    00393
    00394     //-----------------------------------------------------------------------
    00395     std::ostream& operator<<( std::ostream& o, Camera& c )
    00396     {
    00397         o << "Camera(Name='" << c.mName << "', pos=" << c.mPosition;
    00398         Vector3 dir(c.mOrientation*Vector3(0,0,-1));
    00399         o << ", direction=" << dir << ",near=" << c.mNearDist;
    00400         o << ", far=" << c.mFarDist << ", FOVy=" << c.mFOVy.valueDegrees();
    00401         o << ", aspect=" << c.mAspect << ", ";
    00402         o << "NearFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_NEAR] << ", ";
    00403         o << "FarFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_FAR] << ", ";
    00404         o << "LeftFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_LEFT] << ", ";
    00405         o << "RightFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_RIGHT] << ", ";
    00406         o << "TopFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_TOP] << ", ";
    00407         o << "BottomFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_BOTTOM];
    00408         o << ")";
    00409
    00410         return o;
    00411     }
    00412
    00413     //-----------------------------------------------------------------------
    00414     void Camera::setFixedYawAxis(bool useFixed, const Vector3& fixedAxis)
    00415     {
    00416         mYawFixed = useFixed;
    00417         mYawFixedAxis = fixedAxis;
    00418     }
    00419
    00420     //-----------------------------------------------------------------------
    00421     void Camera::_notifyRenderedFaces(unsigned int numfaces)
    00422     {
    00423         mVisFacesLastRender = numfaces;
    00424     }
    00425
    00426     //-----------------------------------------------------------------------
    00427     unsigned int Camera::_getNumRenderedFaces(void) const
    00428     {
    00429         return mVisFacesLastRender;
    00430     }
    00431
    00432     //-----------------------------------------------------------------------
    00433     const Quaternion& Camera::getOrientation(void) const
    00434     {
    00435         return mOrientation;
    00436     }
    00437
    00438     //-----------------------------------------------------------------------
    00439     void Camera::setOrientation(const Quaternion& q)
    00440     {
    00441         mOrientation = q;
    00442         invalidateView();
    00443     }
    00444     //-----------------------------------------------------------------------
    00445     const Quaternion& Camera::getDerivedOrientation(void) const
    00446     {
    00447         updateView();
    00448         return mDerivedOrientation;
    00449     }
    00450     //-----------------------------------------------------------------------
    00451     const Vector3& Camera::getDerivedPosition(void) const
    00452     {
    00453         updateView();
    00454         return mDerivedPosition;
    00455     }
    00456     //-----------------------------------------------------------------------
    00457     Vector3 Camera::getDerivedDirection(void) const
    00458     {
    00459         // Direction points down -Z by default
    00460         updateView();
    00461         return mDerivedOrientation * -Vector3::UNIT_Z;
    00462     }
    00463     //-----------------------------------------------------------------------
    00464     const String& Camera::getMovableType(void) const
    00465     {
    00466         return msMovableType;
    00467     }
    00468     //-----------------------------------------------------------------------
    00469     void Camera::setAutoTracking(bool enabled, SceneNode* target,
    00470         const Vector3& offset)
    00471     {
    00472         if (enabled)
    00473         {
    00474             assert (target != 0 && "target cannot be a null pointer if tracking is enabled");
    00475             mAutoTrackTarget = target;
    00476             mAutoTrackOffset = offset;
    00477         }
    00478         else
    00479         {
    00480             mAutoTrackTarget = 0;
    00481         }
    00482     }
    00483     //-----------------------------------------------------------------------
    00484     void Camera::_autoTrack(void)
    00485     {
    00486         // NB assumes that all scene nodes have been updated
    00487         if (mAutoTrackTarget)
    00488         {
    00489             lookAt(mAutoTrackTarget->_getDerivedPosition() + mAutoTrackOffset);
    00490         }
    00491     }
    00492     //-----------------------------------------------------------------------
    00493     void Camera::setLodBias(Real factor)
    00494     {
    00495         assert(factor > 0.0f && "Bias factor must be > 0!");
    00496         mSceneLodFactor = factor;
    00497         mSceneLodFactorInv = 1.0f / factor;
    00498     }
    00499     //-----------------------------------------------------------------------
    00500     Real Camera::getLodBias(void) const
    00501     {
    00502         return mSceneLodFactor;
    00503     }
    00504     //-----------------------------------------------------------------------
    00505     Real Camera::_getLodBiasInverse(void) const
    00506     {
    00507         return mSceneLodFactorInv;
    00508     }
    00509     //-----------------------------------------------------------------------
    00510     Ray Camera::getCameraToViewportRay(Real screenX, Real screenY) const
    00511     {
    00512         Real centeredScreenX = (screenX - 0.5f);
    00513         Real centeredScreenY = (0.5f - screenY);
    00514
    00515         Real normalizedSlope = Math::Tan(mFOVy / 2);
    00516         Real viewportYToWorldY = normalizedSlope * mNearDist * 2;
    00517         Real viewportXToWorldX = viewportYToWorldY * mAspect;
    00518
    00519         Vector3 rayDirection(centeredScreenX * viewportXToWorldX,
    00520             centeredScreenY * viewportYToWorldY,
    00521             -mNearDist);
    00522         rayDirection = getDerivedOrientation() * rayDirection;
    00523         rayDirection.normalise();
    00524
    00525         return Ray(getDerivedPosition(), rayDirection);
    00526     }
    00527
    00528     // -------------------------------------------------------------------
    00529     void Camera::setWindow (Real Left, Real Top, Real Right, Real Bottom)
    00530     {
    00531         mWLeft = Left;
    00532         mWTop = Top;
    00533         mWRight = Right;
    00534         mWBottom = Bottom;
    00535
    00536         mWindowSet = true;
    00537         mRecalcWindow = true;
    00538
    00539         invalidateView();
    00540     }
    00541     // -------------------------------------------------------------------
    00542     void Camera::resetWindow ()
    00543     {
    00544         mWindowSet = false;
    00545     }
    00546     // -------------------------------------------------------------------
    00547     void Camera::setWindowImpl() const
    00548     {
    00549         if (!mWindowSet || !mRecalcWindow)
    00550             return;
    00551
    00552
    00553         Radian thetaY ( mFOVy / 2.0f );
    00554         Real tanThetaY = Math::Tan(thetaY);
    00555         //Real thetaX = thetaY * mAspect;
    00556         Real tanThetaX = tanThetaY * mAspect;
    00557
    00558         Real vpTop = tanThetaY * mNearDist;
    00559         Real vpLeft = -tanThetaX * mNearDist;
    00560         Real vpWidth = -2 * vpLeft;
    00561         Real vpHeight = 2 * vpTop;
    00562
    00563         Real wvpLeft   = vpLeft + mWLeft * vpWidth;
    00564         Real wvpRight  = vpLeft + mWRight * vpWidth;
    00565         Real wvpTop    = vpTop - mWTop * vpHeight;
    00566         Real wvpBottom = vpTop - mWBottom * vpHeight;
    00567
    00568         Vector3 vp_ul (wvpLeft, wvpTop, -mNearDist);
    00569         Vector3 vp_ur (wvpRight, wvpTop, -mNearDist);
    00570         Vector3 vp_bl (wvpLeft, wvpBottom, -mNearDist);
    00571         Vector3 vp_br (wvpRight, wvpBottom, -mNearDist);
    00572
    00573         Matrix4 inv = mViewMatrix.inverse();
    00574
    00575         Vector3 vw_ul = inv * vp_ul;
    00576         Vector3 vw_ur = inv * vp_ur;
    00577         Vector3 vw_bl = inv * vp_bl;
    00578         Vector3 vw_br = inv * vp_br;
    00579
    00580         Vector3 position = getPosition();
    00581
    00582         mWindowClipPlanes.clear();
    00583         mWindowClipPlanes.push_back(Plane(position, vw_bl, vw_ul));
    00584         mWindowClipPlanes.push_back(Plane(position, vw_ul, vw_ur));
    00585         mWindowClipPlanes.push_back(Plane(position, vw_ur, vw_br));
    00586         mWindowClipPlanes.push_back(Plane(position, vw_br, vw_bl));
    00587
    00588         mRecalcWindow = false;
    00589
    00590     }
    00591     // -------------------------------------------------------------------
    00592     const std::vector<Plane>& Camera::getWindowPlanes(void) const
    00593     {
    00594         setWindowImpl();
    00595         return mWindowClipPlanes;
    00596     }
    00597     // -------------------------------------------------------------------
    00598     Real Camera::getBoundingRadius(void) const
    00599     {
    00600         // return a little bigger than the near distance
    00601         // just to keep things just outside
    00602         return mNearDist * 1.5;
    00603
    00604     }
    00605     //-----------------------------------------------------------------------
    00606     const Vector3& Camera::getPositionForViewUpdate(void) const
    00607     {
    00608         // Note no update, because we're calling this from the update!
    00609         return mDerivedPosition;
    00610     }
    00611     //-----------------------------------------------------------------------
    00612     const Quaternion& Camera::getOrientationForViewUpdate(void) const
    00613     {
    00614         return mDerivedOrientation;
    00615     }
    00616     //-----------------------------------------------------------------------
    00617     bool Camera::getAutoAspectRatio(void) const
    00618     {
    00619         return mAutoAspectRatio;
    00620     }
    00621     //-----------------------------------------------------------------------
    00622     void Camera::setAutoAspectRatio(bool autoratio)
    00623     {
    00624         mAutoAspectRatio = autoratio;
    00625     }
    00626
    00627 } // namespace Ogre

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:17 2004