Blender V2.61 - r43446

SG_Node.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include "SG_Node.h"
00034 #include "SG_ParentRelation.h"
00035 #include <algorithm>
00036 
00037 using namespace std;
00038 
00039 
00040 SG_Node::SG_Node(
00041     void* clientobj,
00042     void* clientinfo,
00043     SG_Callbacks& callbacks
00044 
00045 )
00046     : SG_Spatial(clientobj,clientinfo,callbacks),
00047     m_SGparent(NULL)
00048 {
00049     m_modified = true;
00050 }
00051 
00052 SG_Node::SG_Node(
00053     const SG_Node & other
00054 ) :
00055     SG_Spatial(other),
00056     m_children(other.m_children),
00057     m_SGparent(other.m_SGparent)
00058 {
00059     m_modified = true;
00060 }
00061 
00062 SG_Node::~SG_Node()
00063 {
00064 }
00065 
00066 
00067 SG_Node* SG_Node::GetSGReplica()
00068 {
00069     SG_Node* replica = new SG_Node(*this);
00070     if (replica == NULL) return NULL;
00071 
00072     ProcessSGReplica(&replica);
00073     
00074     return replica;
00075 }
00076 
00077     void 
00078 SG_Node::
00079 ProcessSGReplica(
00080     SG_Node** replica
00081 ){
00082     // Apply the replication call back function.
00083     if (!ActivateReplicationCallback(*replica)) 
00084     {
00085         delete (*replica);
00086         *replica = NULL;
00087         return;
00088     }
00089 
00090     // clear the replica node of it's parent.
00091     static_cast<SG_Node*>(*replica)->m_SGparent = NULL;
00092 
00093     if (m_children.begin() != m_children.end())
00094     {
00095         // if this node has children, the replica has too, so clear and clone children
00096         (*replica)->ClearSGChildren();
00097     
00098         NodeList::iterator childit;
00099         for (childit = m_children.begin();childit!=m_children.end();++childit)
00100         {
00101             SG_Node* childnode = (*childit)->GetSGReplica();
00102             if (childnode)
00103                 (*replica)->AddChild(childnode);
00104         }
00105     }
00106     // Nodes without children and without client object are
00107     // not worth to keep, they will just take up CPU
00108     // This can happen in partial replication of hierarchy
00109     // during group duplication.
00110     if ((*replica)->m_children.empty() && 
00111         (*replica)->GetSGClientObject() == NULL)
00112     {
00113         delete (*replica);
00114         *replica = NULL;
00115     }
00116 }
00117 
00118 
00119     void 
00120 SG_Node::
00121 Destruct()
00122 {
00123     // Not entirely sure what Destruct() expects to happen.
00124     // I think it probably means just to call the DestructionCallback
00125     // in the right order on all the children - rather than free any memory
00126     
00127     // We'll delete m_parent_relation now anyway.
00128     
00129     delete(m_parent_relation);
00130     m_parent_relation = NULL;
00131 
00132     if (m_children.begin() != m_children.end())
00133     {
00134         NodeList::iterator childit;
00135         for (childit = m_children.begin();childit!=m_children.end();++childit)
00136         {
00137             // call the SG_Node destruct method on each of our children }-)
00138             (*childit)->Destruct();
00139         }
00140     }
00141 
00142     ActivateDestructionCallback();
00143 }
00144 
00145 const 
00146     SG_Node*    
00147 SG_Node::
00148 GetRootSGParent(
00149 ) const {
00150     return (m_SGparent ? (const SG_Node*) m_SGparent->GetRootSGParent() : (const SG_Node*) this);
00151 }
00152 
00153 bool SG_Node::IsAncessor(const SG_Node* child) const
00154 {
00155     return (!child->m_SGparent) ? false : 
00156         (child->m_SGparent == this) ? true : IsAncessor(child->m_SGparent);
00157 }
00158 
00159     void 
00160 SG_Node::
00161 DisconnectFromParent(
00162 ){
00163     if (m_SGparent)
00164     {
00165         m_SGparent->RemoveChild(this);
00166         m_SGparent = NULL;
00167     }
00168 
00169 }
00170 
00171 void SG_Node::AddChild(SG_Node* child)
00172 {
00173     m_children.push_back(child);
00174     child->SetSGParent(this); // this way ?
00175 }
00176 
00177 void SG_Node::RemoveChild(SG_Node* child)
00178 {
00179     NodeList::iterator childfound = find(m_children.begin(),m_children.end(),child);
00180 
00181     if (childfound != m_children.end())
00182     {
00183         m_children.erase(childfound);
00184     }
00185 }
00186 
00187 
00188 
00189 void SG_Node::UpdateWorldData(double time, bool parentUpdated)
00190 {
00191     //if (!GetSGParent())
00192     //  return;
00193 
00194     if (UpdateSpatialData(GetSGParent(),time,parentUpdated))
00195         // to update the 
00196         ActivateUpdateTransformCallback();
00197 
00198     // The node is updated, remove it from the update list
00199     Delink();
00200 
00201     // update children's worlddata
00202     for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it)
00203     {
00204         (*it)->UpdateWorldData(time, parentUpdated);
00205     }
00206 }
00207 
00208 
00209 
00210 void SG_Node::SetSimulatedTime(double time,bool recurse)
00211 {
00212 
00213     // update the controllers of this node.
00214     SetControllerTime(time);
00215 
00216     // update children's simulate time.
00217     if (recurse)
00218     {
00219         for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it)
00220         {
00221             (*it)->SetSimulatedTime(time,recurse);
00222         }
00223     }
00224 }
00225 
00226 
00227