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         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