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 | {
|
---|
46 | // Init camera location & direction
|
---|
47 |
|
---|
48 | // Locate at (0,0,0)
|
---|
49 | mPosition.x = mPosition.y = mPosition.z = 0;
|
---|
50 | // Point down -Z axis
|
---|
51 | mOrientation = Quaternion::IDENTITY;
|
---|
52 |
|
---|
53 |
|
---|
54 | // Reasonable defaults to camera params
|
---|
55 | mFOVy = Radian(Math::PI/4.0);
|
---|
56 | mNearDist = 100.0f;
|
---|
57 | mFarDist = 100000.0f;
|
---|
58 | mAspect = 1.33333333333333f;
|
---|
59 | mProjType = PT_PERSPECTIVE;
|
---|
60 | mSceneDetail = SDL_SOLID;
|
---|
61 | setFixedYawAxis(true); // Default to fixed yaw, like freelook since most people expect this
|
---|
62 |
|
---|
63 | invalidateFrustum();
|
---|
64 | invalidateView();
|
---|
65 |
|
---|
66 | // Init matrices
|
---|
67 | mViewMatrix = Matrix4::ZERO;
|
---|
68 | mProjMatrix = Matrix4::ZERO;
|
---|
69 |
|
---|
70 | mParentNode = 0;
|
---|
71 |
|
---|
72 | // Record SceneManager
|
---|
73 | mSceneMgr = sm;
|
---|
74 |
|
---|
75 | // Init no tracking
|
---|
76 | mAutoTrackTarget = 0;
|
---|
77 |
|
---|
78 | // Init lod
|
---|
79 | mSceneLodFactor = mSceneLodFactorInv = 1.0f;
|
---|
80 |
|
---|
81 | // no reflection
|
---|
82 | mReflect = false;
|
---|
83 |
|
---|
84 | mVisible = false;
|
---|
85 |
|
---|
86 |
|
---|
87 | mWindowSet = false;
|
---|
88 | mAutoAspectRatio = false;
|
---|
89 | }
|
---|
90 |
|
---|
91 | //-----------------------------------------------------------------------
|
---|
92 | Camera::~Camera()
|
---|
93 | {
|
---|
94 | // Do nothing
|
---|
95 | }
|
---|
96 |
|
---|
97 | //-----------------------------------------------------------------------
|
---|
98 | SceneManager* Camera::getSceneManager(void) const
|
---|
99 | {
|
---|
100 | return mSceneMgr;
|
---|
101 | }
|
---|
102 | //-----------------------------------------------------------------------
|
---|
103 | const String& Camera::getName(void) const
|
---|
104 | {
|
---|
105 | return mName;
|
---|
106 | }
|
---|
107 |
|
---|
108 |
|
---|
109 | //-----------------------------------------------------------------------
|
---|
110 | void Camera::setDetailLevel(SceneDetailLevel sd)
|
---|
111 | {
|
---|
112 | mSceneDetail = sd;
|
---|
113 | }
|
---|
114 |
|
---|
115 | //-----------------------------------------------------------------------
|
---|
116 | SceneDetailLevel Camera::getDetailLevel(void) const
|
---|
117 | {
|
---|
118 | return mSceneDetail;
|
---|
119 | }
|
---|
120 |
|
---|
121 | //-----------------------------------------------------------------------
|
---|
122 | void Camera::setPosition(Real x, Real y, Real z)
|
---|
123 | {
|
---|
124 | mPosition.x = x;
|
---|
125 | mPosition.y = y;
|
---|
126 | mPosition.z = z;
|
---|
127 | invalidateView();
|
---|
128 | }
|
---|
129 |
|
---|
130 | //-----------------------------------------------------------------------
|
---|
131 | void Camera::setPosition(const Vector3& vec)
|
---|
132 | {
|
---|
133 | mPosition = vec;
|
---|
134 | invalidateView();
|
---|
135 | }
|
---|
136 |
|
---|
137 | //-----------------------------------------------------------------------
|
---|
138 | const Vector3& Camera::getPosition(void) const
|
---|
139 | {
|
---|
140 | return mPosition;
|
---|
141 | }
|
---|
142 |
|
---|
143 | //-----------------------------------------------------------------------
|
---|
144 | void Camera::move(const Vector3& vec)
|
---|
145 | {
|
---|
146 | mPosition = mPosition + vec;
|
---|
147 | invalidateView();
|
---|
148 | }
|
---|
149 |
|
---|
150 | //-----------------------------------------------------------------------
|
---|
151 | void Camera::moveRelative(const Vector3& vec)
|
---|
152 | {
|
---|
153 | // Transform the axes of the relative vector by camera's local axes
|
---|
154 | Vector3 trans = mOrientation * vec;
|
---|
155 |
|
---|
156 | mPosition = mPosition + trans;
|
---|
157 | invalidateView();
|
---|
158 | }
|
---|
159 |
|
---|
160 | //-----------------------------------------------------------------------
|
---|
161 | void Camera::setDirection(Real x, Real y, Real z)
|
---|
162 | {
|
---|
163 | setDirection(Vector3(x,y,z));
|
---|
164 | }
|
---|
165 |
|
---|
166 | //-----------------------------------------------------------------------
|
---|
167 | void Camera::setDirection(const Vector3& vec)
|
---|
168 | {
|
---|
169 | // Do nothing if given a zero vector
|
---|
170 | // (Replaced assert since this could happen with auto tracking camera and
|
---|
171 | // camera passes through the lookAt point)
|
---|
172 | if (vec == Vector3::ZERO) return;
|
---|
173 |
|
---|
174 | // Remember, camera points down -Z of local axes!
|
---|
175 | // Therefore reverse direction of direction vector before determining local Z
|
---|
176 | Vector3 zAdjustVec = -vec;
|
---|
177 | zAdjustVec.normalise();
|
---|
178 |
|
---|
179 |
|
---|
180 | if( mYawFixed )
|
---|
181 | {
|
---|
182 | Vector3 xVec = mYawFixedAxis.crossProduct( zAdjustVec );
|
---|
183 | xVec.normalise();
|
---|
184 |
|
---|
185 | Vector3 yVec = zAdjustVec.crossProduct( xVec );
|
---|
186 | yVec.normalise();
|
---|
187 |
|
---|
188 | mOrientation.FromAxes( xVec, yVec, zAdjustVec );
|
---|
189 | }
|
---|
190 | else
|
---|
191 | {
|
---|
192 |
|
---|
193 | // Get axes from current quaternion
|
---|
194 | Vector3 axes[3];
|
---|
195 | updateView();
|
---|
196 | mDerivedOrientation.ToAxes(axes);
|
---|
197 | Quaternion rotQuat;
|
---|
198 | if ( (axes[2]+zAdjustVec).squaredLength() < 0.00005f)
|
---|
199 | {
|
---|
200 | // Oops, a 180 degree turn (infinite possible rotation axes)
|
---|
201 | // Default to yaw i.e. use current UP
|
---|
202 | rotQuat.FromAngleAxis(Radian(Math::PI), axes[1]);
|
---|
203 | }
|
---|
204 | else
|
---|
205 | {
|
---|
206 | // Derive shortest arc to new direction
|
---|
207 | rotQuat = axes[2].getRotationTo(zAdjustVec);
|
---|
208 |
|
---|
209 | }
|
---|
210 | mOrientation = rotQuat * mOrientation;
|
---|
211 | }
|
---|
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 - mDerivedPosition);
|
---|
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 | void Camera::updateFrustum(void) const
|
---|
316 | {
|
---|
317 | Frustum::updateFrustum();
|
---|
318 | // Set the clipping planes
|
---|
319 | setWindowImpl();
|
---|
320 | }
|
---|
321 |
|
---|
322 | //-----------------------------------------------------------------------
|
---|
323 | bool Camera::isViewOutOfDate(void) const
|
---|
324 | {
|
---|
325 | bool returnVal = false;
|
---|
326 | // Overridden from Frustum to use local orientation / position offsets
|
---|
327 | // Attached to node?
|
---|
328 | if (mParentNode != 0)
|
---|
329 | {
|
---|
330 | if (!mRecalcView && mParentNode->_getDerivedOrientation() == mLastParentOrientation &&
|
---|
331 | mParentNode->_getDerivedPosition() == mLastParentPosition)
|
---|
332 | {
|
---|
333 | returnVal = false;
|
---|
334 | }
|
---|
335 | else
|
---|
336 | {
|
---|
337 | // Ok, we're out of date with SceneNode we're attached to
|
---|
338 | mLastParentOrientation = mParentNode->_getDerivedOrientation();
|
---|
339 | mLastParentPosition = mParentNode->_getDerivedPosition();
|
---|
340 | mDerivedOrientation = mLastParentOrientation * mOrientation;
|
---|
341 | mDerivedPosition = (mLastParentOrientation * mPosition) + mLastParentPosition;
|
---|
342 | returnVal = true;
|
---|
343 | }
|
---|
344 | }
|
---|
345 | else
|
---|
346 | {
|
---|
347 | // Rely on own updates
|
---|
348 | mDerivedOrientation = mOrientation;
|
---|
349 | mDerivedPosition = mPosition;
|
---|
350 | }
|
---|
351 |
|
---|
352 | // Deriving reflection from linked plane?
|
---|
353 | if (mReflect && mLinkedReflectPlane &&
|
---|
354 | !(mLastLinkedReflectionPlane == mLinkedReflectPlane->_getDerivedPlane()))
|
---|
355 | {
|
---|
356 | mReflectPlane = mLinkedReflectPlane->_getDerivedPlane();
|
---|
357 | mReflectMatrix = Math::buildReflectionMatrix(mReflectPlane);
|
---|
358 | mLastLinkedReflectionPlane = mLinkedReflectPlane->_getDerivedPlane();
|
---|
359 | returnVal = true;
|
---|
360 | }
|
---|
361 |
|
---|
362 | return returnVal || mRecalcView;
|
---|
363 |
|
---|
364 | }
|
---|
365 |
|
---|
366 |
|
---|
367 | //-----------------------------------------------------------------------
|
---|
368 | void Camera::updateView(void) const
|
---|
369 | {
|
---|
370 | Frustum::updateView();
|
---|
371 | setWindowImpl();
|
---|
372 |
|
---|
373 | }
|
---|
374 | // -------------------------------------------------------------------
|
---|
375 | void Camera::invalidateView() const
|
---|
376 | {
|
---|
377 | mRecalcView = true;
|
---|
378 | mRecalcWindow = true;
|
---|
379 | }
|
---|
380 | // -------------------------------------------------------------------
|
---|
381 | void Camera::invalidateFrustum(void) const
|
---|
382 | {
|
---|
383 | mRecalcFrustum = true;
|
---|
384 | mRecalcWindow = true;
|
---|
385 | }
|
---|
386 | //-----------------------------------------------------------------------
|
---|
387 | void Camera::_renderScene(Viewport *vp, bool includeOverlays)
|
---|
388 | {
|
---|
389 |
|
---|
390 | mSceneMgr->_renderScene(this, vp, includeOverlays);
|
---|
391 | }
|
---|
392 |
|
---|
393 |
|
---|
394 | //-----------------------------------------------------------------------
|
---|
395 | std::ostream& operator<<( std::ostream& o, Camera& c )
|
---|
396 | {
|
---|
397 | o << "Camera(Name='" << c.mName << "', pos=" << c.mPosition;
|
---|
398 | Vector3 dir(c.mOrientation*Vector3(0,0,-1));
|
---|
399 | o << ", direction=" << dir << ",near=" << c.mNearDist;
|
---|
400 | o << ", far=" << c.mFarDist << ", FOVy=" << c.mFOVy.valueDegrees();
|
---|
401 | o << ", aspect=" << c.mAspect << ", ";
|
---|
402 | o << "NearFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_NEAR] << ", ";
|
---|
403 | o << "FarFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_FAR] << ", ";
|
---|
404 | o << "LeftFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_LEFT] << ", ";
|
---|
405 | o << "RightFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_RIGHT] << ", ";
|
---|
406 | o << "TopFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_TOP] << ", ";
|
---|
407 | o << "BottomFrustumPlane=" << c.mFrustumPlanes[FRUSTUM_PLANE_BOTTOM];
|
---|
408 | o << ")";
|
---|
409 |
|
---|
410 | return o;
|
---|
411 | }
|
---|
412 |
|
---|
413 | //-----------------------------------------------------------------------
|
---|
414 | void Camera::setFixedYawAxis(bool useFixed, const Vector3& fixedAxis)
|
---|
415 | {
|
---|
416 | mYawFixed = useFixed;
|
---|
417 | mYawFixedAxis = fixedAxis;
|
---|
418 | }
|
---|
419 |
|
---|
420 | //-----------------------------------------------------------------------
|
---|
421 | void Camera::_notifyRenderedFaces(unsigned int numfaces)
|
---|
422 | {
|
---|
423 | mVisFacesLastRender = numfaces;
|
---|
424 | }
|
---|
425 |
|
---|
426 | //-----------------------------------------------------------------------
|
---|
427 | unsigned int Camera::_getNumRenderedFaces(void) const
|
---|
428 | {
|
---|
429 | return mVisFacesLastRender;
|
---|
430 | }
|
---|
431 |
|
---|
432 | //-----------------------------------------------------------------------
|
---|
433 | const Quaternion& Camera::getOrientation(void) const
|
---|
434 | {
|
---|
435 | return mOrientation;
|
---|
436 | }
|
---|
437 |
|
---|
438 | //-----------------------------------------------------------------------
|
---|
439 | void Camera::setOrientation(const Quaternion& q)
|
---|
440 | {
|
---|
441 | mOrientation = q;
|
---|
442 | invalidateView();
|
---|
443 | }
|
---|
444 | //-----------------------------------------------------------------------
|
---|
445 | const Quaternion& Camera::getDerivedOrientation(void) const
|
---|
446 | {
|
---|
447 | updateView();
|
---|
448 | return mDerivedOrientation;
|
---|
449 | }
|
---|
450 | //-----------------------------------------------------------------------
|
---|
451 | const Vector3& Camera::getDerivedPosition(void) const
|
---|
452 | {
|
---|
453 | updateView();
|
---|
454 | return mDerivedPosition;
|
---|
455 | }
|
---|
456 | //-----------------------------------------------------------------------
|
---|
457 | Vector3 Camera::getDerivedDirection(void) const
|
---|
458 | {
|
---|
459 | // Direction points down -Z by default
|
---|
460 | updateView();
|
---|
461 | return mDerivedOrientation * -Vector3::UNIT_Z;
|
---|
462 | }
|
---|
463 | //-----------------------------------------------------------------------
|
---|
464 | Vector3 Camera::getDerivedUp(void) const
|
---|
465 | {
|
---|
466 | updateView();
|
---|
467 | return mDerivedOrientation * Vector3::UNIT_Y;
|
---|
468 | }
|
---|
469 | //-----------------------------------------------------------------------
|
---|
470 | Vector3 Camera::getDerivedRight(void) const
|
---|
471 | {
|
---|
472 | updateView();
|
---|
473 | return mDerivedOrientation * Vector3::UNIT_X;
|
---|
474 | }
|
---|
475 | //-----------------------------------------------------------------------
|
---|
476 | const String& Camera::getMovableType(void) const
|
---|
477 | {
|
---|
478 | return msMovableType;
|
---|
479 | }
|
---|
480 | //-----------------------------------------------------------------------
|
---|
481 | void Camera::setAutoTracking(bool enabled, SceneNode* target,
|
---|
482 | const Vector3& offset)
|
---|
483 | {
|
---|
484 | if (enabled)
|
---|
485 | {
|
---|
486 | assert (target != 0 && "target cannot be a null pointer if tracking is enabled");
|
---|
487 | mAutoTrackTarget = target;
|
---|
488 | mAutoTrackOffset = offset;
|
---|
489 | }
|
---|
490 | else
|
---|
491 | {
|
---|
492 | mAutoTrackTarget = 0;
|
---|
493 | }
|
---|
494 | }
|
---|
495 | //-----------------------------------------------------------------------
|
---|
496 | void Camera::_autoTrack(void)
|
---|
497 | {
|
---|
498 | // NB assumes that all scene nodes have been updated
|
---|
499 | if (mAutoTrackTarget)
|
---|
500 | {
|
---|
501 | lookAt(mAutoTrackTarget->_getDerivedPosition() + mAutoTrackOffset);
|
---|
502 | }
|
---|
503 | }
|
---|
504 | //-----------------------------------------------------------------------
|
---|
505 | void Camera::setLodBias(Real factor)
|
---|
506 | {
|
---|
507 | assert(factor > 0.0f && "Bias factor must be > 0!");
|
---|
508 | mSceneLodFactor = factor;
|
---|
509 | mSceneLodFactorInv = 1.0f / factor;
|
---|
510 | }
|
---|
511 | //-----------------------------------------------------------------------
|
---|
512 | Real Camera::getLodBias(void) const
|
---|
513 | {
|
---|
514 | return mSceneLodFactor;
|
---|
515 | }
|
---|
516 | //-----------------------------------------------------------------------
|
---|
517 | Real Camera::_getLodBiasInverse(void) const
|
---|
518 | {
|
---|
519 | return mSceneLodFactorInv;
|
---|
520 | }
|
---|
521 | //-----------------------------------------------------------------------
|
---|
522 | Ray Camera::getCameraToViewportRay(Real screenX, Real screenY) const
|
---|
523 | {
|
---|
524 | Real centeredScreenX = (screenX - 0.5f);
|
---|
525 | Real centeredScreenY = (0.5f - screenY);
|
---|
526 |
|
---|
527 | Real normalizedSlope = Math::Tan(mFOVy / 2);
|
---|
528 | Real viewportYToWorldY = normalizedSlope * mNearDist * 2;
|
---|
529 | Real viewportXToWorldX = viewportYToWorldY * mAspect;
|
---|
530 |
|
---|
531 | Vector3 rayDirection, rayOrigin;
|
---|
532 | if (mProjType == PT_PERSPECTIVE)
|
---|
533 | {
|
---|
534 | // From camera centre
|
---|
535 | rayOrigin = getDerivedPosition();
|
---|
536 | // Point to perspective projected position
|
---|
537 | rayDirection.x = centeredScreenX * viewportXToWorldX;
|
---|
538 | rayDirection.y = centeredScreenY * viewportYToWorldY;
|
---|
539 | rayDirection.z = -mNearDist;
|
---|
540 | rayDirection = getDerivedOrientation() * rayDirection;
|
---|
541 | rayDirection.normalise();
|
---|
542 | }
|
---|
543 | else
|
---|
544 | {
|
---|
545 | // Ortho always parallel to point on screen
|
---|
546 | rayOrigin.x = centeredScreenX * viewportXToWorldX;
|
---|
547 | rayOrigin.y = centeredScreenY * viewportYToWorldY;
|
---|
548 | rayOrigin.z = 0.0f;
|
---|
549 | rayOrigin = getDerivedOrientation() * rayOrigin;
|
---|
550 | rayOrigin = getDerivedPosition() + rayOrigin;
|
---|
551 | rayDirection = getDerivedDirection();
|
---|
552 | }
|
---|
553 |
|
---|
554 | return Ray(rayOrigin, rayDirection);
|
---|
555 | }
|
---|
556 |
|
---|
557 | // -------------------------------------------------------------------
|
---|
558 | void Camera::setWindow (Real Left, Real Top, Real Right, Real Bottom)
|
---|
559 | {
|
---|
560 | mWLeft = Left;
|
---|
561 | mWTop = Top;
|
---|
562 | mWRight = Right;
|
---|
563 | mWBottom = Bottom;
|
---|
564 |
|
---|
565 | mWindowSet = true;
|
---|
566 | mRecalcWindow = true;
|
---|
567 |
|
---|
568 | invalidateView();
|
---|
569 | }
|
---|
570 | // -------------------------------------------------------------------
|
---|
571 | void Camera::resetWindow ()
|
---|
572 | {
|
---|
573 | mWindowSet = false;
|
---|
574 | }
|
---|
575 | // -------------------------------------------------------------------
|
---|
576 | void Camera::setWindowImpl() const
|
---|
577 | {
|
---|
578 | if (!mWindowSet || !mRecalcWindow)
|
---|
579 | return;
|
---|
580 |
|
---|
581 |
|
---|
582 | Radian thetaY ( mFOVy / 2.0f );
|
---|
583 | Real tanThetaY = Math::Tan(thetaY);
|
---|
584 | //Real thetaX = thetaY * mAspect;
|
---|
585 | Real tanThetaX = tanThetaY * mAspect;
|
---|
586 |
|
---|
587 | Real vpTop = tanThetaY * mNearDist;
|
---|
588 | Real vpLeft = -tanThetaX * mNearDist;
|
---|
589 | Real vpWidth = -2 * vpLeft;
|
---|
590 | Real vpHeight = 2 * vpTop;
|
---|
591 |
|
---|
592 | Real wvpLeft = vpLeft + mWLeft * vpWidth;
|
---|
593 | Real wvpRight = vpLeft + mWRight * vpWidth;
|
---|
594 | Real wvpTop = vpTop - mWTop * vpHeight;
|
---|
595 | Real wvpBottom = vpTop - mWBottom * vpHeight;
|
---|
596 |
|
---|
597 | Vector3 vp_ul (wvpLeft, wvpTop, -mNearDist);
|
---|
598 | Vector3 vp_ur (wvpRight, wvpTop, -mNearDist);
|
---|
599 | Vector3 vp_bl (wvpLeft, wvpBottom, -mNearDist);
|
---|
600 | Vector3 vp_br (wvpRight, wvpBottom, -mNearDist);
|
---|
601 |
|
---|
602 | Matrix4 inv = mViewMatrix.inverse();
|
---|
603 |
|
---|
604 | Vector3 vw_ul = inv * vp_ul;
|
---|
605 | Vector3 vw_ur = inv * vp_ur;
|
---|
606 | Vector3 vw_bl = inv * vp_bl;
|
---|
607 | Vector3 vw_br = inv * vp_br;
|
---|
608 |
|
---|
609 | Vector3 position = getPosition();
|
---|
610 |
|
---|
611 | mWindowClipPlanes.clear();
|
---|
612 | mWindowClipPlanes.push_back(Plane(position, vw_bl, vw_ul));
|
---|
613 | mWindowClipPlanes.push_back(Plane(position, vw_ul, vw_ur));
|
---|
614 | mWindowClipPlanes.push_back(Plane(position, vw_ur, vw_br));
|
---|
615 | mWindowClipPlanes.push_back(Plane(position, vw_br, vw_bl));
|
---|
616 |
|
---|
617 | mRecalcWindow = false;
|
---|
618 |
|
---|
619 | }
|
---|
620 | // -------------------------------------------------------------------
|
---|
621 | const std::vector<Plane>& Camera::getWindowPlanes(void) const
|
---|
622 | {
|
---|
623 | setWindowImpl();
|
---|
624 | return mWindowClipPlanes;
|
---|
625 | }
|
---|
626 | // -------------------------------------------------------------------
|
---|
627 | Real Camera::getBoundingRadius(void) const
|
---|
628 | {
|
---|
629 | // return a little bigger than the near distance
|
---|
630 | // just to keep things just outside
|
---|
631 | return mNearDist * 1.5;
|
---|
632 |
|
---|
633 | }
|
---|
634 | //-----------------------------------------------------------------------
|
---|
635 | const Vector3& Camera::getPositionForViewUpdate(void) const
|
---|
636 | {
|
---|
637 | // Note no update, because we're calling this from the update!
|
---|
638 | return mDerivedPosition;
|
---|
639 | }
|
---|
640 | //-----------------------------------------------------------------------
|
---|
641 | const Quaternion& Camera::getOrientationForViewUpdate(void) const
|
---|
642 | {
|
---|
643 | return mDerivedOrientation;
|
---|
644 | }
|
---|
645 | //-----------------------------------------------------------------------
|
---|
646 | bool Camera::getAutoAspectRatio(void) const
|
---|
647 | {
|
---|
648 | return mAutoAspectRatio;
|
---|
649 | }
|
---|
650 | //-----------------------------------------------------------------------
|
---|
651 | void Camera::setAutoAspectRatio(bool autoratio)
|
---|
652 | {
|
---|
653 | mAutoAspectRatio = autoratio;
|
---|
654 | }
|
---|
655 |
|
---|
656 | } // namespace Ogre
|
---|