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