1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://ogre.sourceforge.net/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software; you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | #include "OgreStableHeaders.h"
|
---|
26 | #include "OgreCamera.h"
|
---|
27 |
|
---|
28 | #include "OgreMath.h"
|
---|
29 | #include "OgreMatrix3.h"
|
---|
30 | #include "OgreSceneManager.h"
|
---|
31 | #include "OgreSceneNode.h"
|
---|
32 | #include "OgreAxisAlignedBox.h"
|
---|
33 | #include "OgreSphere.h"
|
---|
34 | #include "OgreLogManager.h"
|
---|
35 | #include "OgreException.h"
|
---|
36 | #include "OgreRoot.h"
|
---|
37 | #include "OgreRenderSystem.h"
|
---|
38 |
|
---|
39 | namespace Ogre {
|
---|
40 |
|
---|
41 | String Camera::msMovableType = "Camera";
|
---|
42 | //-----------------------------------------------------------------------
|
---|
43 | Camera::Camera( const String& name, SceneManager* sm)
|
---|
44 | : mName( name ),
|
---|
45 | mSceneMgr(sm),
|
---|
46 | mOrientation(Quaternion::IDENTITY),
|
---|
47 | mPosition(Vector3::ZERO),
|
---|
48 | mSceneDetail(PM_SOLID),
|
---|
49 | mAutoTrackTarget(0),
|
---|
50 | mAutoTrackOffset(Vector3::ZERO),
|
---|
51 | mSceneLodFactor(1.0f),
|
---|
52 | mSceneLodFactorInv(1.0f),
|
---|
53 | mWindowSet(false),
|
---|
54 | mLastViewport(0),
|
---|
55 | mAutoAspectRatio(false),
|
---|
56 | mCullFrustum(0),
|
---|
57 | mUseRenderingDistance(true)
|
---|
58 |
|
---|
59 | {
|
---|
60 |
|
---|
61 | // Reasonable defaults to camera params
|
---|
62 | mFOVy = Radian(Math::PI/4.0);
|
---|
63 | mNearDist = 100.0f;
|
---|
64 | mFarDist = 100000.0f;
|
---|
65 | mAspect = 1.33333333333333f;
|
---|
66 | mProjType = PT_PERSPECTIVE;
|
---|
67 | setFixedYawAxis(true); // Default to fixed yaw, like freelook since most people expect this
|
---|
68 |
|
---|
69 | invalidateFrustum();
|
---|
70 | invalidateView();
|
---|
71 |
|
---|
72 | // Init matrices
|
---|
73 | mViewMatrix = Matrix4::ZERO;
|
---|
74 | mProjMatrixRS = Matrix4::ZERO;
|
---|
75 |
|
---|
76 | mParentNode = 0;
|
---|
77 |
|
---|
78 | // no reflection
|
---|
79 | mReflect = false;
|
---|
80 |
|
---|
81 | mVisible = false;
|
---|
82 |
|
---|
83 | }
|
---|
84 |
|
---|
85 | //-----------------------------------------------------------------------
|
---|
86 | Camera::~Camera()
|
---|
87 | {
|
---|
88 | // Do nothing
|
---|
89 | }
|
---|
90 |
|
---|
91 | //-----------------------------------------------------------------------
|
---|
92 | SceneManager* Camera::getSceneManager(void) const
|
---|
93 | {
|
---|
94 | return mSceneMgr;
|
---|
95 | }
|
---|
96 | //-----------------------------------------------------------------------
|
---|
97 | const String& Camera::getName(void) const
|
---|
98 | {
|
---|
99 | return mName;
|
---|
100 | }
|
---|
101 |
|
---|
102 |
|
---|
103 | //-----------------------------------------------------------------------
|
---|
104 | void Camera::setPolygonMode(PolygonMode sd)
|
---|
105 | {
|
---|
106 | mSceneDetail = sd;
|
---|
107 | }
|
---|
108 |
|
---|
109 | //-----------------------------------------------------------------------
|
---|
110 | PolygonMode Camera::getPolygonMode(void) const
|
---|
111 | {
|
---|
112 | return mSceneDetail;
|
---|
113 | }
|
---|
114 |
|
---|
115 | //-----------------------------------------------------------------------
|
---|
116 | void Camera::setPosition(Real x, Real y, Real z)
|
---|
117 | {
|
---|
118 | mPosition.x = x;
|
---|
119 | mPosition.y = y;
|
---|
120 | mPosition.z = z;
|
---|
121 | invalidateView();
|
---|
122 | }
|
---|
123 |
|
---|
124 | //-----------------------------------------------------------------------
|
---|
125 | void Camera::setPosition(const Vector3& vec)
|
---|
126 | {
|
---|
127 | mPosition = vec;
|
---|
128 | invalidateView();
|
---|
129 | }
|
---|
130 |
|
---|
131 | //-----------------------------------------------------------------------
|
---|
132 | const Vector3& Camera::getPosition(void) const
|
---|
133 | {
|
---|
134 | return mPosition;
|
---|
135 | }
|
---|
136 |
|
---|
137 | //-----------------------------------------------------------------------
|
---|
138 | void Camera::move(const Vector3& vec)
|
---|
139 | {
|
---|
140 | mPosition = mPosition + vec;
|
---|
141 | invalidateView();
|
---|
142 | }
|
---|
143 |
|
---|
144 | //-----------------------------------------------------------------------
|
---|
145 | void Camera::moveRelative(const Vector3& vec)
|
---|
146 | {
|
---|
147 | // Transform the axes of the relative vector by camera's local axes
|
---|
148 | Vector3 trans = mOrientation * vec;
|
---|
149 |
|
---|
150 | mPosition = mPosition + trans;
|
---|
151 | invalidateView();
|
---|
152 | }
|
---|
153 |
|
---|
154 | //-----------------------------------------------------------------------
|
---|
155 | void Camera::setDirection(Real x, Real y, Real z)
|
---|
156 | {
|
---|
157 | setDirection(Vector3(x,y,z));
|
---|
158 | }
|
---|
159 |
|
---|
160 | //-----------------------------------------------------------------------
|
---|
161 | void Camera::setDirection(const Vector3& vec)
|
---|
162 | {
|
---|
163 | // Do nothing if given a zero vector
|
---|
164 | // (Replaced assert since this could happen with auto tracking camera and
|
---|
165 | // camera passes through the lookAt point)
|
---|
166 | if (vec == Vector3::ZERO) return;
|
---|
167 |
|
---|
168 | // Remember, camera points down -Z of local axes!
|
---|
169 | // Therefore reverse direction of direction vector before determining local Z
|
---|
170 | Vector3 zAdjustVec = -vec;
|
---|
171 | zAdjustVec.normalise();
|
---|
172 |
|
---|
173 |
|
---|
174 | if( mYawFixed )
|
---|
175 | {
|
---|
176 | Vector3 xVec = mYawFixedAxis.crossProduct( zAdjustVec );
|
---|
177 | xVec.normalise();
|
---|
178 |
|
---|
179 | Vector3 yVec = zAdjustVec.crossProduct( xVec );
|
---|
180 | yVec.normalise();
|
---|
181 |
|
---|
182 | mOrientation.FromAxes( xVec, yVec, zAdjustVec );
|
---|
183 | }
|
---|
184 | else
|
---|
185 | {
|
---|
186 |
|
---|
187 | // Get axes from current quaternion
|
---|
188 | Vector3 axes[3];
|
---|
189 | updateView();
|
---|
190 | mRealOrientation.ToAxes(axes);
|
---|
191 | Quaternion rotQuat;
|
---|
192 | if ( (axes[2]+zAdjustVec).squaredLength() < 0.00005f)
|
---|
193 | {
|
---|
194 | // Oops, a 180 degree turn (infinite possible rotation axes)
|
---|
195 | // Default to yaw i.e. use current UP
|
---|
196 | rotQuat.FromAngleAxis(Radian(Math::PI), axes[1]);
|
---|
197 | }
|
---|
198 | else
|
---|
199 | {
|
---|
200 | // Derive shortest arc to new direction
|
---|
201 | rotQuat = axes[2].getRotationTo(zAdjustVec);
|
---|
202 |
|
---|
203 | }
|
---|
204 | mOrientation = rotQuat * mOrientation;
|
---|
205 | }
|
---|
206 |
|
---|
207 | // transform to parent space
|
---|
208 | if (mParentNode)
|
---|
209 | {
|
---|
210 | mOrientation =
|
---|
211 | mParentNode->_getDerivedOrientation().Inverse() * mOrientation;
|
---|
212 | }
|
---|
213 |
|
---|
214 | // TODO If we have a fixed yaw axis, we mustn't break it by using the
|
---|
215 | // shortest arc because this will sometimes cause a relative yaw
|
---|
216 | // which will tip the camera
|
---|
217 |
|
---|
218 | invalidateView();
|
---|
219 |
|
---|
220 | }
|
---|
221 |
|
---|
222 | //-----------------------------------------------------------------------
|
---|
223 | Vector3 Camera::getDirection(void) const
|
---|
224 | {
|
---|
225 | // Direction points down -Z by default
|
---|
226 | return mOrientation * -Vector3::UNIT_Z;
|
---|
227 | }
|
---|
228 |
|
---|
229 | //-----------------------------------------------------------------------
|
---|
230 | Vector3 Camera::getUp(void) const
|
---|
231 | {
|
---|
232 | return mOrientation * Vector3::UNIT_Y;
|
---|
233 | }
|
---|
234 |
|
---|
235 | //-----------------------------------------------------------------------
|
---|
236 | Vector3 Camera::getRight(void) const
|
---|
237 | {
|
---|
238 | return mOrientation * Vector3::UNIT_X;
|
---|
239 | }
|
---|
240 |
|
---|
241 | //-----------------------------------------------------------------------
|
---|
242 | void Camera::lookAt(const Vector3& targetPoint)
|
---|
243 | {
|
---|
244 | updateView();
|
---|
245 | this->setDirection(targetPoint - mRealPosition);
|
---|
246 | }
|
---|
247 |
|
---|
248 | //-----------------------------------------------------------------------
|
---|
249 | void Camera::lookAt( Real x, Real y, Real z )
|
---|
250 | {
|
---|
251 | Vector3 vTemp( x, y, z );
|
---|
252 | this->lookAt(vTemp);
|
---|
253 | }
|
---|
254 |
|
---|
255 | //-----------------------------------------------------------------------
|
---|
256 | void Camera::roll(const Radian& angle)
|
---|
257 | {
|
---|
258 | // Rotate around local Z axis
|
---|
259 | Vector3 zAxis = mOrientation * Vector3::UNIT_Z;
|
---|
260 | rotate(zAxis, angle);
|
---|
261 |
|
---|
262 | invalidateView();
|
---|
263 | }
|
---|
264 |
|
---|
265 | //-----------------------------------------------------------------------
|
---|
266 | void Camera::yaw(const Radian& angle)
|
---|
267 | {
|
---|
268 | Vector3 yAxis;
|
---|
269 |
|
---|
270 | if (mYawFixed)
|
---|
271 | {
|
---|
272 | // Rotate around fixed yaw axis
|
---|
273 | yAxis = mYawFixedAxis;
|
---|
274 | }
|
---|
275 | else
|
---|
276 | {
|
---|
277 | // Rotate around local Y axis
|
---|
278 | yAxis = mOrientation * Vector3::UNIT_Y;
|
---|
279 | }
|
---|
280 |
|
---|
281 | rotate(yAxis, angle);
|
---|
282 |
|
---|
283 | invalidateView();
|
---|
284 | }
|
---|
285 |
|
---|
286 | //-----------------------------------------------------------------------
|
---|
287 | void Camera::pitch(const Radian& angle)
|
---|
288 | {
|
---|
289 | // Rotate around local X axis
|
---|
290 | Vector3 xAxis = mOrientation * Vector3::UNIT_X;
|
---|
291 | rotate(xAxis, angle);
|
---|
292 |
|
---|
293 | invalidateView();
|
---|
294 |
|
---|
295 | }
|
---|
296 |
|
---|
297 | //-----------------------------------------------------------------------
|
---|
298 | void Camera::rotate(const Vector3& axis, const Radian& angle)
|
---|
299 | {
|
---|
300 | Quaternion q;
|
---|
301 | q.FromAngleAxis(angle,axis);
|
---|
302 | rotate(q);
|
---|
303 | }
|
---|
304 |
|
---|
305 | //-----------------------------------------------------------------------
|
---|
306 | void Camera::rotate(const Quaternion& q)
|
---|
307 | {
|
---|
308 | // Note the order of the mult, i.e. q comes after
|
---|
309 | mOrientation = q * mOrientation;
|
---|
310 | invalidateView();
|
---|
311 |
|
---|
312 | }
|
---|
313 |
|
---|
314 | //-----------------------------------------------------------------------
|
---|
315 | bool Camera::isViewOutOfDate(void) const
|
---|
316 | {
|
---|
317 | // Overridden from Frustum to use local orientation / position offsets
|
---|
318 | // Attached to node?
|
---|
319 | if (mParentNode != 0)
|
---|
320 | {
|
---|
321 | if (mRecalcView ||
|
---|
322 | mParentNode->_getDerivedOrientation() != mLastParentOrientation ||
|
---|
323 | mParentNode->_getDerivedPosition() != mLastParentPosition)
|
---|
324 | {
|
---|
325 | // Ok, we're out of date with SceneNode we're attached to
|
---|
326 | mLastParentOrientation = mParentNode->_getDerivedOrientation();
|
---|
327 | mLastParentPosition = mParentNode->_getDerivedPosition();
|
---|
328 | mRealOrientation = mLastParentOrientation * mOrientation;
|
---|
329 | mRealPosition = (mLastParentOrientation * mPosition) + mLastParentPosition;
|
---|
330 | mRecalcView = true;
|
---|
331 | mRecalcWindow = true;
|
---|
332 | }
|
---|
333 | }
|
---|
334 | else
|
---|
335 | {
|
---|
336 | // Rely on own updates
|
---|
337 | mRealOrientation = mOrientation;
|
---|
338 | mRealPosition = mPosition;
|
---|
339 | }
|
---|
340 |
|
---|
341 | // Deriving reflection from linked plane?
|
---|
342 | if (mReflect && mLinkedReflectPlane &&
|
---|
343 | !(mLastLinkedReflectionPlane == mLinkedReflectPlane->_getDerivedPlane()))
|
---|
344 | {
|
---|
345 | mReflectPlane = mLinkedReflectPlane->_getDerivedPlane();
|
---|
346 | mReflectMatrix = Math::buildReflectionMatrix(mReflectPlane);
|
---|
347 | mLastLinkedReflectionPlane = mLinkedReflectPlane->_getDerivedPlane();
|
---|
348 | mRecalcView = true;
|
---|
349 | mRecalcWindow = true;
|
---|
350 | }
|
---|
351 |
|
---|
352 | // Deriving reflected orientation / position
|
---|
353 | if (mRecalcView)
|
---|
354 | {
|
---|
355 | if (mReflect)
|
---|
356 | {
|
---|
357 | // Calculate reflected orientation, use up-vector as fallback axis.
|
---|
358 | Vector3 dir = mRealOrientation * Vector3::NEGATIVE_UNIT_Z;
|
---|
359 | Vector3 rdir = dir.reflect(mReflectPlane.normal);
|
---|
360 | Vector3 up = mRealOrientation * Vector3::UNIT_Y;
|
---|
361 | mDerivedOrientation = dir.getRotationTo(rdir, up) * mRealOrientation;
|
---|
362 |
|
---|
363 | // Calculate reflected position.
|
---|
364 | mDerivedPosition = mReflectMatrix * mRealPosition;
|
---|
365 | }
|
---|
366 | else
|
---|
367 | {
|
---|
368 | mDerivedOrientation = mRealOrientation;
|
---|
369 | mDerivedPosition = mRealPosition;
|
---|
370 | }
|
---|
371 | }
|
---|
372 |
|
---|
373 | return mRecalcView;
|
---|
374 |
|
---|
375 | }
|
---|
376 |
|
---|
377 | // -------------------------------------------------------------------
|
---|
378 | void Camera::invalidateView() const
|
---|
379 | {
|
---|
380 | mRecalcWindow = true;
|
---|
381 | Frustum::invalidateView();
|
---|
382 | }
|
---|
383 | // -------------------------------------------------------------------
|
---|
384 | void Camera::invalidateFrustum(void) const
|
---|
385 | {
|
---|
386 | mRecalcWindow = true;
|
---|
387 | Frustum::invalidateFrustum();
|
---|
388 | }
|
---|
389 | //-----------------------------------------------------------------------
|
---|
390 | void Camera::_renderScene(Viewport *vp, bool includeOverlays)
|
---|
391 | {
|
---|
392 |
|
---|
393 | mSceneMgr->_renderScene(this, vp, includeOverlays);
|
---|
394 | }
|
---|
395 |
|
---|
396 |
|
---|
397 | //-----------------------------------------------------------------------
|
---|
398 | std::ostream& operator<<( std::ostream& o, Camera& c )
|
---|
399 | {
|
---|
400 | o << "Camera(Name='" << c.mName << "', pos=" << c.mPosition;
|
---|
401 | Vector3 dir(c.mOrientation*Vector3(0,0,-1));
|
---|
402 | o << ", direction=" << dir << ",near=" << c.mNearDist;
|
---|
403 | o << ", far=" << c.mFarDist << ", FOVy=" << c.mFOVy.valueDegrees();
|
---|
404 | o << ", aspect=" << c.mAspect << ", ";
|
---|
405 | o << ", xoffset=" << c.mFrustumOffset.x << ", yoffset=" << c.mFrustumOffset.y;
|
---|
406 | o << ", focalLength=" << c.mFocalLength << ", ";
|
---|
407 | o << "NearFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_NEAR] << ", ";
|
---|
408 | o << "FarFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_FAR] << ", ";
|
---|
409 | o << "LeftFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_LEFT] << ", ";
|
---|
410 | o << "RightFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_RIGHT] << ", ";
|
---|
411 | o << "TopFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_TOP] << ", ";
|
---|
412 | o << "BottomFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_BOTTOM];
|
---|
413 | o << ")";
|
---|
414 |
|
---|
415 | return o;
|
---|
416 | }
|
---|
417 |
|
---|
418 | //-----------------------------------------------------------------------
|
---|
419 | void Camera::setFixedYawAxis(bool useFixed, const Vector3& fixedAxis)
|
---|
420 | {
|
---|
421 | mYawFixed = useFixed;
|
---|
422 | mYawFixedAxis = fixedAxis;
|
---|
423 | }
|
---|
424 |
|
---|
425 | //-----------------------------------------------------------------------
|
---|
426 | void Camera::_notifyRenderedFaces(unsigned int numfaces)
|
---|
427 | {
|
---|
428 | mVisFacesLastRender = numfaces;
|
---|
429 | }
|
---|
430 |
|
---|
431 | //-----------------------------------------------------------------------
|
---|
432 | unsigned int Camera::_getNumRenderedFaces(void) const
|
---|
433 | {
|
---|
434 | return mVisFacesLastRender;
|
---|
435 | }
|
---|
436 |
|
---|
437 | //-----------------------------------------------------------------------
|
---|
438 | const Quaternion& Camera::getOrientation(void) const
|
---|
439 | {
|
---|
440 | return mOrientation;
|
---|
441 | }
|
---|
442 |
|
---|
443 | //-----------------------------------------------------------------------
|
---|
444 | void Camera::setOrientation(const Quaternion& q)
|
---|
445 | {
|
---|
446 | mOrientation = q;
|
---|
447 | invalidateView();
|
---|
448 | }
|
---|
449 | //-----------------------------------------------------------------------
|
---|
450 | const Quaternion& Camera::getDerivedOrientation(void) const
|
---|
451 | {
|
---|
452 | updateView();
|
---|
453 | return mDerivedOrientation;
|
---|
454 | }
|
---|
455 | //-----------------------------------------------------------------------
|
---|
456 | const Vector3& Camera::getDerivedPosition(void) const
|
---|
457 | {
|
---|
458 | updateView();
|
---|
459 | return mDerivedPosition;
|
---|
460 | }
|
---|
461 | //-----------------------------------------------------------------------
|
---|
462 | Vector3 Camera::getDerivedDirection(void) const
|
---|
463 | {
|
---|
464 | // Direction points down -Z
|
---|
465 | updateView();
|
---|
466 | return mDerivedOrientation * Vector3::NEGATIVE_UNIT_Z;
|
---|
467 | }
|
---|
468 | //-----------------------------------------------------------------------
|
---|
469 | Vector3 Camera::getDerivedUp(void) const
|
---|
470 | {
|
---|
471 | updateView();
|
---|
472 | return mDerivedOrientation * Vector3::UNIT_Y;
|
---|
473 | }
|
---|
474 | //-----------------------------------------------------------------------
|
---|
475 | Vector3 Camera::getDerivedRight(void) const
|
---|
476 | {
|
---|
477 | updateView();
|
---|
478 | return mDerivedOrientation * Vector3::UNIT_X;
|
---|
479 | }
|
---|
480 | //-----------------------------------------------------------------------
|
---|
481 | const Quaternion& Camera::getRealOrientation(void) const
|
---|
482 | {
|
---|
483 | updateView();
|
---|
484 | return mRealOrientation;
|
---|
485 | }
|
---|
486 | //-----------------------------------------------------------------------
|
---|
487 | const Vector3& Camera::getRealPosition(void) const
|
---|
488 | {
|
---|
489 | updateView();
|
---|
490 | return mRealPosition;
|
---|
491 | }
|
---|
492 | //-----------------------------------------------------------------------
|
---|
493 | Vector3 Camera::getRealDirection(void) const
|
---|
494 | {
|
---|
495 | // Direction points down -Z
|
---|
496 | updateView();
|
---|
497 | return mRealOrientation * Vector3::NEGATIVE_UNIT_Z;
|
---|
498 | }
|
---|
499 | //-----------------------------------------------------------------------
|
---|
500 | Vector3 Camera::getRealUp(void) const
|
---|
501 | {
|
---|
502 | updateView();
|
---|
503 | return mRealOrientation * Vector3::UNIT_Y;
|
---|
504 | }
|
---|
505 | //-----------------------------------------------------------------------
|
---|
506 | Vector3 Camera::getRealRight(void) const
|
---|
507 | {
|
---|
508 | updateView();
|
---|
509 | return mRealOrientation * Vector3::UNIT_X;
|
---|
510 | }
|
---|
511 | //-----------------------------------------------------------------------
|
---|
512 | const String& Camera::getMovableType(void) const
|
---|
513 | {
|
---|
514 | return msMovableType;
|
---|
515 | }
|
---|
516 | //-----------------------------------------------------------------------
|
---|
517 | void Camera::setAutoTracking(bool enabled, SceneNode* target,
|
---|
518 | const Vector3& offset)
|
---|
519 | {
|
---|
520 | if (enabled)
|
---|
521 | {
|
---|
522 | assert (target != 0 && "target cannot be a null pointer if tracking is enabled");
|
---|
523 | mAutoTrackTarget = target;
|
---|
524 | mAutoTrackOffset = offset;
|
---|
525 | }
|
---|
526 | else
|
---|
527 | {
|
---|
528 | mAutoTrackTarget = 0;
|
---|
529 | }
|
---|
530 | }
|
---|
531 | //-----------------------------------------------------------------------
|
---|
532 | void Camera::_autoTrack(void)
|
---|
533 | {
|
---|
534 | // NB assumes that all scene nodes have been updated
|
---|
535 | if (mAutoTrackTarget)
|
---|
536 | {
|
---|
537 | lookAt(mAutoTrackTarget->_getDerivedPosition() + mAutoTrackOffset);
|
---|
538 | }
|
---|
539 | }
|
---|
540 | //-----------------------------------------------------------------------
|
---|
541 | void Camera::setLodBias(Real factor)
|
---|
542 | {
|
---|
543 | assert(factor > 0.0f && "Bias factor must be > 0!");
|
---|
544 | mSceneLodFactor = factor;
|
---|
545 | mSceneLodFactorInv = 1.0f / factor;
|
---|
546 | }
|
---|
547 | //-----------------------------------------------------------------------
|
---|
548 | Real Camera::getLodBias(void) const
|
---|
549 | {
|
---|
550 | return mSceneLodFactor;
|
---|
551 | }
|
---|
552 | //-----------------------------------------------------------------------
|
---|
553 | Real Camera::_getLodBiasInverse(void) const
|
---|
554 | {
|
---|
555 | return mSceneLodFactorInv;
|
---|
556 | }
|
---|
557 | //-----------------------------------------------------------------------
|
---|
558 | Ray Camera::getCameraToViewportRay(Real screenX, Real screenY) const
|
---|
559 | {
|
---|
560 | Real centeredScreenX = (screenX - 0.5f);
|
---|
561 | Real centeredScreenY = (0.5f - screenY);
|
---|
562 |
|
---|
563 | Real normalizedSlope = Math::Tan(mFOVy / 2);
|
---|
564 | Real viewportYToWorldY = normalizedSlope * mNearDist * 2;
|
---|
565 | Real viewportXToWorldX = viewportYToWorldY * mAspect;
|
---|
566 |
|
---|
567 | Vector3 rayDirection, rayOrigin;
|
---|
568 | if (mProjType == PT_PERSPECTIVE)
|
---|
569 | {
|
---|
570 | // Frustum offset (at near plane)
|
---|
571 | Real nearFocal = mNearDist / mFocalLength;
|
---|
572 | Real offsetX = mFrustumOffset.x * nearFocal;
|
---|
573 | Real offsetY = mFrustumOffset.y * nearFocal;
|
---|
574 | // From camera centre
|
---|
575 | rayOrigin = getDerivedPosition();
|
---|
576 | // Point to perspective projected position
|
---|
577 | rayDirection.x = centeredScreenX * viewportXToWorldX + offsetX;
|
---|
578 | rayDirection.y = centeredScreenY * viewportYToWorldY + offsetY;
|
---|
579 | rayDirection.z = -mNearDist;
|
---|
580 | rayDirection = getDerivedOrientation() * rayDirection;
|
---|
581 | rayDirection.normalise();
|
---|
582 | }
|
---|
583 | else
|
---|
584 | {
|
---|
585 | // Ortho always parallel to point on screen
|
---|
586 | rayOrigin.x = centeredScreenX * viewportXToWorldX;
|
---|
587 | rayOrigin.y = centeredScreenY * viewportYToWorldY;
|
---|
588 | rayOrigin.z = 0.0f;
|
---|
589 | rayOrigin = getDerivedOrientation() * rayOrigin;
|
---|
590 | rayOrigin = getDerivedPosition() + rayOrigin;
|
---|
591 | rayDirection = getDerivedDirection();
|
---|
592 | }
|
---|
593 |
|
---|
594 | return Ray(rayOrigin, rayDirection);
|
---|
595 | }
|
---|
596 |
|
---|
597 | // -------------------------------------------------------------------
|
---|
598 | void Camera::setWindow (Real Left, Real Top, Real Right, Real Bottom)
|
---|
599 | {
|
---|
600 | mWLeft = Left;
|
---|
601 | mWTop = Top;
|
---|
602 | mWRight = Right;
|
---|
603 | mWBottom = Bottom;
|
---|
604 |
|
---|
605 | mWindowSet = true;
|
---|
606 | mRecalcWindow = true;
|
---|
607 | }
|
---|
608 | // -------------------------------------------------------------------
|
---|
609 | void Camera::resetWindow ()
|
---|
610 | {
|
---|
611 | mWindowSet = false;
|
---|
612 | }
|
---|
613 | // -------------------------------------------------------------------
|
---|
614 | void Camera::setWindowImpl() const
|
---|
615 | {
|
---|
616 | if (!mWindowSet || !mRecalcWindow)
|
---|
617 | return;
|
---|
618 |
|
---|
619 | // Calculate general projection parameters
|
---|
620 | Real vpLeft, vpRight, vpBottom, vpTop;
|
---|
621 | calcProjectionParameters(vpLeft, vpRight, vpBottom, vpTop);
|
---|
622 |
|
---|
623 | Real vpWidth = vpRight - vpLeft;
|
---|
624 | Real vpHeight = vpTop - vpBottom;
|
---|
625 |
|
---|
626 | Real wvpLeft = vpLeft + mWLeft * vpWidth;
|
---|
627 | Real wvpRight = vpLeft + mWRight * vpWidth;
|
---|
628 | Real wvpTop = vpTop - mWTop * vpHeight;
|
---|
629 | Real wvpBottom = vpTop - mWBottom * vpHeight;
|
---|
630 |
|
---|
631 | Vector3 vp_ul (wvpLeft, wvpTop, -mNearDist);
|
---|
632 | Vector3 vp_ur (wvpRight, wvpTop, -mNearDist);
|
---|
633 | Vector3 vp_bl (wvpLeft, wvpBottom, -mNearDist);
|
---|
634 | Vector3 vp_br (wvpRight, wvpBottom, -mNearDist);
|
---|
635 |
|
---|
636 | Matrix4 inv = mViewMatrix.inverse();
|
---|
637 |
|
---|
638 | Vector3 vw_ul = inv * vp_ul;
|
---|
639 | Vector3 vw_ur = inv * vp_ur;
|
---|
640 | Vector3 vw_bl = inv * vp_bl;
|
---|
641 | Vector3 vw_br = inv * vp_br;
|
---|
642 |
|
---|
643 | if (mProjType == PT_PERSPECTIVE)
|
---|
644 | {
|
---|
645 | Vector3 position = getPosition();
|
---|
646 | mWindowClipPlanes.push_back(Plane(position, vw_bl, vw_ul));
|
---|
647 | mWindowClipPlanes.push_back(Plane(position, vw_ul, vw_ur));
|
---|
648 | mWindowClipPlanes.push_back(Plane(position, vw_ur, vw_br));
|
---|
649 | mWindowClipPlanes.push_back(Plane(position, vw_br, vw_bl));
|
---|
650 | }
|
---|
651 | else
|
---|
652 | {
|
---|
653 | Vector3 x_axis(inv[0][0], inv[0][1], inv[0][2]);
|
---|
654 | Vector3 y_axis(inv[1][0], inv[1][1], inv[1][2]);
|
---|
655 | x_axis.normalise();
|
---|
656 | y_axis.normalise();
|
---|
657 | mWindowClipPlanes.push_back(Plane( x_axis, vw_bl));
|
---|
658 | mWindowClipPlanes.push_back(Plane(-x_axis, vw_ur));
|
---|
659 | mWindowClipPlanes.push_back(Plane( y_axis, vw_bl));
|
---|
660 | mWindowClipPlanes.push_back(Plane(-y_axis, vw_ur));
|
---|
661 | }
|
---|
662 |
|
---|
663 | mRecalcWindow = false;
|
---|
664 |
|
---|
665 | }
|
---|
666 | // -------------------------------------------------------------------
|
---|
667 | const std::vector<Plane>& Camera::getWindowPlanes(void) const
|
---|
668 | {
|
---|
669 | updateView();
|
---|
670 | setWindowImpl();
|
---|
671 | return mWindowClipPlanes;
|
---|
672 | }
|
---|
673 | // -------------------------------------------------------------------
|
---|
674 | Real Camera::getBoundingRadius(void) const
|
---|
675 | {
|
---|
676 | // return a little bigger than the near distance
|
---|
677 | // just to keep things just outside
|
---|
678 | return mNearDist * 1.5;
|
---|
679 |
|
---|
680 | }
|
---|
681 | //-----------------------------------------------------------------------
|
---|
682 | const Vector3& Camera::getPositionForViewUpdate(void) const
|
---|
683 | {
|
---|
684 | // Note no update, because we're calling this from the update!
|
---|
685 | return mRealPosition;
|
---|
686 | }
|
---|
687 | //-----------------------------------------------------------------------
|
---|
688 | const Quaternion& Camera::getOrientationForViewUpdate(void) const
|
---|
689 | {
|
---|
690 | return mRealOrientation;
|
---|
691 | }
|
---|
692 | //-----------------------------------------------------------------------
|
---|
693 | bool Camera::getAutoAspectRatio(void) const
|
---|
694 | {
|
---|
695 | return mAutoAspectRatio;
|
---|
696 | }
|
---|
697 | //-----------------------------------------------------------------------
|
---|
698 | void Camera::setAutoAspectRatio(bool autoratio)
|
---|
699 | {
|
---|
700 | mAutoAspectRatio = autoratio;
|
---|
701 | }
|
---|
702 | //-----------------------------------------------------------------------
|
---|
703 | bool Camera::isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy) const
|
---|
704 | {
|
---|
705 | if (mCullFrustum)
|
---|
706 | {
|
---|
707 | return mCullFrustum->isVisible(bound, culledBy);
|
---|
708 | }
|
---|
709 | else
|
---|
710 | {
|
---|
711 | return Frustum::isVisible(bound, culledBy);
|
---|
712 | }
|
---|
713 | }
|
---|
714 | //-----------------------------------------------------------------------
|
---|
715 | bool Camera::isVisible(const Sphere& bound, FrustumPlane* culledBy) const
|
---|
716 | {
|
---|
717 | if (mCullFrustum)
|
---|
718 | {
|
---|
719 | return mCullFrustum->isVisible(bound, culledBy);
|
---|
720 | }
|
---|
721 | else
|
---|
722 | {
|
---|
723 | return Frustum::isVisible(bound, culledBy);
|
---|
724 | }
|
---|
725 | }
|
---|
726 | //-----------------------------------------------------------------------
|
---|
727 | bool Camera::isVisible(const Vector3& vert, FrustumPlane* culledBy) const
|
---|
728 | {
|
---|
729 | if (mCullFrustum)
|
---|
730 | {
|
---|
731 | return mCullFrustum->isVisible(vert, culledBy);
|
---|
732 | }
|
---|
733 | else
|
---|
734 | {
|
---|
735 | return Frustum::isVisible(vert, culledBy);
|
---|
736 | }
|
---|
737 | }
|
---|
738 | //-----------------------------------------------------------------------
|
---|
739 | const Vector3* Camera::getWorldSpaceCorners(void) const
|
---|
740 | {
|
---|
741 | if (mCullFrustum)
|
---|
742 | {
|
---|
743 | return mCullFrustum->getWorldSpaceCorners();
|
---|
744 | }
|
---|
745 | else
|
---|
746 | {
|
---|
747 | return Frustum::getWorldSpaceCorners();
|
---|
748 | }
|
---|
749 | }
|
---|
750 | //-----------------------------------------------------------------------
|
---|
751 | const Plane& Camera::getFrustumPlane( unsigned short plane ) const
|
---|
752 | {
|
---|
753 | if (mCullFrustum)
|
---|
754 | {
|
---|
755 | return mCullFrustum->getFrustumPlane(plane);
|
---|
756 | }
|
---|
757 | else
|
---|
758 | {
|
---|
759 | return Frustum::getFrustumPlane(plane);
|
---|
760 | }
|
---|
761 | }
|
---|
762 | //-----------------------------------------------------------------------
|
---|
763 | bool Camera::projectSphere(const Sphere& sphere,
|
---|
764 | Real* left, Real* top, Real* right, Real* bottom) const
|
---|
765 | {
|
---|
766 | if (mCullFrustum)
|
---|
767 | {
|
---|
768 | return mCullFrustum->projectSphere(sphere, left, top, right, bottom);
|
---|
769 | }
|
---|
770 | else
|
---|
771 | {
|
---|
772 | return Frustum::projectSphere(sphere, left, top, right, bottom);
|
---|
773 | }
|
---|
774 | }
|
---|
775 | //-----------------------------------------------------------------------
|
---|
776 | Real Camera::getNearClipDistance(void) const
|
---|
777 | {
|
---|
778 | if (mCullFrustum)
|
---|
779 | {
|
---|
780 | return mCullFrustum->getNearClipDistance();
|
---|
781 | }
|
---|
782 | else
|
---|
783 | {
|
---|
784 | return Frustum::getNearClipDistance();
|
---|
785 | }
|
---|
786 | }
|
---|
787 | //-----------------------------------------------------------------------
|
---|
788 | Real Camera::getFarClipDistance(void) const
|
---|
789 | {
|
---|
790 | if (mCullFrustum)
|
---|
791 | {
|
---|
792 | return mCullFrustum->getFarClipDistance();
|
---|
793 | }
|
---|
794 | else
|
---|
795 | {
|
---|
796 | return Frustum::getFarClipDistance();
|
---|
797 | }
|
---|
798 | }
|
---|
799 | //-----------------------------------------------------------------------
|
---|
800 | const Matrix4& Camera::getViewMatrix(void) const
|
---|
801 | {
|
---|
802 | if (mCullFrustum)
|
---|
803 | {
|
---|
804 | return mCullFrustum->getViewMatrix();
|
---|
805 | }
|
---|
806 | else
|
---|
807 | {
|
---|
808 | return Frustum::getViewMatrix();
|
---|
809 | }
|
---|
810 | }
|
---|
811 | //-----------------------------------------------------------------------
|
---|
812 | const Matrix4& Camera::getViewMatrix(bool ownFrustumOnly) const
|
---|
813 | {
|
---|
814 | if (ownFrustumOnly)
|
---|
815 | {
|
---|
816 | return Frustum::getViewMatrix();
|
---|
817 | }
|
---|
818 | else
|
---|
819 | {
|
---|
820 | return getViewMatrix();
|
---|
821 | }
|
---|
822 | }
|
---|
823 | //-----------------------------------------------------------------------
|
---|
824 |
|
---|
825 |
|
---|
826 |
|
---|
827 | } // namespace Ogre
|
---|