Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreNode.cpp

Go to the documentation of this file.
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