Blender V2.61 - r43446
|
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