00001 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- 00002 00003 this file is part of rcssserver3D 00004 Copyright (C) 2002,2003 Koblenz University 00005 Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group 00006 $Id: basenode.cpp,v 1.12 2004/05/05 09:03:10 rollmark Exp $ 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; version 2 of the License. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 00021 BaseNode 00022 */ 00023 00024 #include "basenode.h" 00025 #include "sceneserver.h" 00026 #include "scene.h" 00027 #include <zeitgeist/logserver/logserver.h> 00028 00029 using namespace boost; 00030 using namespace oxygen; 00031 using namespace salt; 00032 using namespace zeitgeist; 00033 using namespace std; 00034 00035 const salt::Matrix BaseNode::mIdentityMatrix(salt::Matrix::GetIdentity()); 00036 00037 BaseNode::BaseNode() : 00038 zeitgeist::Node(), mDebugMode(false) 00039 { 00040 } 00041 00042 BaseNode::~BaseNode() 00043 { 00044 } 00045 00046 const salt::Matrix& BaseNode::GetLocalTransform() const 00047 { 00048 return mIdentityMatrix; 00049 } 00050 00051 const salt::Matrix& BaseNode::GetWorldTransform() const 00052 { 00053 shared_ptr<BaseNode> parent = shared_static_cast<BaseNode> 00054 (make_shared(mParent)); 00055 00056 // no parent, return identity 00057 if (parent.get() == 0) 00058 { 00059 return mIdentityMatrix; 00060 } else 00061 { 00062 return parent->GetWorldTransform(); 00063 } 00064 } 00065 00066 void BaseNode::SetLocalTransform(const salt::Matrix& /*transform*/) 00067 { 00068 } 00069 00070 void BaseNode::SetWorldTransform(const salt::Matrix& transform) 00071 { 00072 shared_ptr<BaseNode> parent = shared_static_cast<BaseNode> 00073 (make_shared(mParent)); 00074 00075 if (parent.get() == 0) 00076 { 00077 return; 00078 } 00079 00080 parent->SetWorldTransform(transform); 00081 } 00082 00083 // This routine is responsible for updating the local bounding box of 00084 // the node. The default behavior is to treat the node as a point. 00085 // Note that this is always called from Compute(). 00086 void BaseNode::ComputeBoundingBox() 00087 { 00088 mLocalBoundingBox.minVec.Set(0,0,0); 00089 mLocalBoundingBox.maxVec.Set(0,0,0); 00090 } 00091 00092 void BaseNode::PrePhysicsUpdate(float deltaTime) 00093 { 00094 // perform update on hierarchy 00095 TLeafList baseNodes; 00096 ListChildrenSupportingClass<BaseNode>(baseNodes); 00097 for (TLeafList::iterator i = baseNodes.begin(); i!= baseNodes.end(); ++i) 00098 { 00099 shared_static_cast<BaseNode>(*i)->PrePhysicsUpdate(deltaTime); 00100 } 00101 00102 // do the internal update. This can be overridden by derived classes 00103 // to add custom behavior 00104 PrePhysicsUpdateInternal(deltaTime); 00105 00106 ComputeBoundingBox(); 00107 } 00108 00109 void BaseNode::PostPhysicsUpdate() 00110 { 00111 // perform update on hierarchy 00112 TLeafList baseNodes; 00113 ListChildrenSupportingClass<BaseNode>(baseNodes); 00114 for (TLeafList::iterator i = baseNodes.begin(); i!= baseNodes.end(); ++i) 00115 { 00116 shared_static_cast<BaseNode>(*i)->PostPhysicsUpdate(); 00117 } 00118 00119 // do the internal update this can be overridden by derived classes 00120 // to add custom behavior 00121 PostPhysicsUpdateInternal(); 00122 } 00123 00124 void BaseNode::UpdateHierarchy() 00125 { 00126 // do the internal update this can be overridden by derived classes 00127 // to add custom behavior 00128 UpdateHierarchyInternal(); 00129 00130 // generate the bounding volume of this node 00131 Matrix worldTransform = GetWorldTransform(); 00132 mWorldBoundingBox = mLocalBoundingBox; 00133 mWorldBoundingBox.TransformBy(worldTransform); 00134 00135 // perform update on hierarchy 00136 TLeafList baseNodes; 00137 ListChildrenSupportingClass<BaseNode>(baseNodes); 00138 for (TLeafList::iterator i = baseNodes.begin(); i!= baseNodes.end(); ++i) 00139 { 00140 shared_ptr<BaseNode> node = shared_static_cast<BaseNode>(*i); 00141 node->UpdateHierarchy(); 00142 00143 // here we merge our world bounding volume with the child 00144 // volumes 00145 mWorldBoundingBox.Encapsulate(node->GetWorldBoundingBox()); 00146 } 00147 } 00148 00149 shared_ptr<Scene> BaseNode::GetScene() 00150 { 00151 // is this node the scene node ? 00152 shared_ptr<Scene> self = shared_dynamic_cast<Scene>(make_shared(GetSelf())); 00153 if (self.get() != 0) 00154 { 00155 return self; 00156 } 00157 00158 // move up the hierarchy until we find a scene node 00159 return make_shared(FindParentSupportingClass<Scene>()); 00160 } 00161 00162 void BaseNode::EnableDebugMode() 00163 { 00164 mDebugMode = true; 00165 } 00166 00167 void BaseNode::DisableDebugMode() 00168 { 00169 mDebugMode = false; 00170 } 00171 00172 void BaseNode::PrePhysicsUpdateInternal(float /*deltaTime*/) 00173 { 00174 } 00175 00176 void BaseNode::PostPhysicsUpdateInternal() 00177 { 00178 } 00179 00180 void BaseNode::UpdateHierarchyInternal() 00181 { 00182 } 00183 00184 const salt::AABB3& BaseNode::GetWorldBoundingBox() const 00185 { 00186 return mWorldBoundingBox; 00187 } 00188 00189 bool BaseNode::ImportScene(const string& fileName, shared_ptr<ParameterList> parameter) 00190 { 00191 shared_ptr<SceneServer> sceneServer = shared_dynamic_cast<SceneServer> 00192 (GetCore()->Get("/sys/server/scene")); 00193 00194 if (sceneServer.get() == 0) 00195 { 00196 GetLog()->Error() << "(BaseNode) ERROR: SceneServer not found\n"; 00197 return false; 00198 } 00199 00200 shared_ptr<BaseNode> node = shared_dynamic_cast<BaseNode> 00201 (make_shared(GetSelf())); 00202 return sceneServer->ImportScene(fileName,node,parameter); 00203 } 00204 00205 salt::Vector3f BaseNode::GetLocalPos(const salt::Vector3f& worldPos) 00206 { 00207 Matrix invWorld = GetWorldTransform(); 00208 invWorld.InvertRotationMatrix(); 00209 return invWorld.Transform(worldPos); 00210 } 00211 00212 00213