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 = Math::RadiansToAngleUnits(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     }
00089 
00090     //-----------------------------------------------------------------------
00091     Camera::~Camera()
00092     {
00093         // Do nothing
00094     }
00095 
00096     //-----------------------------------------------------------------------
00097     SceneManager* Camera::getSceneManager(void) const
00098     {
00099         return mSceneMgr;
00100     }
00101     //-----------------------------------------------------------------------
00102     const String& Camera::getName(void) const
00103     {
00104         return mName;
00105     }
00106 
00107 
00108     //-----------------------------------------------------------------------
00109     void Camera::setDetailLevel(SceneDetailLevel sd)
00110     {
00111         mSceneDetail = sd;
00112     }
00113 
00114     //-----------------------------------------------------------------------
00115     SceneDetailLevel Camera::getDetailLevel(void) const
00116     {
00117         return mSceneDetail;
00118     }
00119 
00120     //-----------------------------------------------------------------------
00121     void Camera::setPosition(Real x, Real y, Real z)
00122     {
00123         mPosition.x = x;
00124         mPosition.y = y;
00125         mPosition.z = z;
00126         invalidateView();
00127     }
00128 
00129     //-----------------------------------------------------------------------
00130     void Camera::setPosition(const Vector3& vec)
00131     {
00132         mPosition = vec;
00133         invalidateView();
00134     }
00135 
00136     //-----------------------------------------------------------------------
00137     const Vector3& Camera::getPosition(void) const
00138     {
00139         return mPosition;
00140     }
00141 
00142     //-----------------------------------------------------------------------
00143     void Camera::move(const Vector3& vec)
00144     {
00145         mPosition = mPosition + vec;
00146         invalidateView();
00147     }
00148 
00149     //-----------------------------------------------------------------------
00150     void Camera::moveRelative(const Vector3& vec)
00151     {
00152         // Transform the axes of the relative vector by camera's local axes
00153         Vector3 trans = mOrientation * vec;
00154 
00155         mPosition = mPosition + trans;
00156         invalidateView();
00157     }
00158 
00159     //-----------------------------------------------------------------------
00160     void Camera::setDirection(Real x, Real y, Real z)
00161     {
00162         setDirection(Vector3(x,y,z));
00163     }
00164 
00165     //-----------------------------------------------------------------------
00166     void Camera::setDirection(const Vector3& vec)
00167     {
00168         // Do nothing if given a zero vector
00169         // (Replaced assert since this could happen with auto tracking camera and
00170         //  camera passes through the lookAt point)
00171         if (vec == Vector3::ZERO) return;
00172 
00173         // Remember, camera points down -Z of local axes!
00174         // Therefore reverse direction of direction vector before determining local Z
00175         Vector3 zAdjustVec = -vec;
00176         zAdjustVec.normalise();
00177 
00178 
00179         if( mYawFixed )
00180         {
00181             Vector3 xVec = mYawFixedAxis.crossProduct( zAdjustVec );
00182             xVec.normalise();
00183 
00184             Vector3 yVec = zAdjustVec.crossProduct( xVec );
00185             yVec.normalise();
00186 
00187             mOrientation.FromAxes( xVec, yVec, zAdjustVec );
00188         }
00189         else
00190         {
00191 
00192             // Get axes from current quaternion
00193             Vector3 axes[3];
00194             updateView();
00195             mDerivedOrientation.ToAxes(axes);
00196             Quaternion rotQuat;
00197             if (-zAdjustVec == axes[2])
00198             {
00199                 // Oops, a 180 degree turn (infinite possible rotation axes)
00200                 // Default to yaw i.e. use current UP
00201                 rotQuat.FromAngleAxis(Math::PI, axes[1]);
00202             }
00203             else
00204             {
00205                 // Derive shortest arc to new direction
00206                 rotQuat = axes[2].getRotationTo(zAdjustVec);
00207 
00208             }
00209             mOrientation = rotQuat * mOrientation;
00210         }
00211 
00212 
00213         // TODO If we have a fixed yaw axis, we mustn't break it by using the
00214         // shortest arc because this will sometimes cause a relative yaw
00215         // which will tip the camera
00216 
00217         invalidateView();
00218 
00219     }
00220 
00221     //-----------------------------------------------------------------------
00222     Vector3 Camera::getDirection(void) const
00223     {
00224         // Direction points down -Z by default
00225         return mOrientation * -Vector3::UNIT_Z;
00226     }
00227 
00228     //-----------------------------------------------------------------------
00229     Vector3 Camera::getUp(void) const
00230     {
00231         return mOrientation * Vector3::UNIT_Y;
00232     }
00233 
00234     //-----------------------------------------------------------------------
00235     Vector3 Camera::getRight(void) const
00236     {
00237         return mOrientation * Vector3::UNIT_X;
00238     }
00239 
00240     //-----------------------------------------------------------------------
00241     void Camera::lookAt(const Vector3& targetPoint)
00242     {
00243 
00244         updateView();
00245         this->setDirection(targetPoint - mDerivedPosition);
00246 
00247     }
00248 
00249     //-----------------------------------------------------------------------
00250     void Camera::lookAt( Real x, Real y, Real z )
00251     {
00252         Vector3 vTemp( x, y, z );
00253         this->lookAt(vTemp);
00254 
00255     }
00256 
00257 
00258     //-----------------------------------------------------------------------
00259     void Camera::roll(Real degrees)
00260     {
00261         // Rotate around local Z axis
00262         Vector3 zAxis = mOrientation * Vector3::UNIT_Z;
00263         rotate(zAxis, degrees);
00264 
00265         invalidateView();
00266     }
00267 
00268     //-----------------------------------------------------------------------
00269     void Camera::yaw(Real degrees)
00270     {
00271         Vector3 yAxis;
00272 
00273         if (mYawFixed)
00274         {
00275             // Rotate around fixed yaw axis
00276             yAxis = mYawFixedAxis;
00277         }
00278         else
00279         {
00280             // Rotate around local Y axis
00281             yAxis = mOrientation * Vector3::UNIT_Y;
00282         }
00283 
00284         rotate(yAxis, degrees);
00285 
00286         invalidateView();
00287     }
00288 
00289     //-----------------------------------------------------------------------
00290     void Camera::pitch(Real degrees)
00291     {
00292         // Rotate around local X axis
00293         Vector3 xAxis = mOrientation * Vector3::UNIT_X;
00294         rotate(xAxis, degrees);
00295 
00296         invalidateView();
00297 
00298     }
00299 
00300     //-----------------------------------------------------------------------
00301     void Camera::rotate(const Vector3& axis, Real degrees)
00302     {
00303         Quaternion q;
00304         q.FromAngleAxis(Math::AngleUnitsToRadians(degrees),axis);
00305         rotate(q);
00306 
00307     }
00308     //-----------------------------------------------------------------------
00309     void Camera::rotate(const Quaternion& q)
00310     {
00311         // Note the order of the mult, i.e. q comes after
00312         mOrientation = q * mOrientation;
00313         invalidateView();
00314 
00315     }
00316 
00317     //-----------------------------------------------------------------------
00318     void Camera::updateFrustum(void) const
00319     {
00320         Frustum::updateFrustum();
00321         // Set the clipping planes
00322         setWindowImpl();
00323     }
00324 
00325     //-----------------------------------------------------------------------
00326     bool Camera::isViewOutOfDate(void) const
00327     {
00328         // Overridden from Frustum to use local orientation / position offsets
00329         // Attached to node?
00330         if (mParentNode != 0)
00331         {
00332             if (!mRecalcView && mParentNode->_getDerivedOrientation() == mLastParentOrientation &&
00333                 mParentNode->_getDerivedPosition() == mLastParentPosition)
00334             {
00335                 return false;
00336             }
00337             else
00338             {
00339                 // Ok, we're out of date with SceneNode we're attached to
00340                 mLastParentOrientation = mParentNode->_getDerivedOrientation();
00341                 mLastParentPosition = mParentNode->_getDerivedPosition();
00342                 mDerivedOrientation = mLastParentOrientation * mOrientation;
00343                 mDerivedPosition = (mLastParentOrientation * mPosition) + mLastParentPosition;
00344                 return true;
00345             }
00346         }
00347         else
00348         {
00349             // Rely on own updates
00350             mDerivedOrientation = mOrientation;
00351             mDerivedPosition = mPosition;
00352             return mRecalcView;
00353         }
00354     }
00355 
00356 
00357     //-----------------------------------------------------------------------
00358     void Camera::updateView(void) const
00359     {
00360         Frustum::updateView();
00361         setWindowImpl();
00362 
00363     }
00364     // -------------------------------------------------------------------
00365     void Camera::invalidateView()
00366     {
00367         mRecalcView = true;
00368         mRecalcWindow = true;
00369     }
00370     // -------------------------------------------------------------------
00371     void Camera::invalidateFrustum(void)
00372     {
00373         mRecalcFrustum = true;
00374         mRecalcWindow = true;
00375     }
00376     //-----------------------------------------------------------------------
00377     void Camera::_renderScene(Viewport *vp, bool includeOverlays)
00378     {
00379 
00380         mSceneMgr->_renderScene(this, vp, includeOverlays);
00381     }
00382 
00383 
00384     //-----------------------------------------------------------------------
00385     std::ostream& operator<<( std::ostream& o, Camera& c )
00386     {
00387         o << "Camera(Name='" << c.mName << "', pos=" << c.mPosition;
00388         Vector3 dir(c.mOrientation*Vector3(0,0,-1));
00389         o << ", direction=" << dir << ",near=" << c.mNearDist;
00390         o << ", far=" << c.mFarDist << ", FOVy=" << c.mFOVy;
00391         o << ", aspect=" << c.mAspect << ", ";
00392         o << "NearFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_NEAR] << ", ";
00393         o << "FarFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_FAR] << ", ";
00394         o << "LeftFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_LEFT] << ", ";
00395         o << "RightFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_RIGHT] << ", ";
00396         o << "TopFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_TOP] << ", ";
00397         o << "BottomFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_BOTTOM];
00398         o << ")";
00399 
00400         return o;
00401     }
00402 
00403     //-----------------------------------------------------------------------
00404     void Camera::setFixedYawAxis(bool useFixed, const Vector3& fixedAxis)
00405     {
00406         mYawFixed = useFixed;
00407         mYawFixedAxis = fixedAxis;
00408     }
00409 
00410     //-----------------------------------------------------------------------
00411     void Camera::_notifyRenderedFaces(unsigned int numfaces)
00412     {
00413         mVisFacesLastRender = numfaces;
00414     }
00415 
00416     //-----------------------------------------------------------------------
00417     unsigned int Camera::_getNumRenderedFaces(void) const
00418     {
00419         return mVisFacesLastRender;
00420     }
00421 
00422     //-----------------------------------------------------------------------
00423     const Quaternion& Camera::getOrientation(void) const
00424     {
00425         return mOrientation;
00426     }
00427 
00428     //-----------------------------------------------------------------------
00429     void Camera::setOrientation(const Quaternion& q)
00430     {
00431         mOrientation = q;
00432         invalidateView();
00433     }
00434     //-----------------------------------------------------------------------
00435     Quaternion Camera::getDerivedOrientation(void) const
00436     {
00437         updateView();
00438         return mDerivedOrientation;
00439     }
00440     //-----------------------------------------------------------------------
00441     Vector3 Camera::getDerivedPosition(void) const
00442     {
00443         updateView();
00444         return mDerivedPosition;
00445     }
00446     //-----------------------------------------------------------------------
00447     Vector3 Camera::getDerivedDirection(void) const
00448     {
00449         // Direction points down -Z by default
00450         updateView();
00451         return mDerivedOrientation * -Vector3::UNIT_Z;
00452     }
00453     //-----------------------------------------------------------------------
00454     const String& Camera::getMovableType(void) const
00455     {
00456         return msMovableType;
00457     }
00458     //-----------------------------------------------------------------------
00459     void Camera::setAutoTracking(bool enabled, SceneNode* target, 
00460         const Vector3& offset)
00461     {
00462         if (enabled)
00463         {
00464             assert (target != 0 && "target cannot be a null pointer if tracking is enabled");
00465             mAutoTrackTarget = target;
00466             mAutoTrackOffset = offset;
00467         }
00468         else
00469         {
00470             mAutoTrackTarget = 0;
00471         }
00472     }
00473     //-----------------------------------------------------------------------
00474     void Camera::_autoTrack(void)
00475     {
00476         // NB assumes that all scene nodes have been updated
00477         if (mAutoTrackTarget)
00478         {
00479             lookAt(mAutoTrackTarget->_getDerivedPosition() + mAutoTrackOffset);
00480         }
00481     }
00482     //-----------------------------------------------------------------------
00483     void Camera::setLodBias(Real factor)
00484     {
00485         assert(factor > 0.0f && "Bias factor must be > 0!");
00486         mSceneLodFactor = factor;
00487         mSceneLodFactorInv = 1.0f / factor;
00488     }
00489     //-----------------------------------------------------------------------
00490     Real Camera::getLodBias(void) const
00491     {
00492         return mSceneLodFactor;
00493     }
00494     //-----------------------------------------------------------------------
00495     Real Camera::_getLodBiasInverse(void) const
00496     {
00497         return mSceneLodFactorInv;
00498     }
00499     //-----------------------------------------------------------------------
00500     Ray Camera::getCameraToViewportRay(Real screenX, Real screenY)
00501     {
00502         Real centeredScreenX = (screenX - 0.5f);
00503         Real centeredScreenY = (0.5f - screenY);
00504 
00505         Real normalizedSlope = Math::Tan(Math::DegreesToRadians(mFOVy / 2));
00506         Real viewportYToWorldY = normalizedSlope * mNearDist * 2;
00507         Real viewportXToWorldX = viewportYToWorldY * mAspect;
00508 
00509         Vector3 rayDirection(centeredScreenX * viewportXToWorldX,
00510             centeredScreenY * viewportYToWorldY,
00511             -mNearDist);
00512         rayDirection = getDerivedOrientation() * rayDirection;
00513         rayDirection.normalise();
00514 
00515         return Ray(getDerivedPosition(), rayDirection);
00516     } 
00517 
00518     // -------------------------------------------------------------------
00519     void Camera::setWindow (Real Left, Real Top, Real Right, Real Bottom)
00520     {
00521         mWLeft = Left;
00522         mWTop = Top;
00523         mWRight = Right;
00524         mWBottom = Bottom;
00525 
00526         mWindowSet = true;
00527         mRecalcWindow = true;
00528 
00529         invalidateView();
00530     }
00531     // -------------------------------------------------------------------
00532     void Camera::resetWindow ()
00533     {
00534         mWindowSet = false;
00535     }
00536     // -------------------------------------------------------------------
00537     void Camera::setWindowImpl() const
00538     {
00539         if (!mWindowSet || !mRecalcWindow)
00540             return;
00541 
00542 
00543         Real thetaY = Math::AngleUnitsToRadians(mFOVy / 2.0f);
00544         Real tanThetaY = Math::Tan(thetaY);
00545         //Real thetaX = thetaY * mAspect;
00546         Real tanThetaX = tanThetaY * mAspect;
00547 
00548         Real vpTop = tanThetaY * mNearDist;
00549         Real vpLeft = -tanThetaX * mNearDist;
00550         Real vpWidth = -2 * vpLeft;
00551         Real vpHeight = 2 * vpTop;
00552 
00553         Real wvpLeft   = vpLeft + mWLeft * vpWidth;
00554         Real wvpRight  = vpLeft + mWRight * vpWidth;
00555         Real wvpTop    = vpTop - mWTop * vpHeight;
00556         Real wvpBottom = vpTop - mWBottom * vpHeight;
00557 
00558         Vector3 vp_ul (wvpLeft, wvpTop, -mNearDist);
00559         Vector3 vp_ur (wvpRight, wvpTop, -mNearDist);
00560         Vector3 vp_bl (wvpLeft, wvpBottom, -mNearDist);
00561         Vector3 vp_br (wvpRight, wvpBottom, -mNearDist);
00562 
00563         Matrix4 inv = mViewMatrix.inverse();
00564 
00565         Vector3 vw_ul = inv * vp_ul;
00566         Vector3 vw_ur = inv * vp_ur;
00567         Vector3 vw_bl = inv * vp_bl;
00568         Vector3 vw_br = inv * vp_br;
00569 
00570         Vector3 position = getPosition();
00571 
00572         mWindowClipPlanes.clear();
00573         mWindowClipPlanes.push_back(Plane(position, vw_bl, vw_ul));
00574         mWindowClipPlanes.push_back(Plane(position, vw_ul, vw_ur));
00575         mWindowClipPlanes.push_back(Plane(position, vw_ur, vw_br));
00576         mWindowClipPlanes.push_back(Plane(position, vw_br, vw_bl));
00577 
00578         mRecalcWindow = false;
00579 
00580     }
00581     // -------------------------------------------------------------------
00582     const std::vector<Plane>& Camera::getWindowPlanes(void) const
00583     {
00584         setWindowImpl();
00585         return mWindowClipPlanes;
00586     }
00587     // -------------------------------------------------------------------
00588     Real Camera::getBoundingRadius(void) const
00589     {
00590         // return a little bigger than the near distance
00591         // just to keep things just outside
00592         return mNearDist * 1.5;
00593 
00594     }
00595     //-----------------------------------------------------------------------
00596     const Vector3& Camera::getPositionForViewUpdate(void) const
00597     {
00598         // Note no update, because we're calling this from the update!
00599         return mDerivedPosition;
00600     }
00601     //-----------------------------------------------------------------------
00602     const Quaternion& Camera::getOrientationForViewUpdate(void) const
00603     {
00604         return mDerivedOrientation;
00605     }
00606 
00607 
00608 } // namespace Ogre

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:21:56 2004