|
Blender
V2.59
|
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