00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "sceneserver.h"
00024 #include <zeitgeist/logserver/logserver.h>
00025 #include <zeitgeist/corecontext.h>
00026 #include <zeitgeist/fileserver/fileserver.h>
00027 #include <salt/vector.h>
00028 #include <salt/frustum.h>
00029 #include "transform.h"
00030 #include "scene.h"
00031 #include "sceneimporter.h"
00032 #include <oxygen/physicsserver/world.h>
00033 #include <oxygen/physicsserver/space.h>
00034
00035 using namespace boost;
00036 using namespace oxygen;
00037 using namespace salt;
00038 using namespace zeitgeist;
00039 using namespace std;
00040
00041 int SceneServer::mTransformMark = 0;
00042
00043 SceneServer::SceneServer() : Node()
00044 {
00045 }
00046
00047 SceneServer::~SceneServer()
00048 {
00049 }
00050
00051 boost::shared_ptr<Scene> SceneServer::CreateScene(const std::string &location)
00052 {
00053 shared_ptr<CoreContext> context = GetCore()->CreateContext();
00054
00055 shared_ptr<Scene> scene = shared_static_cast<Scene>
00056 (context->New("oxygen/Scene", location));
00057
00058 if (scene.get() != 0)
00059 {
00060 ResetCache();
00061 mActiveScene = scene;
00062 }
00063
00064 return scene;
00065 }
00066
00067 bool SceneServer::SetActiveScene(const std::string &location)
00068 {
00069 shared_ptr<Scene> scene =
00070 shared_dynamic_cast<Scene>(GetCore()->Get(location));
00071
00072 if (scene.get() != 0)
00073 {
00074 ResetCache();
00075 mActiveScene = scene;
00076 return true;
00077 }
00078
00079 return false;
00080 }
00081
00082 void SceneServer::ResetCache()
00083 {
00084 mActiveScene.reset();
00085 mActiveSpace.reset();
00086 mActiveWorld.reset();
00087 }
00088
00089 void SceneServer::UpdateCache()
00090 {
00091 if (mActiveScene.get() == 0)
00092 {
00093 ResetCache();
00094 return;
00095 }
00096
00097 if (mActiveSpace.get() == 0)
00098 {
00099
00100 mActiveSpace = shared_dynamic_cast<Space>
00101 (mActiveScene->GetChildOfClass("Space"));
00102 }
00103
00104 if (mActiveWorld.get() == 0)
00105 {
00106
00107 mActiveWorld = shared_dynamic_cast<World>
00108 (mActiveScene->GetChildOfClass("World"));
00109 }
00110 }
00111
00112 void SceneServer::OnUnlink()
00113 {
00114 ResetCache();
00115 }
00116
00117 int SceneServer::GetTransformMark()
00118 {
00119 return mTransformMark;
00120 }
00121
00160 void SceneServer::Update(float deltaTime)
00161 {
00162 if (
00163 (deltaTime == 0.0f) ||
00164 (mActiveScene.get() == 0)
00165 )
00166 {
00167 return;
00168 }
00169
00170 UpdateCache();
00171 ++mTransformMark;
00172
00173 mActiveScene->PrePhysicsUpdate(deltaTime);
00174
00175
00176 if (mActiveSpace.get() != 0)
00177 {
00178 mActiveSpace->Collide();
00179 }
00180
00181
00182 if (mActiveWorld.get() != 0)
00183 {
00184 mActiveWorld->Step(deltaTime);
00185 }
00186
00187 mActiveScene->PostPhysicsUpdate();
00188 mActiveScene->UpdateHierarchy();
00189 }
00190
00191 bool SceneServer::ImportScene(const string& fileName, shared_ptr<BaseNode> root,
00192 shared_ptr<ParameterList> parameter)
00193 {
00194 if (! GetFile()->Exist(fileName))
00195 {
00196 GetLog()->Error() << "(SceneServer) ERROR: cannot locate file '"
00197 << fileName << "'\n";
00198
00199 return false;
00200 }
00201
00202 TLeafList importer;
00203 ListChildrenSupportingClass<SceneImporter>(importer);
00204
00205 if (importer.size() == 0)
00206 {
00207 GetLog()->Error()
00208 << "(SceneServer) Warning: no SceneImporter registered\n";
00209 }
00210
00211 for (
00212 TLeafList::iterator iter = importer.begin();
00213 iter != importer.end();
00214 ++iter
00215 )
00216 {
00217 shared_ptr<SceneImporter> importer =
00218 shared_static_cast<SceneImporter>(*iter);
00219
00220 if (importer->ImportScene(fileName,root,parameter))
00221 {
00222 GetLog()->Normal()
00223 << "(SceneServer) imported scene file '"
00224 << fileName << " with '"
00225 << importer->GetName()
00226 << " at " << root->GetFullPath() << endl;
00227
00228 RemoveTransformPaths(root);
00229
00230
00231 shared_ptr<Scene> scene = root->GetScene();
00232 if (scene.get() != 0)
00233 {
00234 scene->SetModified(true);
00235 }
00236
00237 return true;
00238 }
00239 }
00240
00241 GetLog()->Error() << "(SceneServer) ERROR: cannot import scene file '"
00242 << fileName << "'\n";
00243
00244 return false;
00245 }
00246
00247 void SceneServer::ReparentTransformChildren(shared_ptr<Transform> node)
00248 {
00249 shared_ptr<BaseNode> parent =
00250 shared_dynamic_cast<BaseNode>(make_shared(node->GetParent()));
00251
00252
00253 while (node->begin() != node->end())
00254 {
00255 shared_ptr<Leaf> child = (*node->begin());
00256
00257 shared_ptr<Transform> tChild
00258 = shared_dynamic_cast<Transform>(child);
00259
00260 if (tChild.get() != 0)
00261 {
00262 tChild->SetLocalTransform
00263 (node->GetLocalTransform() * tChild->GetLocalTransform());
00264 }
00265
00266 child->Unlink();
00267 parent->AddChildReference(child);
00268 }
00269 }
00270
00271 void SceneServer::RemoveTransformPaths(shared_ptr<Leaf> root)
00272 {
00273 if (root.get() == 0)
00274 {
00275 return;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285 for (
00286 TLeafList::iterator iter = root->begin();
00287 iter != root->end();
00288 ++iter
00289 )
00290 {
00291 RemoveTransformPaths(*iter);
00292 }
00293
00294 shared_ptr<Transform> trans = shared_dynamic_cast<Transform>(root);
00295 bool tRoot = (trans.get() != 0);
00296 bool tChildOnly = true;
00297
00298 TLeafList::iterator iter = root->begin();
00299 while (iter != root->end())
00300 {
00301 shared_ptr<Transform> tChild = shared_dynamic_cast<Transform>(*iter);
00302 if (tChild.get() == 0)
00303 {
00304 tChildOnly = false;
00305 } else
00306 {
00307 if (tChild->begin() == tChild->end())
00308 {
00309
00310
00311 tChild->Unlink();
00312
00313
00314 iter = root->begin();
00315 continue;
00316 }
00317 }
00318
00319 ++iter;
00320 }
00321
00322 if ( (tRoot) && (tChildOnly))
00323 {
00324 ReparentTransformChildren(trans);
00325 }
00326 }
00327
00328 bool SceneServer::InitSceneImporter(const std::string& importerName)
00329 {
00330 shared_ptr<SceneImporter> importer
00331 = shared_dynamic_cast<SceneImporter>(GetCore()->New(importerName));
00332
00333 if (importer.get() == 0)
00334 {
00335 GetLog()->Error() << "ERROR (SceneServer::InitSceneImporter) "
00336 << "Unable to create '" << importerName << "'\n";
00337 return false;
00338 }
00339
00340 importer->SetName(importerName);
00341 AddChildReference(importer);
00342
00343 GetLog()->Normal()
00344 << "(SceneServer) SceneImporter '" << importerName << "' registered\n";
00345
00346 return true;
00347 }
00348
00349