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