source: OGRE/trunk/ogrenew/OgreMain/src/OgreNode.cpp @ 692

Revision 692, 27.5 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26#include "OgreNode.h"
27
28#include "OgreException.h"
29#include "OgreMath.h"
30
31// Dependencies on render-related types due to ability to render node
32#include "OgreMaterialManager.h"
33#include "OgreMeshManager.h"
34#include "OgreMesh.h"
35#include "OgreSubMesh.h"
36#include "OgreCamera.h"
37
38namespace Ogre {
39
40    unsigned long Node::msNextGeneratedNameExt = 1;
41        Node::QueuedUpdates Node::msQueuedUpdates;
42    //-----------------------------------------------------------------------
43    Node::Node()
44                :mParent(0),
45                mNeedParentUpdate(false),
46                mNeedChildUpdate(false),
47                mParentNotified(false),
48                mOrientation(Quaternion::IDENTITY),
49                mPosition(Vector3::ZERO),
50                mScale(Vector3::UNIT_SCALE),
51        mInheritOrientation(true),
52                mInheritScale(true),
53                mDerivedOrientation(Quaternion::IDENTITY),
54                mDerivedPosition(Vector3::ZERO),
55                mDerivedScale(Vector3::UNIT_SCALE),
56                mInitialPosition(Vector3::ZERO),
57                mInitialOrientation(Quaternion::IDENTITY),
58                mInitialScale(Vector3::UNIT_SCALE),
59                mAccumAnimWeight(0.0f),
60                mCachedTransformOutOfDate(true),
61                mListener(0)
62    {
63        // Generate a name
64                StringUtil::StrStreamType str;
65                str << "Unnamed_" << msNextGeneratedNameExt++;
66        mName = str.str();
67
68        needUpdate();
69
70    }
71    //-----------------------------------------------------------------------
72        Node::Node(const String& name) : Renderable(),
73                mParent(0),
74                mNeedParentUpdate(false),
75                mNeedChildUpdate(false),
76                mParentNotified(false),
77                mName(name),
78                mOrientation(Quaternion::IDENTITY),
79                mPosition(Vector3::ZERO),
80                mScale(Vector3::UNIT_SCALE),
81        mInheritOrientation(true),
82                mInheritScale(true),
83                mDerivedOrientation(Quaternion::IDENTITY),
84                mDerivedPosition(Vector3::ZERO),
85                mDerivedScale(Vector3::UNIT_SCALE),
86                mInitialPosition(Vector3::ZERO),
87                mInitialOrientation(Quaternion::IDENTITY),
88                mInitialScale(Vector3::UNIT_SCALE),
89                mAccumAnimWeight(0.0f),
90                mCachedTransformOutOfDate(true),
91                mListener(0)
92
93    {
94
95        needUpdate();
96
97    }
98
99    //-----------------------------------------------------------------------
100    Node::~Node()
101    {
102                // Call listener (note, only called if there's something to do)
103                if (mListener)
104                {
105                        mListener->nodeDestroyed(this);
106                }
107
108                removeAllChildren();
109                if(mParent)
110                        mParent->removeChild(this);
111
112        // Erase from queued updates
113        QueuedUpdates::iterator it =
114            std::find(msQueuedUpdates.begin(), msQueuedUpdates.end(), this);
115        if (it != msQueuedUpdates.end())
116        {
117            // Optimised algorithm to erase an element from unordered vector.
118            *it = msQueuedUpdates.back();
119            msQueuedUpdates.pop_back();
120        }
121        }
122    //-----------------------------------------------------------------------
123    Node* Node::getParent(void) const
124    {
125        return mParent;
126    }
127
128    //-----------------------------------------------------------------------
129    void Node::setParent(Node* parent)
130    {
131                bool different = (parent != mParent);
132
133        mParent = parent;
134        // Request update from parent
135                mParentNotified = false ;
136        needUpdate();
137
138                // Call listener (note, only called if there's something to do)
139                if (mListener && different)
140                {
141                        if (mParent)
142                                mListener->nodeAttached(this);
143                        else
144                                mListener->nodeDetached(this);
145                }
146
147    }
148
149    //-----------------------------------------------------------------------
150    Matrix4 Node::_getFullTransform(void) const
151    {
152        if (mCachedTransformOutOfDate)
153        {
154            // Use derived values
155            mCachedTransform.makeTransform(
156                _getDerivedPosition(),
157                _getDerivedScale(),
158                _getDerivedOrientation());
159            mCachedTransformOutOfDate = false;
160        }
161        return mCachedTransform;
162    }
163    //-----------------------------------------------------------------------
164    void Node::_update(bool updateChildren, bool parentHasChanged)
165    {
166                // always clear information about parent notification
167                mParentNotified = false ;
168
169        // Short circuit the off case
170        if (!updateChildren && !mNeedParentUpdate && !mNeedChildUpdate && !parentHasChanged )
171        {
172            return;
173        }
174
175
176        // See if we should process everyone
177        if (mNeedParentUpdate || parentHasChanged)
178        {
179            // Update transforms from parent
180            _updateFromParent();
181                        mNeedParentUpdate = false;
182
183                        // Call listener (note, only called if there's something to do)
184                        if (mListener)
185                        {
186                                mListener->nodeUpdated(this);
187                        }
188
189                }
190
191                if (mNeedChildUpdate || parentHasChanged)
192                {
193
194            ChildNodeMap::iterator it, itend;
195                        itend = mChildren.end();
196            for (it = mChildren.begin(); it != itend; ++it)
197            {
198                Node* child = it->second;
199                child->_update(true, true);
200            }
201            mChildrenToUpdate.clear();
202        }
203        else
204        {
205            // Just update selected children
206
207            ChildUpdateSet::iterator it, itend;
208                        itend = mChildrenToUpdate.end();
209            for(it = mChildrenToUpdate.begin(); it != itend; ++it)
210            {
211                Node* child = *it;
212                child->_update(true, false);
213            }
214
215            mChildrenToUpdate.clear();
216        }
217
218        mNeedChildUpdate = false;
219
220    }
221
222    //-----------------------------------------------------------------------
223    void Node::_updateFromParent(void) const
224    {
225        if (mParent)
226        {
227            // Update orientation
228            const Quaternion& parentOrientation = mParent->_getDerivedOrientation();
229            if (mInheritOrientation)
230            {
231                // Combine orientation with that of parent
232                mDerivedOrientation = parentOrientation * mOrientation;
233            }
234            else
235            {
236                // No inheritence
237                mDerivedOrientation = mOrientation;
238            }
239
240            // Update scale
241            const Vector3& parentScale = mParent->_getDerivedScale();
242            if (mInheritScale)
243            {
244                // Scale own position by parent scale, NB just combine
245                // as equivalent axes, no shearing
246                mDerivedScale = parentScale * mScale;
247            }
248            else
249            {
250                // No inheritence
251                mDerivedScale = mScale;
252            }
253
254            // Change position vector based on parent's orientation & scale
255            mDerivedPosition = parentOrientation * (parentScale * mPosition);
256
257            // Add altered position vector to parents
258            mDerivedPosition += mParent->_getDerivedPosition();
259        }
260        else
261        {
262            // Root node, no parent
263            mDerivedOrientation = mOrientation;
264            mDerivedPosition = mPosition;
265            mDerivedScale = mScale;
266        }
267
268        mCachedTransformOutOfDate = true;
269
270
271    }
272    //-----------------------------------------------------------------------
273    Node* Node::createChild(const Vector3& translate, const Quaternion& rotate)
274    {
275        Node* newNode = createChildImpl();
276        newNode->translate(translate);
277        newNode->rotate(rotate);
278        this->addChild(newNode);
279
280        return newNode;
281    }
282    //-----------------------------------------------------------------------
283    Node* Node::createChild(const String& name, const Vector3& translate, const Quaternion& rotate)
284    {
285        Node* newNode = createChildImpl(name);
286        newNode->translate(translate);
287        newNode->rotate(rotate);
288        this->addChild(newNode);
289
290        return newNode;
291    }
292    //-----------------------------------------------------------------------
293    void Node::addChild(Node* child)
294    {
295        assert(!child->mParent);
296
297        mChildren.insert(ChildNodeMap::value_type(child->getName(), child));
298        child->setParent(this);
299
300    }
301    //-----------------------------------------------------------------------
302    unsigned short Node::numChildren(void) const
303    {
304        return static_cast< unsigned short >( mChildren.size() );
305    }
306    //-----------------------------------------------------------------------
307    Node* Node::getChild(unsigned short index) const
308    {
309        if( index < mChildren.size() )
310        {
311            ChildNodeMap::const_iterator i = mChildren.begin();
312            while (index--) ++i;
313            return i->second;
314        }
315        else
316            return NULL;
317    }
318    //-----------------------------------------------------------------------
319    Node* Node::removeChild(unsigned short index)
320    {
321        Node* ret;
322        if (index < mChildren.size())
323        {
324            ChildNodeMap::iterator i = mChildren.begin();
325            while (index--) ++i;
326            ret = i->second;
327            // cancel any pending update
328            cancelUpdate(ret);
329
330            mChildren.erase(i);
331            ret->setParent(NULL);
332            return ret;
333        }
334        else
335        {
336            OGRE_EXCEPT(
337                Exception::ERR_INVALIDPARAMS,
338                "Child index out of bounds.",
339                "Node::getChild" );
340        }
341        return 0;
342    }
343    //-----------------------------------------------------------------------
344    Node* Node::removeChild(Node* child)
345    {
346        ChildNodeMap::iterator i, iend;
347        iend = mChildren.end();
348        for (i = mChildren.begin(); i != iend; ++i)
349        {
350            if (i->second == child)
351            {
352                // cancel any pending update
353                cancelUpdate(child);
354
355                mChildren.erase(i);
356                child->setParent(NULL);
357                break;
358            }
359        }
360        return child;
361    }
362    //-----------------------------------------------------------------------
363    const Quaternion& Node::getOrientation() const
364    {
365        return mOrientation;
366    }
367
368    //-----------------------------------------------------------------------
369    void Node::setOrientation( const Quaternion & q )
370    {
371        mOrientation = q;
372        needUpdate();
373    }
374    //-----------------------------------------------------------------------
375    void Node::setOrientation( Real w, Real x, Real y, Real z)
376    {
377        mOrientation.w = w;
378        mOrientation.x = x;
379        mOrientation.y = y;
380        mOrientation.z = z;
381        needUpdate();
382    }
383    //-----------------------------------------------------------------------
384    void Node::resetOrientation(void)
385    {
386        mOrientation = Quaternion::IDENTITY;
387        needUpdate();
388    }
389
390    //-----------------------------------------------------------------------
391    void Node::setPosition(const Vector3& pos)
392    {
393        mPosition = pos;
394        needUpdate();
395    }
396
397
398    //-----------------------------------------------------------------------
399    void Node::setPosition(Real x, Real y, Real z)
400    {
401        Vector3 v(x,y,z);
402        setPosition(v);
403    }
404
405    //-----------------------------------------------------------------------
406    const Vector3 & Node::getPosition(void) const
407    {
408        return mPosition;
409    }
410    //-----------------------------------------------------------------------
411    Matrix3 Node::getLocalAxes(void) const
412    {
413        Vector3 axisX = Vector3::UNIT_X;
414        Vector3 axisY = Vector3::UNIT_Y;
415        Vector3 axisZ = Vector3::UNIT_Z;
416
417        axisX = mOrientation * axisX;
418        axisY = mOrientation * axisY;
419        axisZ = mOrientation * axisZ;
420
421        return Matrix3(axisX.x, axisY.x, axisZ.x,
422                       axisX.y, axisY.y, axisZ.y,
423                       axisX.z, axisY.z, axisZ.z);
424    }
425
426    //-----------------------------------------------------------------------
427    void Node::translate(const Vector3& d, TransformSpace relativeTo)
428    {
429        Vector3 adjusted;
430        switch(relativeTo)
431        {
432        case TS_LOCAL:
433            // position is relative to parent so transform downwards
434            mPosition += mOrientation * d;
435                break;
436        case TS_WORLD:
437            // position is relative to parent so transform upwards
438            if (mParent)
439            {
440                mPosition += (mParent->_getDerivedOrientation().Inverse() * d)
441                    / mParent->_getDerivedScale();
442            }
443            else
444            {
445                mPosition += d;
446            }
447                break;
448        case TS_PARENT:
449            mPosition += d;
450            break;
451        }
452        needUpdate();
453
454    }
455    //-----------------------------------------------------------------------
456    void Node::translate(Real x, Real y, Real z, TransformSpace relativeTo)
457    {
458        Vector3 v(x,y,z);
459        translate(v, relativeTo);
460    }
461    //-----------------------------------------------------------------------
462    void Node::translate(const Matrix3& axes, const Vector3& move, TransformSpace relativeTo)
463    {
464        Vector3 derived = axes * move;
465        translate(derived, relativeTo);
466    }
467    //-----------------------------------------------------------------------
468    void Node::translate(const Matrix3& axes, Real x, Real y, Real z, TransformSpace relativeTo)
469    {
470        Vector3 d(x,y,z);
471        translate(axes,d,relativeTo);
472    }
473    //-----------------------------------------------------------------------
474    void Node::roll(const Radian& angle, TransformSpace relativeTo)
475    {
476        rotate(Vector3::UNIT_Z, angle, relativeTo);
477    }
478    //-----------------------------------------------------------------------
479    void Node::pitch(const Radian& angle, TransformSpace relativeTo)
480    {
481        rotate(Vector3::UNIT_X, angle, relativeTo);
482    }
483    //-----------------------------------------------------------------------
484    void Node::yaw(const Radian& angle, TransformSpace relativeTo)
485    {
486        rotate(Vector3::UNIT_Y, angle, relativeTo);
487
488    }
489    //-----------------------------------------------------------------------
490    void Node::rotate(const Vector3& axis, const Radian& angle, TransformSpace relativeTo)
491    {
492        Quaternion q;
493        q.FromAngleAxis(angle,axis);
494        rotate(q, relativeTo);
495    }
496
497    //-----------------------------------------------------------------------
498    void Node::rotate(const Quaternion& q, TransformSpace relativeTo)
499    {
500        switch(relativeTo)
501        {
502        case TS_PARENT:
503            // Rotations are normally relative to local axes, transform up
504            mOrientation = q * mOrientation;
505            break;
506        case TS_WORLD:
507            // Rotations are normally relative to local axes, transform up
508            mOrientation = mOrientation * _getDerivedOrientation().Inverse()
509                * q * _getDerivedOrientation();
510            break;
511        case TS_LOCAL:
512            // Note the order of the mult, i.e. q comes after
513            mOrientation = mOrientation * q;
514            break;
515        }
516        needUpdate();
517    }
518    //-----------------------------------------------------------------------
519    const Quaternion & Node::_getDerivedOrientation(void) const
520    {
521                if (mNeedParentUpdate)
522                {
523                _updateFromParent();
524                        mNeedParentUpdate = false;
525                }
526        return mDerivedOrientation;
527    }
528    //-----------------------------------------------------------------------
529    const Vector3 & Node::_getDerivedPosition(void) const
530    {
531                if (mNeedParentUpdate)
532                {
533                _updateFromParent();
534                        mNeedParentUpdate = false;
535                }
536        return mDerivedPosition;
537    }
538    //-----------------------------------------------------------------------
539    const Vector3 & Node::_getDerivedScale(void) const
540    {
541        if (mNeedParentUpdate)
542        {
543            _updateFromParent();
544            mNeedParentUpdate = false;
545        }
546        return mDerivedScale;
547    }
548    //-----------------------------------------------------------------------
549    void Node::removeAllChildren(void)
550    {
551                ChildNodeMap::iterator i, iend;
552                iend = mChildren.end();
553                for (i = mChildren.begin(); i != iend; ++i)
554                {
555                        i->second->setParent(0);
556                }
557        mChildren.clear();
558                mChildrenToUpdate.clear();
559    }
560    //-----------------------------------------------------------------------
561    void Node::setScale(const Vector3& scale)
562    {
563        mScale = scale;
564        needUpdate();
565    }
566    //-----------------------------------------------------------------------
567    void Node::setScale(Real x, Real y, Real z)
568    {
569        mScale.x = x;
570        mScale.y = y;
571        mScale.z = z;
572        needUpdate();
573    }
574    //-----------------------------------------------------------------------
575    const Vector3 & Node::getScale(void) const
576    {
577        return mScale;
578    }
579    //-----------------------------------------------------------------------
580    void Node::setInheritOrientation(bool inherit)
581    {
582        mInheritOrientation = inherit;
583        needUpdate();
584    }
585    //-----------------------------------------------------------------------
586    bool Node::getInheritOrientation(void) const
587    {
588        return mInheritOrientation;
589    }
590    //-----------------------------------------------------------------------
591    void Node::setInheritScale(bool inherit)
592    {
593        mInheritScale = inherit;
594        needUpdate();
595    }
596    //-----------------------------------------------------------------------
597    bool Node::getInheritScale(void) const
598    {
599        return mInheritScale;
600    }
601    //-----------------------------------------------------------------------
602    void Node::scale(const Vector3& scale)
603    {
604        mScale = mScale * scale;
605        needUpdate();
606
607    }
608    //-----------------------------------------------------------------------
609    void Node::scale(Real x, Real y, Real z)
610    {
611        mScale.x *= x;
612        mScale.y *= y;
613        mScale.z *= z;
614        needUpdate();
615
616    }
617    //-----------------------------------------------------------------------
618    const String& Node::getName(void) const
619    {
620        return mName;
621    }
622    //-----------------------------------------------------------------------
623    const MaterialPtr& Node::getMaterial(void) const
624    {
625        if (mpMaterial.isNull())
626        {
627            mpMaterial = MaterialManager::getSingleton().getByName("Core/NodeMaterial");
628                        if (mpMaterial.isNull())
629                                OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material Core/NodeMaterial",
630                                        "Node::getMaterial" );
631            mpMaterial->load();
632        }
633        return mpMaterial;
634
635    }
636    //-----------------------------------------------------------------------
637    void Node::getRenderOperation(RenderOperation& op)
638    {
639        static SubMesh* pSubMesh = 0;
640        if (!pSubMesh)
641        {
642            MeshPtr pMesh = MeshManager::getSingleton().load("axes.mesh",
643                                ResourceGroupManager::BOOTSTRAP_RESOURCE_GROUP_NAME);
644            pSubMesh = pMesh->getSubMesh(0);
645        }
646        pSubMesh->_getRenderOperation(op);
647    }
648    //-----------------------------------------------------------------------
649    void Node::getWorldTransforms(Matrix4* xform) const
650    {
651        // Assumes up to date
652        *xform = this->_getFullTransform();
653    }
654    //-----------------------------------------------------------------------
655    const Quaternion& Node::getWorldOrientation(void) const
656    {
657        return _getDerivedOrientation();
658    }
659    //-----------------------------------------------------------------------
660    const Vector3& Node::getWorldPosition(void) const
661    {
662        return _getDerivedPosition();
663    }
664    //-----------------------------------------------------------------------
665    void Node::setInitialState(void)
666    {
667        mInitialPosition = mPosition;
668        mInitialOrientation = mOrientation;
669        mInitialScale = mScale;
670    }
671    //-----------------------------------------------------------------------
672    void Node::resetToInitialState(void)
673    {
674        mPosition = mInitialPosition;
675        mOrientation = mInitialOrientation;
676        mScale = mInitialScale;
677
678        // Reset weights
679        mAccumAnimWeight = 0.0f;
680        mTransFromInitial = Vector3::ZERO;
681        mRotFromInitial = Quaternion::IDENTITY;
682        mScaleFromInitial = Vector3::UNIT_SCALE;
683
684        needUpdate();
685    }
686    //-----------------------------------------------------------------------
687    const Vector3& Node::getInitialPosition(void) const
688    {
689        return mInitialPosition;
690    }
691    //-----------------------------------------------------------------------
692    const Quaternion& Node::getInitialOrientation(void) const
693    {
694        return mInitialOrientation;
695
696    }
697    //-----------------------------------------------------------------------
698    const Vector3& Node::getInitialScale(void) const
699    {
700        return mInitialScale;
701    }
702    //-----------------------------------------------------------------------
703    Node* Node::getChild(const String& name) const
704    {
705        ChildNodeMap::const_iterator i = mChildren.find(name);
706
707        if (i == mChildren.end())
708        {
709            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Child node named " + name +
710                " does not exist.", "Node::getChild");
711        }
712        return i->second;
713
714    }
715    //-----------------------------------------------------------------------
716    Node* Node::removeChild(const String& name)
717    {
718        ChildNodeMap::iterator i = mChildren.find(name);
719
720        if (i == mChildren.end())
721        {
722            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Child node named " + name +
723                " does not exist.", "Node::removeChild");
724        }
725
726        Node* ret = i->second;
727        // Cancel any pending update
728        cancelUpdate(ret);
729
730        mChildren.erase(i);
731        ret->setParent(NULL);
732
733        return ret;
734
735
736    }
737    //-----------------------------------------------------------------------
738    Node::ChildNodeIterator Node::getChildIterator(void)
739    {
740        return ChildNodeIterator(mChildren.begin(), mChildren.end());
741    }
742        //-----------------------------------------------------------------------
743        Node::ConstChildNodeIterator Node::getChildIterator(void) const
744        {
745                return ConstChildNodeIterator(mChildren.begin(), mChildren.end());
746        }
747    //-----------------------------------------------------------------------
748    void Node::_weightedTransform(Real weight, const Vector3& translate,
749       const Quaternion& rotate, const Vector3& scale)
750    {
751        // If no previous transforms, we can just apply
752        if (mAccumAnimWeight == 0.0f)
753        {
754            mRotFromInitial = rotate;
755            mTransFromInitial = translate;
756            mScaleFromInitial = scale;
757            mAccumAnimWeight = weight;
758        }
759        else
760        {
761            // Blend with existing
762            Real factor = weight / (mAccumAnimWeight + weight);
763            mTransFromInitial += (translate - mTransFromInitial) * factor;
764            mRotFromInitial =
765                Quaternion::Slerp(factor, mRotFromInitial, rotate);
766            // For scale, find delta from 1.0, factor then add back before applying
767            Vector3 scaleDiff = (scale - Vector3::UNIT_SCALE) * factor;
768            mScaleFromInitial = mScaleFromInitial *
769                (scaleDiff + Vector3::UNIT_SCALE);
770            mAccumAnimWeight += weight;
771
772        }
773
774        // Update final based on bind position + offsets
775        mOrientation = mInitialOrientation * mRotFromInitial;
776        mPosition = mInitialPosition + mTransFromInitial;
777        mScale = mInitialScale * mScaleFromInitial;
778        needUpdate();
779
780    }
781    //-----------------------------------------------------------------------
782    Real Node::getSquaredViewDepth(const Camera* cam) const
783    {
784        Vector3 diff = _getDerivedPosition() - cam->getDerivedPosition();
785
786        // NB use squared length rather than real depth to avoid square root
787        return diff.squaredLength();
788    }
789    //-----------------------------------------------------------------------
790    void Node::needUpdate(bool forceParentUpdate)
791    {
792
793        mNeedParentUpdate = true;
794                mNeedChildUpdate = true;
795        mCachedTransformOutOfDate = true;
796
797        // Make sure we're not root and parent hasn't been notified before
798        if (mParent && (!mParentNotified || forceParentUpdate))
799        {
800            mParent->requestUpdate(this, forceParentUpdate);
801                        mParentNotified = true ;
802        }
803
804        // all children will be updated
805        mChildrenToUpdate.clear();
806    }
807    //-----------------------------------------------------------------------
808    void Node::requestUpdate(Node* child, bool forceParentUpdate)
809    {
810        // If we're already going to update everything this doesn't matter
811        if (mNeedChildUpdate)
812        {
813            return;
814        }
815
816        mChildrenToUpdate.insert(child);
817        // Request selective update of me, if we didn't do it before
818        if (mParent && (!mParentNotified || forceParentUpdate))
819                {
820            mParent->requestUpdate(this, forceParentUpdate);
821                        mParentNotified = true ;
822                }
823
824    }
825    //-----------------------------------------------------------------------
826    void Node::cancelUpdate(Node* child)
827    {
828        mChildrenToUpdate.erase(child);
829
830        // Propogate this up if we're done
831        if (mChildrenToUpdate.empty() && mParent && !mNeedChildUpdate)
832        {
833            mParent->cancelUpdate(this);
834                        mParentNotified = false ;
835        }
836    }
837        //-----------------------------------------------------------------------
838        void Node::queueNeedUpdate(Node* n)
839        {
840                msQueuedUpdates.push_back(n);
841        }
842        //-----------------------------------------------------------------------
843        void Node::processQueuedUpdates(void)
844        {
845                for (QueuedUpdates::iterator i = msQueuedUpdates.begin();
846                        i != msQueuedUpdates.end(); ++i)
847                {
848                        // Update, and force parent update since chances are we've ended
849                        // up with some mixed state in there due to re-entrancy
850                        (*i)->needUpdate(true);
851                }
852                msQueuedUpdates.clear();
853        }
854    //-----------------------------------------------------------------------
855    const LightList& Node::getLights(void) const
856    {
857        // Nodes should not be lit by the scene, this will not get called
858        static LightList ll;
859        return ll;
860    }
861}
862
Note: See TracBrowser for help on using the repository browser.