00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2002 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreStableHeaders.h" 00026 #include "OgreNode.h" 00027 00028 #include "OgreException.h" 00029 #include "OgreMath.h" 00030 00031 // Dependencies on render-related types due to ability to render node 00032 #include "OgreMaterialManager.h" 00033 #include "OgreMeshManager.h" 00034 #include "OgreMesh.h" 00035 #include "OgreSubMesh.h" 00036 #include "OgreCamera.h" 00037 00038 namespace Ogre { 00039 00040 unsigned long Node::msNextGeneratedNameExt = 1; 00041 //----------------------------------------------------------------------- 00042 Node::Node() 00043 { 00044 mParent = 0; 00045 mOrientation = mInitialOrientation = mDerivedOrientation = Quaternion::IDENTITY; 00046 mPosition = mInitialPosition = mDerivedPosition = Vector3::ZERO; 00047 mScale = mInitialScale = mDerivedScale = Vector3::UNIT_SCALE; 00048 mInheritScale = true; 00049 mParentNotified = false ; 00050 00051 // Generate a name 00052 static char temp[64]; 00053 sprintf(temp, "Unnamed_%lu", msNextGeneratedNameExt++); 00054 mName = temp; 00055 mAccumAnimWeight = 0.0f; 00056 00057 needUpdate(); 00058 00059 } 00060 //----------------------------------------------------------------------- 00061 Node::Node(const String& name) 00062 { 00063 mName = name; 00064 mParent = 0; 00065 mOrientation = mInitialOrientation = mDerivedOrientation = Quaternion::IDENTITY; 00066 mPosition = mInitialPosition = mDerivedPosition = Vector3::ZERO; 00067 mScale = mInitialScale = mDerivedScale = Vector3::UNIT_SCALE; 00068 mInheritScale = true; 00069 mAccumAnimWeight = 0.0f; 00070 mParentNotified = false ; 00071 00072 needUpdate(); 00073 00074 } 00075 00076 //----------------------------------------------------------------------- 00077 Node::~Node() 00078 { 00079 } 00080 00081 //----------------------------------------------------------------------- 00082 Node* Node::getParent(void) const 00083 { 00084 return mParent; 00085 } 00086 00087 //----------------------------------------------------------------------- 00088 void Node::setParent(Node* parent) 00089 { 00090 mParent = parent; 00091 // Request update from parent 00092 mParentNotified = false ; 00093 needUpdate(); 00094 } 00095 00096 //----------------------------------------------------------------------- 00097 Matrix4 Node::_getFullTransform(void) const 00098 { 00099 if (mCachedTransformOutOfDate) 00100 { 00101 // Use derived values 00102 makeTransform( 00103 _getDerivedPosition(), _getDerivedScale(), 00104 _getDerivedOrientation(), mCachedTransform); 00105 mCachedTransformOutOfDate = false; 00106 } 00107 return mCachedTransform; 00108 } 00109 //----------------------------------------------------------------------- 00110 void Node::_update(bool updateChildren, bool parentHasChanged) 00111 { 00112 // always clear information about parent notification 00113 mParentNotified = false ; 00114 00115 // Short circuit the off case 00116 if (!updateChildren && !mNeedParentUpdate && !mNeedChildUpdate && !parentHasChanged ) 00117 { 00118 return; 00119 } 00120 00121 00122 // See if we should process everyone 00123 if (mNeedParentUpdate || parentHasChanged) 00124 { 00125 // Update transforms from parent 00126 _updateFromParent(); 00127 mNeedParentUpdate = false; 00128 } 00129 00130 if (mNeedChildUpdate || parentHasChanged) 00131 { 00132 00133 ChildNodeMap::iterator it, itend; 00134 itend = mChildren.end(); 00135 for (it = mChildren.begin(); it != itend; ++it) 00136 { 00137 Node* child = it->second; 00138 child->_update(true, true); 00139 } 00140 mChildrenToUpdate.clear(); 00141 } 00142 else 00143 { 00144 // Just update selected children 00145 00146 ChildUpdateSet::iterator it, itend; 00147 itend = mChildrenToUpdate.end(); 00148 for(it = mChildrenToUpdate.begin(); it != itend; ++it) 00149 { 00150 Node* child = *it; 00151 child->_update(true, false); 00152 } 00153 00154 mChildrenToUpdate.clear(); 00155 } 00156 00157 mNeedChildUpdate = false; 00158 00159 } 00160 00161 //----------------------------------------------------------------------- 00162 void Node::_updateFromParent(void) const 00163 { 00164 if (mParent) 00165 { 00166 // Combine orientation with that of parent 00167 Quaternion mParentQ = mParent->_getDerivedOrientation(); 00168 mDerivedOrientation = mParentQ * mOrientation; 00169 00170 // Change position vector based on parent's orientation & scale 00171 mDerivedPosition = mParentQ * (mPosition * mParent->_getDerivedScale()); 00172 00173 // Update scale 00174 if (mInheritScale) 00175 { 00176 // Scale own position by parent scale 00177 Vector3 parentScale = mParent->_getDerivedScale(); 00178 // Set own scale, NB just combine as equivalent axes, no shearing 00179 mDerivedScale = mScale * parentScale; 00180 00181 } 00182 else 00183 { 00184 // No inheritence 00185 mDerivedScale = mScale; 00186 } 00187 00188 // Add altered position vector to parents 00189 mDerivedPosition += mParent->_getDerivedPosition(); 00190 } 00191 else 00192 { 00193 // Root node, no parent 00194 mDerivedOrientation = mOrientation; 00195 mDerivedPosition = mPosition; 00196 mDerivedScale = mScale; 00197 } 00198 00199 mCachedTransformOutOfDate = true; 00200 00201 00202 } 00203 //----------------------------------------------------------------------- 00204 Node* Node::createChild(const Vector3& translate, const Quaternion& rotate) 00205 { 00206 Node* newNode = createChildImpl(); 00207 newNode->translate(translate); 00208 newNode->rotate(rotate); 00209 this->addChild(newNode); 00210 00211 return newNode; 00212 } 00213 //----------------------------------------------------------------------- 00214 Node* Node::createChild(const String& name, const Vector3& translate, const Quaternion& rotate) 00215 { 00216 Node* newNode = createChildImpl(name); 00217 newNode->translate(translate); 00218 newNode->rotate(rotate); 00219 this->addChild(newNode); 00220 00221 return newNode; 00222 } 00223 //----------------------------------------------------------------------- 00224 void Node::addChild(Node* child) 00225 { 00226 mChildren.insert(ChildNodeMap::value_type(child->getName(), child)); 00227 child->setParent(this); 00228 00229 } 00230 //----------------------------------------------------------------------- 00231 unsigned short Node::numChildren(void) const 00232 { 00233 return static_cast< unsigned short >( mChildren.size() ); 00234 } 00235 //----------------------------------------------------------------------- 00236 Node* Node::getChild(unsigned short index) const 00237 { 00238 if( index < mChildren.size() ) 00239 { 00240 ChildNodeMap::const_iterator i = mChildren.begin(); 00241 while (index--) ++i; 00242 return i->second; 00243 } 00244 else 00245 return NULL; 00246 } 00247 //----------------------------------------------------------------------- 00248 Node* Node::removeChild(unsigned short index) 00249 { 00250 Node* ret; 00251 if (index < mChildren.size()) 00252 { 00253 ChildNodeMap::iterator i = mChildren.begin(); 00254 while (index--) ++i; 00255 ret = i->second; 00256 // cancel any pending update 00257 cancelUpdate(ret); 00258 00259 mChildren.erase(i); 00260 ret->setParent(NULL); 00261 return ret; 00262 } 00263 else 00264 { 00265 Except( 00266 Exception::ERR_INVALIDPARAMS, 00267 "Child index out of bounds.", 00268 "Node::getChild" ); 00269 } 00270 return 0; 00271 } 00272 //----------------------------------------------------------------------- 00273 Node* Node::removeChild(Node* child) 00274 { 00275 ChildNodeMap::iterator i, iend; 00276 iend = mChildren.end(); 00277 for (i = mChildren.begin(); i != iend; ++i) 00278 { 00279 if (i->second == child) 00280 { 00281 // cancel any pending update 00282 cancelUpdate(child); 00283 00284 mChildren.erase(i); 00285 child->setParent(NULL); 00286 break; 00287 } 00288 } 00289 return child; 00290 } 00291 //----------------------------------------------------------------------- 00292 const Quaternion& Node::getOrientation() const 00293 { 00294 return mOrientation; 00295 } 00296 00297 //----------------------------------------------------------------------- 00298 void Node::setOrientation( const Quaternion & q ) 00299 { 00300 mOrientation = q; 00301 needUpdate(); 00302 } 00303 //----------------------------------------------------------------------- 00304 void Node::setOrientation( Real w, Real x, Real y, Real z) 00305 { 00306 mOrientation.w = w; 00307 mOrientation.x = x; 00308 mOrientation.y = y; 00309 mOrientation.z = z; 00310 needUpdate(); 00311 } 00312 //----------------------------------------------------------------------- 00313 void Node::resetOrientation(void) 00314 { 00315 mOrientation = Quaternion::IDENTITY; 00316 needUpdate(); 00317 } 00318 00319 //----------------------------------------------------------------------- 00320 void Node::setPosition(const Vector3& pos) 00321 { 00322 mPosition = pos; 00323 needUpdate(); 00324 } 00325 00326 00327 //----------------------------------------------------------------------- 00328 void Node::setPosition(Real x, Real y, Real z) 00329 { 00330 Vector3 v(x,y,z); 00331 setPosition(v); 00332 } 00333 00334 //----------------------------------------------------------------------- 00335 const Vector3 & Node::getPosition(void) const 00336 { 00337 return mPosition; 00338 } 00339 //----------------------------------------------------------------------- 00340 Matrix3 Node::getLocalAxes(void) const 00341 { 00342 Vector3 axisX = Vector3::UNIT_X; 00343 Vector3 axisY = Vector3::UNIT_Y; 00344 Vector3 axisZ = Vector3::UNIT_Z; 00345 00346 axisX = mOrientation * axisX; 00347 axisY = mOrientation * axisY; 00348 axisZ = mOrientation * axisZ; 00349 00350 return Matrix3(axisX.x, axisY.x, axisZ.x, 00351 axisX.y, axisY.y, axisZ.y, 00352 axisX.z, axisY.z, axisZ.z); 00353 } 00354 00355 //----------------------------------------------------------------------- 00356 void Node::translate(const Vector3& d, TransformSpace relativeTo) 00357 { 00358 Vector3 adjusted; 00359 switch(relativeTo) 00360 { 00361 case TS_LOCAL: 00362 // position is relative to parent so transform downwards 00363 mPosition += mOrientation * d; 00364 break; 00365 case TS_WORLD: 00366 // position is relative to parent so transform upwards 00367 if (mParent) 00368 { 00369 mPosition += mParent->_getDerivedOrientation().Inverse() * d; 00370 } 00371 else 00372 { 00373 mPosition += d; 00374 } 00375 break; 00376 case TS_PARENT: 00377 mPosition += d; 00378 break; 00379 } 00380 needUpdate(); 00381 00382 } 00383 //----------------------------------------------------------------------- 00384 void Node::translate(Real x, Real y, Real z, TransformSpace relativeTo) 00385 { 00386 Vector3 v(x,y,z); 00387 translate(v, relativeTo); 00388 } 00389 //----------------------------------------------------------------------- 00390 void Node::translate(const Matrix3& axes, const Vector3& move, TransformSpace relativeTo) 00391 { 00392 Vector3 derived = axes * move; 00393 translate(derived, relativeTo); 00394 } 00395 //----------------------------------------------------------------------- 00396 void Node::translate(const Matrix3& axes, Real x, Real y, Real z, TransformSpace relativeTo) 00397 { 00398 Vector3 d(x,y,z); 00399 translate(axes,d,relativeTo); 00400 } 00401 //----------------------------------------------------------------------- 00402 void Node::roll(const Radian& angle, TransformSpace relativeTo) 00403 { 00404 rotate(Vector3::UNIT_Z, angle, relativeTo); 00405 } 00406 //----------------------------------------------------------------------- 00407 void Node::pitch(const Radian& angle, TransformSpace relativeTo) 00408 { 00409 rotate(Vector3::UNIT_X, angle, relativeTo); 00410 } 00411 //----------------------------------------------------------------------- 00412 void Node::yaw(const Radian& angle, TransformSpace relativeTo) 00413 { 00414 rotate(Vector3::UNIT_Y, angle, relativeTo); 00415 00416 } 00417 //----------------------------------------------------------------------- 00418 void Node::rotate(const Vector3& axis, const Radian& angle, TransformSpace relativeTo) 00419 { 00420 Quaternion q; 00421 q.FromAngleAxis(angle,axis); 00422 rotate(q, relativeTo); 00423 } 00424 00425 //----------------------------------------------------------------------- 00426 void Node::rotate(const Quaternion& q, TransformSpace relativeTo) 00427 { 00428 switch(relativeTo) 00429 { 00430 case TS_PARENT: 00431 // Rotations are normally relative to local axes, transform up 00432 mOrientation = q * mOrientation; 00433 break; 00434 case TS_WORLD: 00435 // Rotations are normally relative to local axes, transform up 00436 mOrientation = mOrientation * _getDerivedOrientation().Inverse() 00437 * q * _getDerivedOrientation(); 00438 break; 00439 case TS_LOCAL: 00440 // Note the order of the mult, i.e. q comes after 00441 mOrientation = mOrientation * q; 00442 break; 00443 } 00444 needUpdate(); 00445 } 00446 //----------------------------------------------------------------------- 00447 const Quaternion & Node::_getDerivedOrientation(void) const 00448 { 00449 if (mNeedParentUpdate) 00450 { 00451 _updateFromParent(); 00452 mNeedParentUpdate = false; 00453 } 00454 return mDerivedOrientation; 00455 } 00456 //----------------------------------------------------------------------- 00457 const Vector3 & Node::_getDerivedPosition(void) const 00458 { 00459 if (mNeedParentUpdate) 00460 { 00461 _updateFromParent(); 00462 mNeedParentUpdate = false; 00463 } 00464 return mDerivedPosition; 00465 } 00466 //----------------------------------------------------------------------- 00467 const Vector3 & Node::_getDerivedScale(void) const 00468 { 00469 return mDerivedScale; 00470 } 00471 //----------------------------------------------------------------------- 00472 void Node::removeAllChildren(void) 00473 { 00474 mChildren.clear(); 00475 } 00476 //----------------------------------------------------------------------- 00477 void Node::setScale(const Vector3& scale) 00478 { 00479 mScale = scale; 00480 needUpdate(); 00481 } 00482 //----------------------------------------------------------------------- 00483 void Node::setScale(Real x, Real y, Real z) 00484 { 00485 mScale.x = x; 00486 mScale.y = y; 00487 mScale.z = z; 00488 needUpdate(); 00489 } 00490 //----------------------------------------------------------------------- 00491 const Vector3 & Node::getScale(void) const 00492 { 00493 return mScale; 00494 } 00495 //----------------------------------------------------------------------- 00496 void Node::setInheritScale(bool inherit) 00497 { 00498 mInheritScale = inherit; 00499 needUpdate(); 00500 } 00501 //----------------------------------------------------------------------- 00502 bool Node::getInheritScale(void) const 00503 { 00504 return mInheritScale; 00505 } 00506 //----------------------------------------------------------------------- 00507 void Node::scale(const Vector3& scale) 00508 { 00509 mScale = mScale * scale; 00510 needUpdate(); 00511 00512 } 00513 //----------------------------------------------------------------------- 00514 void Node::scale(Real x, Real y, Real z) 00515 { 00516 mScale.x *= x; 00517 mScale.y *= y; 00518 mScale.z *= z; 00519 needUpdate(); 00520 00521 } 00522 //----------------------------------------------------------------------- 00523 void Node::makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation, 00524 Matrix4& destMatrix) const 00525 { 00526 destMatrix = Matrix4::IDENTITY; 00527 // Ordering: 00528 // 1. Scale 00529 // 2. Rotate 00530 // 3. Translate 00531 00532 // Parent scaling is already applied to derived position 00533 // Own scale is applied before rotation 00534 Matrix3 rot3x3, scale3x3; 00535 orientation.ToRotationMatrix(rot3x3); 00536 scale3x3 = Matrix3::ZERO; 00537 scale3x3[0][0] = scale.x; 00538 scale3x3[1][1] = scale.y; 00539 scale3x3[2][2] = scale.z; 00540 00541 destMatrix = rot3x3 * scale3x3; 00542 destMatrix.setTrans(position); 00543 } 00544 //----------------------------------------------------------------------- 00545 void Node::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation, 00546 Matrix4& destMatrix) 00547 { 00548 destMatrix = Matrix4::IDENTITY; 00549 00550 // Invert the parameters 00551 Vector3 invTranslate = -position; 00552 Vector3 invScale; 00553 invScale.x = 1 / scale.x; 00554 invScale.y = 1 / scale.y; 00555 invScale.z = 1 / scale.z; 00556 00557 Quaternion invRot = orientation.Inverse(); 00558 00559 // Because we're inverting, order is translation, rotation, scale 00560 // So make translation relative to scale & rotation 00561 invTranslate.x *= invScale.x; // scale 00562 invTranslate.y *= invScale.y; // scale 00563 invTranslate.z *= invScale.z; // scale 00564 invTranslate = invRot * invTranslate; // rotate 00565 00566 // Next, make a 3x3 rotation matrix and apply inverse scale 00567 Matrix3 rot3x3, scale3x3; 00568 invRot.ToRotationMatrix(rot3x3); 00569 scale3x3 = Matrix3::ZERO; 00570 scale3x3[0][0] = invScale.x; 00571 scale3x3[1][1] = invScale.y; 00572 scale3x3[2][2] = invScale.z; 00573 00574 // Set up final matrix with scale & rotation 00575 destMatrix = scale3x3 * rot3x3; 00576 00577 destMatrix.setTrans(invTranslate); 00578 } 00579 //----------------------------------------------------------------------- 00580 const String& Node::getName(void) const 00581 { 00582 return mName; 00583 } 00584 //----------------------------------------------------------------------- 00585 Material* Node::getMaterial(void) const 00586 { 00587 static Material* pMaterial = 0; 00588 00589 if (!pMaterial) 00590 { 00591 pMaterial = (Material*)MaterialManager::getSingleton().getByName("Core/NodeMaterial"); 00592 if (!pMaterial) 00593 Except( Exception::ERR_ITEM_NOT_FOUND, "Could not find material Core/NodeMaterial", 00594 "Node::getMaterial" ); 00595 pMaterial->load(); 00596 } 00597 return pMaterial; 00598 00599 } 00600 //----------------------------------------------------------------------- 00601 void Node::getRenderOperation(RenderOperation& op) 00602 { 00603 static SubMesh* pSubMesh = 0; 00604 if (!pSubMesh) 00605 { 00606 Mesh *pMesh = MeshManager::getSingleton().load("axes.mesh"); 00607 pSubMesh = pMesh->getSubMesh(0); 00608 } 00609 pSubMesh->_getRenderOperation(op); 00610 } 00611 //----------------------------------------------------------------------- 00612 void Node::getWorldTransforms(Matrix4* xform) const 00613 { 00614 // Assumes up to date 00615 *xform = this->_getFullTransform(); 00616 } 00617 //----------------------------------------------------------------------- 00618 const Quaternion& Node::getWorldOrientation(void) const 00619 { 00620 return _getDerivedOrientation(); 00621 } 00622 //----------------------------------------------------------------------- 00623 const Vector3& Node::getWorldPosition(void) const 00624 { 00625 return _getDerivedPosition(); 00626 } 00627 //----------------------------------------------------------------------- 00628 void Node::setInitialState(void) 00629 { 00630 mInitialPosition = mPosition; 00631 mInitialOrientation = mOrientation; 00632 mInitialScale = mScale; 00633 } 00634 //----------------------------------------------------------------------- 00635 void Node::resetToInitialState(void) 00636 { 00637 mPosition = mInitialPosition; 00638 mOrientation = mInitialOrientation; 00639 mScale = mInitialScale; 00640 00641 // Reset weights 00642 mAccumAnimWeight = 0.0f; 00643 mTransFromInitial = Vector3::ZERO; 00644 mRotFromInitial = Quaternion::IDENTITY; 00645 mScaleFromInitial = Vector3::UNIT_SCALE; 00646 00647 needUpdate(); 00648 } 00649 //----------------------------------------------------------------------- 00650 const Vector3& Node::getInitialPosition(void) const 00651 { 00652 return mInitialPosition; 00653 } 00654 //----------------------------------------------------------------------- 00655 const Quaternion& Node::getInitialOrientation(void) const 00656 { 00657 return mInitialOrientation; 00658 00659 } 00660 //----------------------------------------------------------------------- 00661 const Vector3& Node::getInitialScale(void) const 00662 { 00663 return mInitialScale; 00664 } 00665 //----------------------------------------------------------------------- 00666 Node* Node::getChild(const String& name) const 00667 { 00668 ChildNodeMap::const_iterator i = mChildren.find(name); 00669 00670 if (i == mChildren.end()) 00671 { 00672 Except(Exception::ERR_ITEM_NOT_FOUND, "Child node named " + name + 00673 " does not exist.", "Node::getChild"); 00674 } 00675 return i->second; 00676 00677 } 00678 //----------------------------------------------------------------------- 00679 Node* Node::removeChild(const String& name) 00680 { 00681 ChildNodeMap::iterator i = mChildren.find(name); 00682 00683 if (i == mChildren.end()) 00684 { 00685 Except(Exception::ERR_ITEM_NOT_FOUND, "Child node named " + name + 00686 " does not exist.", "Node::removeChild"); 00687 } 00688 00689 Node* ret = i->second; 00690 // Cancel any pending update 00691 cancelUpdate(ret); 00692 00693 mChildren.erase(i); 00694 ret->setParent(NULL); 00695 00696 return ret; 00697 00698 00699 } 00700 //----------------------------------------------------------------------- 00701 Node::ChildNodeIterator Node::getChildIterator(void) 00702 { 00703 return ChildNodeIterator(mChildren.begin(), mChildren.end()); 00704 } 00705 //----------------------------------------------------------------------- 00706 void Node::_weightedTransform(Real weight, const Vector3& translate, 00707 const Quaternion& rotate, const Vector3& scale) 00708 { 00709 // If no previous transforms, we can just apply 00710 if (mAccumAnimWeight == 0.0f) 00711 { 00712 mRotFromInitial = rotate; 00713 mTransFromInitial = translate; 00714 mScaleFromInitial = scale; 00715 mAccumAnimWeight = weight; 00716 } 00717 else 00718 { 00719 // Blend with existing 00720 Real factor = weight / (mAccumAnimWeight + weight); 00721 mTransFromInitial += (translate - mTransFromInitial) * factor; 00722 mRotFromInitial = 00723 Quaternion::Slerp(factor, mRotFromInitial, rotate); 00724 // For scale, find delta from 1.0, factor then add back before applying 00725 Vector3 scaleDiff = (scale - Vector3::UNIT_SCALE) * factor; 00726 mScaleFromInitial = mScaleFromInitial * 00727 (scaleDiff + Vector3::UNIT_SCALE); 00728 mAccumAnimWeight += weight; 00729 00730 } 00731 00732 // Update final based on bind position + offsets 00733 mOrientation = mInitialOrientation * mRotFromInitial; 00734 mPosition = mInitialPosition + mTransFromInitial; 00735 mScale = mInitialScale * mScaleFromInitial; 00736 needUpdate(); 00737 00738 } 00739 //----------------------------------------------------------------------- 00740 Real Node::getSquaredViewDepth(const Camera* cam) const 00741 { 00742 Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition(); 00743 00744 // NB use squared length rather than real depth to avoid square root 00745 return diff.squaredLength(); 00746 } 00747 //----------------------------------------------------------------------- 00748 void Node::needUpdate() 00749 { 00750 // If we're already going to update everything this doesn't matter 00751 /* FIX: removed because this causes newly created nodes 00752 which already have mNeedUpdate == true not to notify parent when 00753 added! 00754 if (mNeedUpdate) 00755 { 00756 return; 00757 } 00758 */ 00759 00760 mNeedParentUpdate = true; 00761 mNeedChildUpdate = true; 00762 mCachedTransformOutOfDate = true; 00763 00764 // Make sure we're not root and parent hasn't been notified before 00765 if (mParent && !mParentNotified) 00766 { 00767 mParent->requestUpdate(this); 00768 mParentNotified = true ; 00769 } 00770 00771 // all children will be updated 00772 mChildrenToUpdate.clear(); 00773 } 00774 //----------------------------------------------------------------------- 00775 void Node::requestUpdate(Node* child) 00776 { 00777 // If we're already going to update everything this doesn't matter 00778 if (mNeedChildUpdate) 00779 { 00780 return; 00781 } 00782 00783 mChildrenToUpdate.insert(child); 00784 // Request selective update of me, if we didn't do it before 00785 if (mParent && !mParentNotified) { 00786 mParent->requestUpdate(this); 00787 mParentNotified = true ; 00788 } 00789 00790 } 00791 //----------------------------------------------------------------------- 00792 void Node::cancelUpdate(Node* child) 00793 { 00794 mChildrenToUpdate.erase(child); 00795 00796 // Propogate this up if we're done 00797 if (mChildrenToUpdate.empty() && mParent && !mNeedChildUpdate) 00798 { 00799 mParent->cancelUpdate(this); 00800 mParentNotified = false ; 00801 } 00802 } 00803 } 00804
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:36 2004