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