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 needUpdate(); 00271 return 0; 00272 } 00273 //----------------------------------------------------------------------- 00274 const Quaternion& Node::getOrientation() const 00275 { 00276 return mOrientation; 00277 } 00278 00279 //----------------------------------------------------------------------- 00280 void Node::setOrientation( const Quaternion & q ) 00281 { 00282 mOrientation = q; 00283 needUpdate(); 00284 } 00285 //----------------------------------------------------------------------- 00286 void Node::setOrientation( Real w, Real x, Real y, Real z) 00287 { 00288 mOrientation.w = w; 00289 mOrientation.x = x; 00290 mOrientation.y = y; 00291 mOrientation.z = z; 00292 needUpdate(); 00293 } 00294 //----------------------------------------------------------------------- 00295 void Node::resetOrientation(void) 00296 { 00297 mOrientation = Quaternion::IDENTITY; 00298 needUpdate(); 00299 } 00300 00301 //----------------------------------------------------------------------- 00302 void Node::setPosition(const Vector3& pos) 00303 { 00304 mPosition = pos; 00305 needUpdate(); 00306 } 00307 00308 00309 //----------------------------------------------------------------------- 00310 void Node::setPosition(Real x, Real y, Real z) 00311 { 00312 Vector3 v(x,y,z); 00313 setPosition(v); 00314 } 00315 00316 //----------------------------------------------------------------------- 00317 const Vector3 & Node::getPosition(void) const 00318 { 00319 return mPosition; 00320 } 00321 //----------------------------------------------------------------------- 00322 Matrix3 Node::getLocalAxes(void) const 00323 { 00324 Vector3 axisX = Vector3::UNIT_X; 00325 Vector3 axisY = Vector3::UNIT_Y; 00326 Vector3 axisZ = Vector3::UNIT_Z; 00327 00328 axisX = mOrientation * axisX; 00329 axisY = mOrientation * axisY; 00330 axisZ = mOrientation * axisZ; 00331 00332 return Matrix3(axisX.x, axisY.x, axisZ.x, 00333 axisX.y, axisY.y, axisZ.y, 00334 axisX.z, axisY.z, axisZ.z); 00335 } 00336 00337 //----------------------------------------------------------------------- 00338 void Node::translate(const Vector3& d, TransformSpace relativeTo) 00339 { 00340 Vector3 adjusted; 00341 switch(relativeTo) 00342 { 00343 case TS_LOCAL: 00344 // position is relative to parent so transform downwards 00345 mPosition += mOrientation * d; 00346 break; 00347 case TS_WORLD: 00348 // position is relative to parent so transform upwards 00349 if (mParent) 00350 { 00351 mPosition += mParent->_getDerivedOrientation().Inverse() * d; 00352 } 00353 else 00354 { 00355 mPosition += d; 00356 } 00357 break; 00358 case TS_PARENT: 00359 mPosition += d; 00360 break; 00361 } 00362 needUpdate(); 00363 00364 } 00365 //----------------------------------------------------------------------- 00366 void Node::translate(Real x, Real y, Real z, TransformSpace relativeTo) 00367 { 00368 Vector3 v(x,y,z); 00369 translate(v, relativeTo); 00370 } 00371 //----------------------------------------------------------------------- 00372 void Node::translate(const Matrix3& axes, const Vector3& move, TransformSpace relativeTo) 00373 { 00374 Vector3 derived = axes * move; 00375 translate(derived, relativeTo); 00376 } 00377 //----------------------------------------------------------------------- 00378 void Node::translate(const Matrix3& axes, Real x, Real y, Real z, TransformSpace relativeTo) 00379 { 00380 Vector3 d(x,y,z); 00381 translate(axes,d,relativeTo); 00382 } 00383 //----------------------------------------------------------------------- 00384 void Node::roll(Real angleunits, TransformSpace relativeTo) 00385 { 00386 rotate(Vector3::UNIT_Z, angleunits, relativeTo); 00387 } 00388 //----------------------------------------------------------------------- 00389 void Node::pitch(Real angleunits, TransformSpace relativeTo) 00390 { 00391 rotate(Vector3::UNIT_X, angleunits, relativeTo); 00392 } 00393 //----------------------------------------------------------------------- 00394 void Node::yaw(Real angleunits, TransformSpace relativeTo) 00395 { 00396 rotate(Vector3::UNIT_Y, angleunits, relativeTo); 00397 00398 } 00399 //----------------------------------------------------------------------- 00400 void Node::rotate(const Vector3& axis, Real angleunits, TransformSpace relativeTo) 00401 { 00402 Quaternion q; 00403 q.FromAngleAxis(Math::AngleUnitsToRadians(angleunits),axis); 00404 rotate(q, relativeTo); 00405 } 00406 00407 //----------------------------------------------------------------------- 00408 void Node::rotate(const Quaternion& q, TransformSpace relativeTo) 00409 { 00410 switch(relativeTo) 00411 { 00412 case TS_PARENT: 00413 // Rotations are normally relative to local axes, transform up 00414 mOrientation = mOrientation * (mOrientation.Inverse() * q); 00415 break; 00416 case TS_WORLD: 00417 // Rotations are normally relative to local axes, transform up 00418 mOrientation = mOrientation * 00419 (_getDerivedOrientation().Inverse() * q); 00420 break; 00421 case TS_LOCAL: 00422 // Note the order of the mult, i.e. q comes after 00423 mOrientation = mOrientation * q; 00424 break; 00425 } 00426 needUpdate(); 00427 } 00428 //----------------------------------------------------------------------- 00429 const Quaternion & Node::_getDerivedOrientation(void) const 00430 { 00431 if (mNeedParentUpdate) 00432 { 00433 _updateFromParent(); 00434 mNeedParentUpdate = false; 00435 } 00436 return mDerivedOrientation; 00437 } 00438 //----------------------------------------------------------------------- 00439 const Vector3 & Node::_getDerivedPosition(void) const 00440 { 00441 if (mNeedParentUpdate) 00442 { 00443 _updateFromParent(); 00444 mNeedParentUpdate = false; 00445 } 00446 return mDerivedPosition; 00447 } 00448 //----------------------------------------------------------------------- 00449 const Vector3 & Node::_getDerivedScale(void) const 00450 { 00451 return mDerivedScale; 00452 } 00453 //----------------------------------------------------------------------- 00454 void Node::removeAllChildren(void) 00455 { 00456 mChildren.clear(); 00457 } 00458 //----------------------------------------------------------------------- 00459 void Node::setScale(const Vector3& scale) 00460 { 00461 mScale = scale; 00462 needUpdate(); 00463 } 00464 //----------------------------------------------------------------------- 00465 void Node::setScale(Real x, Real y, Real z) 00466 { 00467 mScale.x = x; 00468 mScale.y = y; 00469 mScale.z = z; 00470 needUpdate(); 00471 } 00472 //----------------------------------------------------------------------- 00473 const Vector3 & Node::getScale(void) const 00474 { 00475 return mScale; 00476 } 00477 //----------------------------------------------------------------------- 00478 void Node::setInheritScale(bool inherit) 00479 { 00480 mInheritScale = inherit; 00481 needUpdate(); 00482 } 00483 //----------------------------------------------------------------------- 00484 bool Node::getInheritScale(void) const 00485 { 00486 return mInheritScale; 00487 } 00488 //----------------------------------------------------------------------- 00489 void Node::scale(const Vector3& scale) 00490 { 00491 mScale = mScale * scale; 00492 needUpdate(); 00493 00494 } 00495 //----------------------------------------------------------------------- 00496 void Node::scale(Real x, Real y, Real z) 00497 { 00498 mScale.x *= x; 00499 mScale.y *= y; 00500 mScale.z *= z; 00501 needUpdate(); 00502 00503 } 00504 //----------------------------------------------------------------------- 00505 void Node::makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation, 00506 Matrix4& destMatrix) const 00507 { 00508 destMatrix = Matrix4::IDENTITY; 00509 // Ordering: 00510 // 1. Scale 00511 // 2. Rotate 00512 // 3. Translate 00513 00514 // Parent scaling is already applied to derived position 00515 // Own scale is applied before rotation 00516 Matrix3 rot3x3, scale3x3; 00517 orientation.ToRotationMatrix(rot3x3); 00518 scale3x3 = Matrix3::ZERO; 00519 scale3x3[0][0] = scale.x; 00520 scale3x3[1][1] = scale.y; 00521 scale3x3[2][2] = scale.z; 00522 00523 destMatrix = rot3x3 * scale3x3; 00524 destMatrix.setTrans(position); 00525 } 00526 //----------------------------------------------------------------------- 00527 void Node::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation, 00528 Matrix4& destMatrix) 00529 { 00530 destMatrix = Matrix4::IDENTITY; 00531 00532 // Invert the parameters 00533 Vector3 invTranslate = -position; 00534 Vector3 invScale; 00535 invScale.x = 1 / scale.x; 00536 invScale.y = 1 / scale.y; 00537 invScale.z = 1 / scale.z; 00538 00539 Quaternion invRot = orientation.Inverse(); 00540 00541 // Because we're inverting, order is translation, rotation, scale 00542 // So make translation relative to scale & rotation 00543 invTranslate.x *= invScale.x; // scale 00544 invTranslate.y *= invScale.y; // scale 00545 invTranslate.z *= invScale.z; // scale 00546 invTranslate = invRot * invTranslate; // rotate 00547 00548 // Next, make a 3x3 rotation matrix and apply inverse scale 00549 Matrix3 rot3x3, scale3x3; 00550 invRot.ToRotationMatrix(rot3x3); 00551 scale3x3 = Matrix3::ZERO; 00552 scale3x3[0][0] = invScale.x; 00553 scale3x3[1][1] = invScale.y; 00554 scale3x3[2][2] = invScale.z; 00555 00556 // Set up final matrix with scale & rotation 00557 destMatrix = scale3x3 * rot3x3; 00558 00559 destMatrix.setTrans(invTranslate); 00560 } 00561 //----------------------------------------------------------------------- 00562 const String& Node::getName(void) const 00563 { 00564 return mName; 00565 } 00566 //----------------------------------------------------------------------- 00567 Material* Node::getMaterial(void) const 00568 { 00569 static Material* pMaterial = 0; 00570 00571 if (!pMaterial) 00572 { 00573 pMaterial = (Material*)MaterialManager::getSingleton().getByName("Core/NodeMaterial"); 00574 if (!pMaterial) 00575 Except( Exception::ERR_ITEM_NOT_FOUND, "Could not find material Core/NodeMaterial", 00576 "Node::getMaterial" ); 00577 pMaterial->load(); 00578 } 00579 return pMaterial; 00580 00581 } 00582 //----------------------------------------------------------------------- 00583 void Node::getRenderOperation(RenderOperation& op) 00584 { 00585 static SubMesh* pSubMesh = 0; 00586 if (!pSubMesh) 00587 { 00588 Mesh *pMesh = MeshManager::getSingleton().load("axes.mesh"); 00589 pSubMesh = pMesh->getSubMesh(0); 00590 } 00591 pSubMesh->_getRenderOperation(op); 00592 } 00593 //----------------------------------------------------------------------- 00594 void Node::getWorldTransforms(Matrix4* xform) const 00595 { 00596 // Assumes up to date 00597 *xform = this->_getFullTransform(); 00598 } 00599 //----------------------------------------------------------------------- 00600 const Quaternion& Node::getWorldOrientation(void) const 00601 { 00602 return _getDerivedOrientation(); 00603 } 00604 //----------------------------------------------------------------------- 00605 const Vector3& Node::getWorldPosition(void) const 00606 { 00607 return _getDerivedPosition(); 00608 } 00609 //----------------------------------------------------------------------- 00610 void Node::setInitialState(void) 00611 { 00612 mInitialPosition = mPosition; 00613 mInitialOrientation = mOrientation; 00614 mInitialScale = mScale; 00615 } 00616 //----------------------------------------------------------------------- 00617 void Node::resetToInitialState(void) 00618 { 00619 mPosition = mInitialPosition; 00620 mOrientation = mInitialOrientation; 00621 mScale = mInitialScale; 00622 00623 // Reset weights 00624 mAccumAnimWeight = 0.0f; 00625 mTransFromInitial = Vector3::ZERO; 00626 mRotFromInitial = Quaternion::IDENTITY; 00627 mScaleFromInitial = Vector3::UNIT_SCALE; 00628 00629 needUpdate(); 00630 } 00631 //----------------------------------------------------------------------- 00632 const Vector3& Node::getInitialPosition(void) const 00633 { 00634 return mInitialPosition; 00635 } 00636 //----------------------------------------------------------------------- 00637 const Quaternion& Node::getInitialOrientation(void) const 00638 { 00639 return mInitialOrientation; 00640 00641 } 00642 //----------------------------------------------------------------------- 00643 const Vector3& Node::getInitialScale(void) const 00644 { 00645 return mInitialScale; 00646 } 00647 //----------------------------------------------------------------------- 00648 Node* Node::getChild(const String& name) const 00649 { 00650 ChildNodeMap::const_iterator i = mChildren.find(name); 00651 00652 if (i == mChildren.end()) 00653 { 00654 Except(Exception::ERR_ITEM_NOT_FOUND, "Child node named " + name + 00655 " does not exist.", "Node::getChild"); 00656 } 00657 return i->second; 00658 00659 } 00660 //----------------------------------------------------------------------- 00661 Node* Node::removeChild(const String& name) 00662 { 00663 ChildNodeMap::iterator i = mChildren.find(name); 00664 00665 if (i == mChildren.end()) 00666 { 00667 Except(Exception::ERR_ITEM_NOT_FOUND, "Child node named " + name + 00668 " does not exist.", "Node::removeChild"); 00669 } 00670 00671 Node* ret = i->second; 00672 // Cancel any pending update 00673 cancelUpdate(ret); 00674 00675 mChildren.erase(i); 00676 ret->setParent(NULL); 00677 00678 return ret; 00679 00680 00681 } 00682 //----------------------------------------------------------------------- 00683 Node::ChildNodeIterator Node::getChildIterator(void) 00684 { 00685 return ChildNodeIterator(mChildren.begin(), mChildren.end()); 00686 } 00687 //----------------------------------------------------------------------- 00688 void Node::_weightedTransform(Real weight, const Vector3& translate, 00689 const Quaternion& rotate, const Vector3& scale) 00690 { 00691 // If no previous transforms, we can just apply 00692 if (mAccumAnimWeight == 0.0f) 00693 { 00694 mRotFromInitial = rotate; 00695 mTransFromInitial = translate; 00696 mScaleFromInitial = scale; 00697 mAccumAnimWeight = weight; 00698 } 00699 else 00700 { 00701 // Blend with existing 00702 Real factor = weight / (mAccumAnimWeight + weight); 00703 mTransFromInitial += (translate - mTransFromInitial) * factor; 00704 mRotFromInitial = 00705 Quaternion::Slerp(factor, mRotFromInitial, rotate); 00706 // For scale, find delta from 1.0, factor then add back before applying 00707 Vector3 scaleDiff = (scale - Vector3::UNIT_SCALE) * factor; 00708 mScaleFromInitial = mScaleFromInitial * 00709 (scaleDiff + Vector3::UNIT_SCALE); 00710 mAccumAnimWeight += weight; 00711 00712 } 00713 00714 // Update final based on bind position + offsets 00715 mOrientation = mInitialOrientation * mRotFromInitial; 00716 mPosition = mInitialPosition + mTransFromInitial; 00717 mScale = mInitialScale * mScaleFromInitial; 00718 needUpdate(); 00719 00720 } 00721 //----------------------------------------------------------------------- 00722 Real Node::getSquaredViewDepth(const Camera* cam) const 00723 { 00724 Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition(); 00725 00726 // NB use squared length rather than real depth to avoid square root 00727 return diff.squaredLength(); 00728 } 00729 //----------------------------------------------------------------------- 00730 void Node::needUpdate() 00731 { 00732 // If we're already going to update everything this doesn't matter 00733 /* FIX: removed because this causes newly created nodes 00734 which already have mNeedUpdate == true not to notify parent when 00735 added! 00736 if (mNeedUpdate) 00737 { 00738 return; 00739 } 00740 */ 00741 00742 mNeedParentUpdate = true; 00743 mNeedChildUpdate = true; 00744 mCachedTransformOutOfDate = true; 00745 00746 // Make sure we're not root and parent hasn't been notified before 00747 if (mParent && !mParentNotified) 00748 { 00749 mParent->requestUpdate(this); 00750 mParentNotified = true ; 00751 } 00752 00753 // all children will be updated 00754 mChildrenToUpdate.clear(); 00755 } 00756 //----------------------------------------------------------------------- 00757 void Node::requestUpdate(Node* child) 00758 { 00759 // If we're already going to update everything this doesn't matter 00760 if (mNeedChildUpdate) 00761 { 00762 return; 00763 } 00764 00765 mChildrenToUpdate.insert(child); 00766 // Request selective update of me, if we didn't do it before 00767 if (mParent && !mParentNotified) { 00768 mParent->requestUpdate(this); 00769 mParentNotified = true ; 00770 } 00771 00772 } 00773 //----------------------------------------------------------------------- 00774 void Node::cancelUpdate(Node* child) 00775 { 00776 mChildrenToUpdate.erase(child); 00777 00778 // Propogate this up if we're done 00779 if (mChildrenToUpdate.empty() && mParent && !mNeedChildUpdate) 00780 { 00781 mParent->cancelUpdate(this); 00782 mParentNotified = false ; 00783 } 00784 } 00785 } 00786
Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:28 2004