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

Revision 657, 27.2 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

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