OgreCamera.cpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org
  6. Copyright (c) 2000-2011 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "OgreCamera.h"
  25. #include "OgreMath.h"
  26. #include "OgreMatrix3.h"
  27. #include "OgreAxisAlignedBox.h"
  28. #include "OgreSphere.h"
  29. #include "OgreException.h"
  30. #include "OgreRenderSystem.h"
  31. #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
  32. #include "macUtils.h"
  33. #endif
  34. namespace Ogre {
  35. String Camera::msMovableType = "Camera";
  36. //-----------------------------------------------------------------------
  37. Camera::Camera( const String& name, SceneManager* sm)
  38. : Frustum(name),
  39. mSceneMgr(sm),
  40. mOrientation(Quaternion::IDENTITY),
  41. mPosition(Vector3::ZERO),
  42. mSceneDetail(PM_SOLID),
  43. mAutoTrackTarget(0),
  44. mAutoTrackOffset(Vector3::ZERO),
  45. mSceneLodFactor(1.0f),
  46. mSceneLodFactorInv(1.0f),
  47. mWindowSet(false),
  48. mLastViewport(0),
  49. mAutoAspectRatio(false),
  50. mCullFrustum(0),
  51. mUseRenderingDistance(true),
  52. mLodCamera(0)
  53. {
  54. // Reasonable defaults to camera params
  55. mFOVy = Radian(Math::PI/4.0f);
  56. mNearDist = 100.0f;
  57. mFarDist = 100000.0f;
  58. mAspect = 1.33333333333333f;
  59. mProjType = PT_PERSPECTIVE;
  60. setFixedYawAxis(true); // Default to fixed yaw, like freelook since most people expect this
  61. invalidateFrustum();
  62. invalidateView();
  63. // Init matrices
  64. mViewMatrix = Matrix4::ZERO;
  65. mProjMatrixRS = Matrix4::ZERO;
  66. // no reflection
  67. mReflect = false;
  68. }
  69. //-----------------------------------------------------------------------
  70. Camera::~Camera()
  71. {
  72. for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
  73. {
  74. (*i)->cameraDestroyed(this);
  75. }
  76. }
  77. //-----------------------------------------------------------------------
  78. SceneManager* Camera::getSceneManager(void) const
  79. {
  80. return mSceneMgr;
  81. }
  82. //-----------------------------------------------------------------------
  83. void Camera::setPolygonMode(PolygonMode sd)
  84. {
  85. mSceneDetail = sd;
  86. }
  87. //-----------------------------------------------------------------------
  88. PolygonMode Camera::getPolygonMode(void) const
  89. {
  90. return mSceneDetail;
  91. }
  92. //-----------------------------------------------------------------------
  93. void Camera::setPosition(Real x, Real y, Real z)
  94. {
  95. mPosition.x = x;
  96. mPosition.y = y;
  97. mPosition.z = z;
  98. invalidateView();
  99. }
  100. //-----------------------------------------------------------------------
  101. void Camera::setPosition(const Vector3& vec)
  102. {
  103. mPosition = vec;
  104. invalidateView();
  105. }
  106. //-----------------------------------------------------------------------
  107. const Vector3& Camera::getPosition(void) const
  108. {
  109. return mPosition;
  110. }
  111. //-----------------------------------------------------------------------
  112. void Camera::move(const Vector3& vec)
  113. {
  114. mPosition = mPosition + vec;
  115. invalidateView();
  116. }
  117. //-----------------------------------------------------------------------
  118. void Camera::moveRelative(const Vector3& vec)
  119. {
  120. // Transform the axes of the relative vector by camera's local axes
  121. Vector3 trans = mOrientation * vec;
  122. mPosition = mPosition + trans;
  123. invalidateView();
  124. }
  125. //-----------------------------------------------------------------------
  126. void Camera::setDirection(Real x, Real y, Real z)
  127. {
  128. setDirection(Vector3(x,y,z));
  129. }
  130. //-----------------------------------------------------------------------
  131. void Camera::setDirection(const Vector3& vec)
  132. {
  133. // Do nothing if given a zero vector
  134. // (Replaced assert since this could happen with auto tracking camera and
  135. // camera passes through the lookAt point)
  136. if (vec == Vector3::ZERO) return;
  137. // Remember, camera points down -Z of local axes!
  138. // Therefore reverse direction of direction vector before determining local Z
  139. Vector3 zAdjustVec = -vec;
  140. zAdjustVec.normalise();
  141. Quaternion targetWorldOrientation;
  142. if( mYawFixed )
  143. {
  144. Vector3 xVec = mYawFixedAxis.crossProduct( zAdjustVec );
  145. xVec.normalise();
  146. Vector3 yVec = zAdjustVec.crossProduct( xVec );
  147. yVec.normalise();
  148. targetWorldOrientation.FromAxes( xVec, yVec, zAdjustVec );
  149. }
  150. else
  151. {
  152. // Get axes from current quaternion
  153. Vector3 axes[3];
  154. updateView();
  155. mRealOrientation.ToAxes(axes);
  156. Quaternion rotQuat;
  157. if ( (axes[2]+zAdjustVec).squaredLength() < 0.00005f)
  158. {
  159. // Oops, a 180 degree turn (infinite possible rotation axes)
  160. // Default to yaw i.e. use current UP
  161. rotQuat.FromAngleAxis(Radian(Math::PI), axes[1]);
  162. }
  163. else
  164. {
  165. // Derive shortest arc to new direction
  166. rotQuat = axes[2].getRotationTo(zAdjustVec);
  167. }
  168. targetWorldOrientation = rotQuat * mRealOrientation;
  169. }
  170. // transform to parent space
  171. // TODO PORT - Can't get orientation from parent until we hook it up properly as a Component
  172. // if (mParentNode)
  173. // {
  174. // mOrientation =
  175. // mParentNode->_getDerivedOrientation().Inverse() * targetWorldOrientation;
  176. // }
  177. //else
  178. {
  179. mOrientation = targetWorldOrientation;
  180. }
  181. // TODO If we have a fixed yaw axis, we mustn't break it by using the
  182. // shortest arc because this will sometimes cause a relative yaw
  183. // which will tip the camera
  184. invalidateView();
  185. }
  186. //-----------------------------------------------------------------------
  187. Vector3 Camera::getDirection(void) const
  188. {
  189. // Direction points down -Z by default
  190. return mOrientation * -Vector3::UNIT_Z;
  191. }
  192. //-----------------------------------------------------------------------
  193. Vector3 Camera::getUp(void) const
  194. {
  195. return mOrientation * Vector3::UNIT_Y;
  196. }
  197. //-----------------------------------------------------------------------
  198. Vector3 Camera::getRight(void) const
  199. {
  200. return mOrientation * Vector3::UNIT_X;
  201. }
  202. //-----------------------------------------------------------------------
  203. void Camera::lookAt(const Vector3& targetPoint)
  204. {
  205. updateView();
  206. this->setDirection(targetPoint - mRealPosition);
  207. }
  208. //-----------------------------------------------------------------------
  209. void Camera::lookAt( Real x, Real y, Real z )
  210. {
  211. Vector3 vTemp( x, y, z );
  212. this->lookAt(vTemp);
  213. }
  214. //-----------------------------------------------------------------------
  215. void Camera::roll(const Radian& angle)
  216. {
  217. // Rotate around local Z axis
  218. Vector3 zAxis = mOrientation * Vector3::UNIT_Z;
  219. rotate(zAxis, angle);
  220. invalidateView();
  221. }
  222. //-----------------------------------------------------------------------
  223. void Camera::yaw(const Radian& angle)
  224. {
  225. Vector3 yAxis;
  226. if (mYawFixed)
  227. {
  228. // Rotate around fixed yaw axis
  229. yAxis = mYawFixedAxis;
  230. }
  231. else
  232. {
  233. // Rotate around local Y axis
  234. yAxis = mOrientation * Vector3::UNIT_Y;
  235. }
  236. rotate(yAxis, angle);
  237. invalidateView();
  238. }
  239. //-----------------------------------------------------------------------
  240. void Camera::pitch(const Radian& angle)
  241. {
  242. // Rotate around local X axis
  243. Vector3 xAxis = mOrientation * Vector3::UNIT_X;
  244. rotate(xAxis, angle);
  245. invalidateView();
  246. }
  247. //-----------------------------------------------------------------------
  248. void Camera::rotate(const Vector3& axis, const Radian& angle)
  249. {
  250. Quaternion q;
  251. q.FromAngleAxis(angle,axis);
  252. rotate(q);
  253. }
  254. //-----------------------------------------------------------------------
  255. void Camera::rotate(const Quaternion& q)
  256. {
  257. // Note the order of the mult, i.e. q comes after
  258. // Normalise the quat to avoid cumulative problems with precision
  259. Quaternion qnorm = q;
  260. qnorm.normalise();
  261. mOrientation = qnorm * mOrientation;
  262. invalidateView();
  263. }
  264. //-----------------------------------------------------------------------
  265. bool Camera::isViewOutOfDate(void) const
  266. {
  267. // Overridden from Frustum to use local orientation / position offsets
  268. // Attached to node?
  269. // TODO PORT - Can't get orientation/position from parent until we hook it up properly as a Component
  270. //if (mParentNode != 0)
  271. //{
  272. // if (mRecalcView ||
  273. // mParentNode->_getDerivedOrientation() != mLastParentOrientation ||
  274. // mParentNode->_getDerivedPosition() != mLastParentPosition)
  275. // {
  276. // // Ok, we're out of date with SceneNode we're attached to
  277. // mLastParentOrientation = mParentNode->_getDerivedOrientation();
  278. // mLastParentPosition = mParentNode->_getDerivedPosition();
  279. // mRealOrientation = mLastParentOrientation * mOrientation;
  280. // mRealPosition = (mLastParentOrientation * mPosition) + mLastParentPosition;
  281. // mRecalcView = true;
  282. // mRecalcWindow = true;
  283. // }
  284. //}
  285. //else
  286. {
  287. // Rely on own updates
  288. mRealOrientation = mOrientation;
  289. mRealPosition = mPosition;
  290. }
  291. // Deriving reflected orientation / position
  292. if (mRecalcView)
  293. {
  294. if (mReflect)
  295. {
  296. // Calculate reflected orientation, use up-vector as fallback axis.
  297. Vector3 dir = mRealOrientation * Vector3::NEGATIVE_UNIT_Z;
  298. Vector3 rdir = dir.reflect(mReflectPlane.normal);
  299. Vector3 up = mRealOrientation * Vector3::UNIT_Y;
  300. mDerivedOrientation = dir.getRotationTo(rdir, up) * mRealOrientation;
  301. // Calculate reflected position.
  302. mDerivedPosition = mReflectMatrix.transformAffine(mRealPosition);
  303. }
  304. else
  305. {
  306. mDerivedOrientation = mRealOrientation;
  307. mDerivedPosition = mRealPosition;
  308. }
  309. }
  310. return mRecalcView;
  311. }
  312. // -------------------------------------------------------------------
  313. void Camera::invalidateView() const
  314. {
  315. mRecalcWindow = true;
  316. Frustum::invalidateView();
  317. }
  318. // -------------------------------------------------------------------
  319. void Camera::invalidateFrustum(void) const
  320. {
  321. mRecalcWindow = true;
  322. Frustum::invalidateFrustum();
  323. }
  324. //-----------------------------------------------------------------------
  325. void Camera::_renderScene(Viewport *vp, bool includeOverlays)
  326. {
  327. for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
  328. {
  329. (*i)->cameraPreRenderScene(this);
  330. }
  331. // TODO PORT - I'm not going to be rendering the scene like this (yet), but I think I will do it eventually
  332. //mSceneMgr->_renderScene(this, vp, includeOverlays);
  333. for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i)
  334. {
  335. (*i)->cameraPostRenderScene(this);
  336. }
  337. }
  338. //---------------------------------------------------------------------
  339. void Camera::addListener(Listener* l)
  340. {
  341. if (std::find(mListeners.begin(), mListeners.end(), l) == mListeners.end())
  342. mListeners.push_back(l);
  343. }
  344. //---------------------------------------------------------------------
  345. void Camera::removeListener(Listener* l)
  346. {
  347. ListenerList::iterator i = std::find(mListeners.begin(), mListeners.end(), l);
  348. if (i != mListeners.end())
  349. mListeners.erase(i);
  350. }
  351. //-----------------------------------------------------------------------
  352. std::ostream& operator<<( std::ostream& o, const Camera& c )
  353. {
  354. o << "Camera(pos=" << c.mPosition;
  355. Vector3 dir(c.mOrientation*Vector3(0,0,-1));
  356. o << ", direction=" << dir << ",near=" << c.mNearDist;
  357. o << ", far=" << c.mFarDist << ", FOVy=" << c.mFOVy.valueDegrees();
  358. o << ", aspect=" << c.mAspect << ", ";
  359. o << ", xoffset=" << c.mFrustumOffset.x << ", yoffset=" << c.mFrustumOffset.y;
  360. o << ", focalLength=" << c.mFocalLength << ", ";
  361. o << "NearFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_NEAR] << ", ";
  362. o << "FarFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_FAR] << ", ";
  363. o << "LeftFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_LEFT] << ", ";
  364. o << "RightFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_RIGHT] << ", ";
  365. o << "TopFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_TOP] << ", ";
  366. o << "BottomFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_BOTTOM];
  367. o << ")";
  368. return o;
  369. }
  370. //-----------------------------------------------------------------------
  371. void Camera::setFixedYawAxis(bool useFixed, const Vector3& fixedAxis)
  372. {
  373. mYawFixed = useFixed;
  374. mYawFixedAxis = fixedAxis;
  375. }
  376. //-----------------------------------------------------------------------
  377. void Camera::_notifyRenderedFaces(unsigned int numfaces)
  378. {
  379. mVisFacesLastRender = numfaces;
  380. }
  381. //-----------------------------------------------------------------------
  382. void Camera::_notifyRenderedBatches(unsigned int numbatches)
  383. {
  384. mVisBatchesLastRender = numbatches;
  385. }
  386. //-----------------------------------------------------------------------
  387. unsigned int Camera::_getNumRenderedFaces(void) const
  388. {
  389. return mVisFacesLastRender;
  390. }
  391. //-----------------------------------------------------------------------
  392. unsigned int Camera::_getNumRenderedBatches(void) const
  393. {
  394. return mVisBatchesLastRender;
  395. }
  396. //-----------------------------------------------------------------------
  397. const Quaternion& Camera::getOrientation(void) const
  398. {
  399. return mOrientation;
  400. }
  401. //-----------------------------------------------------------------------
  402. void Camera::setOrientation(const Quaternion& q)
  403. {
  404. mOrientation = q;
  405. mOrientation.normalise();
  406. invalidateView();
  407. }
  408. //-----------------------------------------------------------------------
  409. const Quaternion& Camera::getDerivedOrientation(void) const
  410. {
  411. updateView();
  412. return mDerivedOrientation;
  413. }
  414. //-----------------------------------------------------------------------
  415. const Vector3& Camera::getDerivedPosition(void) const
  416. {
  417. updateView();
  418. return mDerivedPosition;
  419. }
  420. //-----------------------------------------------------------------------
  421. Vector3 Camera::getDerivedDirection(void) const
  422. {
  423. // Direction points down -Z
  424. updateView();
  425. return mDerivedOrientation * Vector3::NEGATIVE_UNIT_Z;
  426. }
  427. //-----------------------------------------------------------------------
  428. Vector3 Camera::getDerivedUp(void) const
  429. {
  430. updateView();
  431. return mDerivedOrientation * Vector3::UNIT_Y;
  432. }
  433. //-----------------------------------------------------------------------
  434. Vector3 Camera::getDerivedRight(void) const
  435. {
  436. updateView();
  437. return mDerivedOrientation * Vector3::UNIT_X;
  438. }
  439. //-----------------------------------------------------------------------
  440. const Quaternion& Camera::getRealOrientation(void) const
  441. {
  442. updateView();
  443. return mRealOrientation;
  444. }
  445. //-----------------------------------------------------------------------
  446. const Vector3& Camera::getRealPosition(void) const
  447. {
  448. updateView();
  449. return mRealPosition;
  450. }
  451. //-----------------------------------------------------------------------
  452. Vector3 Camera::getRealDirection(void) const
  453. {
  454. // Direction points down -Z
  455. updateView();
  456. return mRealOrientation * Vector3::NEGATIVE_UNIT_Z;
  457. }
  458. //-----------------------------------------------------------------------
  459. Vector3 Camera::getRealUp(void) const
  460. {
  461. updateView();
  462. return mRealOrientation * Vector3::UNIT_Y;
  463. }
  464. //-----------------------------------------------------------------------
  465. Vector3 Camera::getRealRight(void) const
  466. {
  467. updateView();
  468. return mRealOrientation * Vector3::UNIT_X;
  469. }
  470. //-----------------------------------------------------------------------
  471. const String& Camera::getMovableType(void) const
  472. {
  473. return msMovableType;
  474. }
  475. //-----------------------------------------------------------------------
  476. void Camera::setAutoTracking(bool enabled, SceneNode* target,
  477. const Vector3& offset)
  478. {
  479. if (enabled)
  480. {
  481. assert (target != 0 && "target cannot be a null pointer if tracking is enabled");
  482. mAutoTrackTarget = target;
  483. mAutoTrackOffset = offset;
  484. }
  485. else
  486. {
  487. mAutoTrackTarget = 0;
  488. }
  489. }
  490. //-----------------------------------------------------------------------
  491. void Camera::_autoTrack(void)
  492. {
  493. // NB assumes that all scene nodes have been updated
  494. if (mAutoTrackTarget)
  495. {
  496. //lookAt(mAutoTrackTarget->_getDerivedPosition() + mAutoTrackOffset);
  497. }
  498. }
  499. //-----------------------------------------------------------------------
  500. void Camera::setLodBias(Real factor)
  501. {
  502. assert(factor > 0.0f && "Bias factor must be > 0!");
  503. mSceneLodFactor = factor;
  504. mSceneLodFactorInv = 1.0f / factor;
  505. }
  506. //-----------------------------------------------------------------------
  507. Real Camera::getLodBias(void) const
  508. {
  509. return mSceneLodFactor;
  510. }
  511. //-----------------------------------------------------------------------
  512. Real Camera::_getLodBiasInverse(void) const
  513. {
  514. return mSceneLodFactorInv;
  515. }
  516. //-----------------------------------------------------------------------
  517. void Camera::setLodCamera(const Camera* lodCam)
  518. {
  519. if (lodCam == this)
  520. mLodCamera = 0;
  521. else
  522. mLodCamera = lodCam;
  523. }
  524. //---------------------------------------------------------------------
  525. const Camera* Camera::getLodCamera() const
  526. {
  527. return mLodCamera? mLodCamera : this;
  528. }
  529. //-----------------------------------------------------------------------
  530. Ray Camera::getCameraToViewportRay(Real screenX, Real screenY) const
  531. {
  532. Ray ret;
  533. getCameraToViewportRay(screenX, screenY, &ret);
  534. return ret;
  535. }
  536. //---------------------------------------------------------------------
  537. void Camera::getCameraToViewportRay(Real screenX, Real screenY, Ray* outRay) const
  538. {
  539. Matrix4 inverseVP = (getProjectionMatrix() * getViewMatrix(true)).inverse();
  540. #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0
  541. // We need to convert screen point to our oriented viewport (temp solution)
  542. Real tX = screenX; Real a = getOrientationMode() * Math::HALF_PI;
  543. screenX = Math::Cos(a) * (tX-0.5f) + Math::Sin(a) * (screenY-0.5f) + 0.5f;
  544. screenY = Math::Sin(a) * (tX-0.5f) + Math::Cos(a) * (screenY-0.5f) + 0.5f;
  545. if ((int)getOrientationMode()&1) screenY = 1.f - screenY;
  546. #endif
  547. Real nx = (2.0f * screenX) - 1.0f;
  548. Real ny = 1.0f - (2.0f * screenY);
  549. Vector3 nearPoint(nx, ny, -1.f);
  550. // Use midPoint rather than far point to avoid issues with infinite projection
  551. Vector3 midPoint (nx, ny, 0.0f);
  552. // Get ray origin and ray target on near plane in world space
  553. Vector3 rayOrigin, rayTarget;
  554. rayOrigin = inverseVP * nearPoint;
  555. rayTarget = inverseVP * midPoint;
  556. Vector3 rayDirection = rayTarget - rayOrigin;
  557. rayDirection.normalise();
  558. outRay->setOrigin(rayOrigin);
  559. outRay->setDirection(rayDirection);
  560. }
  561. // -------------------------------------------------------------------
  562. void Camera::setWindow (Real Left, Real Top, Real Right, Real Bottom)
  563. {
  564. mWLeft = Left;
  565. mWTop = Top;
  566. mWRight = Right;
  567. mWBottom = Bottom;
  568. mWindowSet = true;
  569. mRecalcWindow = true;
  570. }
  571. // -------------------------------------------------------------------
  572. void Camera::resetWindow ()
  573. {
  574. mWindowSet = false;
  575. }
  576. // -------------------------------------------------------------------
  577. void Camera::setWindowImpl() const
  578. {
  579. if (!mWindowSet || !mRecalcWindow)
  580. return;
  581. // Calculate general projection parameters
  582. Real vpLeft, vpRight, vpBottom, vpTop;
  583. calcProjectionParameters(vpLeft, vpRight, vpBottom, vpTop);
  584. Real vpWidth = vpRight - vpLeft;
  585. Real vpHeight = vpTop - vpBottom;
  586. Real wvpLeft = vpLeft + mWLeft * vpWidth;
  587. Real wvpRight = vpLeft + mWRight * vpWidth;
  588. Real wvpTop = vpTop - mWTop * vpHeight;
  589. Real wvpBottom = vpTop - mWBottom * vpHeight;
  590. Vector3 vp_ul (wvpLeft, wvpTop, -mNearDist);
  591. Vector3 vp_ur (wvpRight, wvpTop, -mNearDist);
  592. Vector3 vp_bl (wvpLeft, wvpBottom, -mNearDist);
  593. Vector3 vp_br (wvpRight, wvpBottom, -mNearDist);
  594. Matrix4 inv = mViewMatrix.inverseAffine();
  595. Vector3 vw_ul = inv.transformAffine(vp_ul);
  596. Vector3 vw_ur = inv.transformAffine(vp_ur);
  597. Vector3 vw_bl = inv.transformAffine(vp_bl);
  598. Vector3 vw_br = inv.transformAffine(vp_br);
  599. mWindowClipPlanes.clear();
  600. if (mProjType == PT_PERSPECTIVE)
  601. {
  602. Vector3 position = getPositionForViewUpdate();
  603. mWindowClipPlanes.push_back(Plane(position, vw_bl, vw_ul));
  604. mWindowClipPlanes.push_back(Plane(position, vw_ul, vw_ur));
  605. mWindowClipPlanes.push_back(Plane(position, vw_ur, vw_br));
  606. mWindowClipPlanes.push_back(Plane(position, vw_br, vw_bl));
  607. }
  608. else
  609. {
  610. Vector3 x_axis(inv[0][0], inv[0][1], inv[0][2]);
  611. Vector3 y_axis(inv[1][0], inv[1][1], inv[1][2]);
  612. x_axis.normalise();
  613. y_axis.normalise();
  614. mWindowClipPlanes.push_back(Plane( x_axis, vw_bl));
  615. mWindowClipPlanes.push_back(Plane(-x_axis, vw_ur));
  616. mWindowClipPlanes.push_back(Plane( y_axis, vw_bl));
  617. mWindowClipPlanes.push_back(Plane(-y_axis, vw_ur));
  618. }
  619. mRecalcWindow = false;
  620. }
  621. // -------------------------------------------------------------------
  622. const vector<Plane>::type& Camera::getWindowPlanes(void) const
  623. {
  624. updateView();
  625. setWindowImpl();
  626. return mWindowClipPlanes;
  627. }
  628. // -------------------------------------------------------------------
  629. Real Camera::getBoundingRadius(void) const
  630. {
  631. // return a little bigger than the near distance
  632. // just to keep things just outside
  633. return mNearDist * 1.5f;
  634. }
  635. //-----------------------------------------------------------------------
  636. const Vector3& Camera::getPositionForViewUpdate(void) const
  637. {
  638. // Note no update, because we're calling this from the update!
  639. return mRealPosition;
  640. }
  641. //-----------------------------------------------------------------------
  642. const Quaternion& Camera::getOrientationForViewUpdate(void) const
  643. {
  644. return mRealOrientation;
  645. }
  646. //-----------------------------------------------------------------------
  647. bool Camera::getAutoAspectRatio(void) const
  648. {
  649. return mAutoAspectRatio;
  650. }
  651. //-----------------------------------------------------------------------
  652. void Camera::setAutoAspectRatio(bool autoratio)
  653. {
  654. mAutoAspectRatio = autoratio;
  655. }
  656. //-----------------------------------------------------------------------
  657. bool Camera::isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy) const
  658. {
  659. if (mCullFrustum)
  660. {
  661. return mCullFrustum->isVisible(bound, culledBy);
  662. }
  663. else
  664. {
  665. return Frustum::isVisible(bound, culledBy);
  666. }
  667. }
  668. //-----------------------------------------------------------------------
  669. bool Camera::isVisible(const Sphere& bound, FrustumPlane* culledBy) const
  670. {
  671. if (mCullFrustum)
  672. {
  673. return mCullFrustum->isVisible(bound, culledBy);
  674. }
  675. else
  676. {
  677. return Frustum::isVisible(bound, culledBy);
  678. }
  679. }
  680. //-----------------------------------------------------------------------
  681. bool Camera::isVisible(const Vector3& vert, FrustumPlane* culledBy) const
  682. {
  683. if (mCullFrustum)
  684. {
  685. return mCullFrustum->isVisible(vert, culledBy);
  686. }
  687. else
  688. {
  689. return Frustum::isVisible(vert, culledBy);
  690. }
  691. }
  692. //-----------------------------------------------------------------------
  693. const Vector3* Camera::getWorldSpaceCorners(void) const
  694. {
  695. if (mCullFrustum)
  696. {
  697. return mCullFrustum->getWorldSpaceCorners();
  698. }
  699. else
  700. {
  701. return Frustum::getWorldSpaceCorners();
  702. }
  703. }
  704. //-----------------------------------------------------------------------
  705. const Plane& Camera::getFrustumPlane( unsigned short plane ) const
  706. {
  707. if (mCullFrustum)
  708. {
  709. return mCullFrustum->getFrustumPlane(plane);
  710. }
  711. else
  712. {
  713. return Frustum::getFrustumPlane(plane);
  714. }
  715. }
  716. //-----------------------------------------------------------------------
  717. bool Camera::projectSphere(const Sphere& sphere,
  718. Real* left, Real* top, Real* right, Real* bottom) const
  719. {
  720. if (mCullFrustum)
  721. {
  722. return mCullFrustum->projectSphere(sphere, left, top, right, bottom);
  723. }
  724. else
  725. {
  726. return Frustum::projectSphere(sphere, left, top, right, bottom);
  727. }
  728. }
  729. //-----------------------------------------------------------------------
  730. Real Camera::getNearClipDistance(void) const
  731. {
  732. if (mCullFrustum)
  733. {
  734. return mCullFrustum->getNearClipDistance();
  735. }
  736. else
  737. {
  738. return Frustum::getNearClipDistance();
  739. }
  740. }
  741. //-----------------------------------------------------------------------
  742. Real Camera::getFarClipDistance(void) const
  743. {
  744. if (mCullFrustum)
  745. {
  746. return mCullFrustum->getFarClipDistance();
  747. }
  748. else
  749. {
  750. return Frustum::getFarClipDistance();
  751. }
  752. }
  753. //-----------------------------------------------------------------------
  754. const Matrix4& Camera::getViewMatrix(void) const
  755. {
  756. if (mCullFrustum)
  757. {
  758. return mCullFrustum->getViewMatrix();
  759. }
  760. else
  761. {
  762. return Frustum::getViewMatrix();
  763. }
  764. }
  765. //-----------------------------------------------------------------------
  766. const Matrix4& Camera::getViewMatrix(bool ownFrustumOnly) const
  767. {
  768. if (ownFrustumOnly)
  769. {
  770. return Frustum::getViewMatrix();
  771. }
  772. else
  773. {
  774. return getViewMatrix();
  775. }
  776. }
  777. //-----------------------------------------------------------------------
  778. //_______________________________________________________
  779. //| |
  780. //| getRayForwardIntersect |
  781. //| ----------------------------- |
  782. //| get the intersections of frustum rays with a plane |
  783. //| of interest. The plane is assumed to have constant |
  784. //| z. If this is not the case, rays |
  785. //| should be rotated beforehand to work in a |
  786. //| coordinate system in which this is true. |
  787. //|_____________________________________________________|
  788. //
  789. vector<Vector4>::type Camera::getRayForwardIntersect(const Vector3& anchor, const Vector3 *dir, Real planeOffset) const
  790. {
  791. vector<Vector4>::type res;
  792. if(!dir)
  793. return res;
  794. int infpt[4] = {0, 0, 0, 0}; // 0=finite, 1=infinite, 2=straddles infinity
  795. Vector3 vec[4];
  796. // find how much the anchor point must be displaced in the plane's
  797. // constant variable
  798. Real delta = planeOffset - anchor.z;
  799. // now set the intersection point and note whether it is a
  800. // point at infinity or straddles infinity
  801. unsigned int i;
  802. for (i=0; i<4; i++)
  803. {
  804. Real test = dir[i].z * delta;
  805. if (test == 0.0) {
  806. vec[i] = dir[i];
  807. infpt[i] = 1;
  808. }
  809. else {
  810. Real lambda = delta / dir[i].z;
  811. vec[i] = anchor + (lambda * dir[i]);
  812. if(test < 0.0)
  813. infpt[i] = 2;
  814. }
  815. }
  816. for (i=0; i<4; i++)
  817. {
  818. // store the finite intersection points
  819. if (infpt[i] == 0)
  820. res.push_back(Vector4(vec[i].x, vec[i].y, vec[i].z, 1.0));
  821. else
  822. {
  823. // handle the infinite points of intersection;
  824. // cases split up into the possible frustum planes
  825. // pieces which may contain a finite intersection point
  826. int nextind = (i+1) % 4;
  827. int prevind = (i+3) % 4;
  828. if ((infpt[prevind] == 0) || (infpt[nextind] == 0))
  829. {
  830. if (infpt[i] == 1)
  831. res.push_back(Vector4(vec[i].x, vec[i].y, vec[i].z, 0.0));
  832. else
  833. {
  834. // handle the intersection points that straddle infinity (back-project)
  835. if(infpt[prevind] == 0)
  836. {
  837. Vector3 temp = vec[prevind] - vec[i];
  838. res.push_back(Vector4(temp.x, temp.y, temp.z, 0.0));
  839. }
  840. if(infpt[nextind] == 0)
  841. {
  842. Vector3 temp = vec[nextind] - vec[i];
  843. res.push_back(Vector4(temp.x, temp.y, temp.z, 0.0));
  844. }
  845. }
  846. } // end if we need to add an intersection point to the list
  847. } // end if infinite point needs to be considered
  848. } // end loop over frustun corners
  849. // we end up with either 0, 3, 4, or 5 intersection points
  850. return res;
  851. }
  852. //_______________________________________________________
  853. //| |
  854. //| forwardIntersect |
  855. //| ----------------------------- |
  856. //| Forward intersect the camera's frustum rays with |
  857. //| a specified plane of interest. |
  858. //| Note that if the frustum rays shoot out and would |
  859. //| back project onto the plane, this means the forward |
  860. //| intersection of the frustum would occur at the |
  861. //| line at infinity. |
  862. //|_____________________________________________________|
  863. //
  864. void Camera::forwardIntersect(const Plane& worldPlane, vector<Vector4>::type* intersect3d) const
  865. {
  866. if(!intersect3d)
  867. return;
  868. Vector3 trCorner = getWorldSpaceCorners()[0];
  869. Vector3 tlCorner = getWorldSpaceCorners()[1];
  870. Vector3 blCorner = getWorldSpaceCorners()[2];
  871. Vector3 brCorner = getWorldSpaceCorners()[3];
  872. // need some sort of rotation that will bring the plane normal to the z axis
  873. Plane pval = worldPlane;
  874. if(pval.normal.z < 0.0)
  875. {
  876. pval.normal *= -1.0;
  877. pval.d *= -1.0;
  878. }
  879. Quaternion invPlaneRot = pval.normal.getRotationTo(Vector3::UNIT_Z);
  880. // get rotated light
  881. Vector3 lPos = invPlaneRot * getDerivedPosition();
  882. Vector3 vec[4];
  883. vec[0] = invPlaneRot * trCorner - lPos;
  884. vec[1] = invPlaneRot * tlCorner - lPos;
  885. vec[2] = invPlaneRot * blCorner - lPos;
  886. vec[3] = invPlaneRot * brCorner - lPos;
  887. // compute intersection points on plane
  888. vector<Vector4>::type iPnt = getRayForwardIntersect(lPos, vec, -pval.d);
  889. // return wanted data
  890. if(intersect3d)
  891. {
  892. Quaternion planeRot = invPlaneRot.Inverse();
  893. (*intersect3d).clear();
  894. for(unsigned int i=0; i<iPnt.size(); i++)
  895. {
  896. Vector3 intersection = planeRot * Vector3(iPnt[i].x, iPnt[i].y, iPnt[i].z);
  897. (*intersect3d).push_back(Vector4(intersection.x, intersection.y, intersection.z, iPnt[i].w));
  898. }
  899. }
  900. }
  901. //-----------------------------------------------------------------------
  902. void Camera::synchroniseBaseSettingsWith(const Camera* cam)
  903. {
  904. this->setPosition(cam->getPosition());
  905. this->setProjectionType(cam->getProjectionType());
  906. this->setOrientation(cam->getOrientation());
  907. this->setAspectRatio(cam->getAspectRatio());
  908. this->setNearClipDistance(cam->getNearClipDistance());
  909. this->setFarClipDistance(cam->getFarClipDistance());
  910. this->setUseRenderingDistance(cam->getUseRenderingDistance());
  911. this->setFOVy(cam->getFOVy());
  912. this->setFocalLength(cam->getFocalLength());
  913. // Don't do these, they're not base settings and can cause referencing issues
  914. //this->setLodCamera(cam->getLodCamera());
  915. //this->setCullingFrustum(cam->getCullingFrustum());
  916. }
  917. } // namespace Ogre