Update of /cvsroot/simspark/simspark/spark/oxygen/sceneserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15620/sceneserver Added Files: basenode.cpp basenode.h basenode_c.cpp camera.cpp camera.h camera_c.cpp fpscontroller.cpp fpscontroller.h fpscontroller_c.cpp scene.cpp scene.h scene_c.cpp sceneimporter.h sceneimporter_c.cpp sceneserver.cpp sceneserver.h sceneserver_c.cpp transform.cpp transform.h transform_c.cpp Log Message: --- NEW FILE: transform.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: transform.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "transform.h" #include "sceneserver.h" using namespace boost; using namespace oxygen; using namespace salt; using namespace zeitgeist; Transform::Transform() : BaseNode() { mChangedMark = -1; mLocalTransform.Identity(); mOldLocalTransform.Identity(); mWorldTransform.Identity(); SetName("transform"); } Transform::~Transform() { } int Transform::GetChangedMark() const { return mChangedMark; } const salt::Matrix& Transform::GetLocalTransform() const { return mLocalTransform; } const salt::Matrix& Transform::GetOldLocalTransform() const { return mOldLocalTransform; } const salt::Matrix& Transform::GetWorldTransform() const { return mWorldTransform; } void Transform::SetLocalTransform(const salt::Matrix &transform) { mChangedMark = SceneServer::GetTransformMark(); mOldLocalTransform = mLocalTransform; mLocalTransform = transform; } void Transform::SetWorldTransform(const salt::Matrix &transform) { shared_ptr<BaseNode> parent = shared_static_cast<BaseNode> (make_shared(mParent)); if (parent.get() == 0) { return; } mChangedMark = SceneServer::GetTransformMark(); mOldLocalTransform = mLocalTransform; mLocalTransform = transform; parent->SetWorldTransform(mIdentityMatrix); } void Transform::SetLocalPos(const salt::Vector3f &pos) { mChangedMark = SceneServer::GetTransformMark(); mOldLocalTransform = mLocalTransform; mLocalTransform.Pos() = pos; UpdateHierarchyInternal(); } void Transform::SetLocalRotation(const salt::Vector3f &rot) { mChangedMark = SceneServer::GetTransformMark(); mOldLocalTransform = mLocalTransform; Vector3f pos = mLocalTransform.Pos(); mLocalTransform.RotationX(gDegToRad(rot[0])); mLocalTransform.RotateY(gDegToRad(rot[1])); mLocalTransform.RotateZ(gDegToRad(rot[2])); mLocalTransform.Pos() = pos; UpdateHierarchyInternal(); } void Transform::OnLink() { UpdateHierarchyInternal(); } void Transform::UpdateHierarchyInternal() { shared_ptr<BaseNode> parent = shared_static_cast<BaseNode>(make_shared(mParent)); // no parent, return local transform if (parent.get() == NULL) { mWorldTransform = mLocalTransform; } else { mWorldTransform = parent->GetWorldTransform() * mLocalTransform; } } --- NEW FILE: scene.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2003 Koblenz University $Id: scene.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "scene.h" using namespace boost; using namespace oxygen; using namespace salt; using namespace zeitgeist; Scene::Scene() : BaseNode(), mModified(false) { } Scene::~Scene() { } const salt::Matrix& Scene::GetWorldTransform() const { return mIdentityMatrix; } void Scene::SetWorldTransform(const salt::Matrix &/*transform*/) { } void Scene::SetModified(bool modified) { mModified = modified; } bool Scene::GetModified() { return mModified; } --- NEW FILE: basenode.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: basenode.h,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. BaseNode NOTE: HISTORY: 05.11.02 - MK - Initial version TODO: TOFIX: */ #ifndef OXYGEN_BASENODE_H #define OXYGEN_BASENODE_H #include <salt/matrix.h> #include <salt/bounds.h> #include <zeitgeist/node.h> namespace oxygen { class Scene; /** BaseNode is the base class for all nodes which are part of the scene hierarchy. It's Hierarchy functionality (children, naming, etc..) is inherited from zeitgeist. It does NOT have an explicit local and world transform. */ class BaseNode : public zeitgeist::Node { // // Functions // public: BaseNode(); virtual ~BaseNode(); // transformation related /** return the local transform of this node. (default: returns * identity) */ virtual const salt::Matrix& GetLocalTransform() const; /** returns the world transform of this node (default: returns * parents world transform) */ virtual const salt::Matrix& GetWorldTransform() const; /** sets the local transform of this node (default: ignored) */ virtual void SetLocalTransform(const salt::Matrix &transform); /** sets the world transform of this node (default: ignored) */ virtual void SetWorldTransform(const salt::Matrix &transform); // bounding box related /** computes the local bounding box of the node */ virtual void ComputeBoundingBox(); /** returns the world bounding box of this node */ const salt::AABB3& GetWorldBoundingBox() const; // scene graph update passes /** updates internal state before physics calculation */ void PrePhysicsUpdate(float deltaTime); /** updates internal state after physics calculation */ void PostPhysicsUpdate(); /** update hierarchical data (position, bounding volumes, etc..) */ void UpdateHierarchy(); /** moves up the hierarchy, until it finds a scene */ boost::shared_ptr<Scene> GetScene(); /** enables debug mode controls */ void EnableDebugMode(); /** disabled debug mode controls */ void DisableDebugMode(); /** imports a scene from a file below this Node */ bool ImportScene(const std::string& fileName, boost::shared_ptr<zeitgeist::ParameterList> parameter); protected: /** returns the corresponding local coordinates to the given world coordinates */ salt::Vector3f GetLocalPos(const salt::Vector3f& worldPos); /** updates internal state before physics calculation */ virtual void PrePhysicsUpdateInternal(float deltaTime); /** updates internal state after physics calculation */ virtual void PostPhysicsUpdateInternal(); /** updates hierarchical date (position, bounding volumes, etc..) */ virtual void UpdateHierarchyInternal(); // // Members // protected: /** the identity matrix */ static const salt::Matrix mIdentityMatrix; /** debug mode (for additional visualization) */ bool mDebugMode; /** local bounding box */ salt::AABB3 mLocalBoundingBox; /** world bounding box */ salt::AABB3 mWorldBoundingBox; }; DECLARE_CLASS(BaseNode); } //namespace oxygen #endif //OXYGEN_BASENODE_H --- NEW FILE: transform.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: transform.h,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Transform NOTE: HISTORY: 05.11.02 - MK - Initial version TODO: TOFIX: */ #ifndef OXYGEN_TRANSFORM_H #define OXYGEN_TRANSFORM_H #include "basenode.h" namespace oxygen { /** Transform is used to do local transforms relative to a parent node. */ class Transform : public BaseNode { // // Functions // public: Transform(); virtual ~Transform(); // transformation related /** returns the old local transform of this node */ const salt::Matrix& GetOldLocalTransform() const; /** returns the local transform of this node */ virtual const salt::Matrix& GetLocalTransform() const; /** returns the world transform of this node */ virtual const salt::Matrix& GetWorldTransform() const; /** sets the local transform of this node */ virtual void SetLocalTransform(const salt::Matrix &transform); /** sets the world transform of this node */ virtual void SetWorldTransform(const salt::Matrix &transform); /** sets the local position of this node */ void SetLocalPos(const salt::Vector3f &pos); /** sets the local rotation of this node in degrees */ void SetLocalRotation(const salt::Vector3f &rot); /** returns the current transform mark */ int GetChangedMark() const; protected: /** upon linkage, we have to update our world transform */ virtual void OnLink(); private: /** updates hierarchical date (position, bounding volumes, etc..) */ virtual void UpdateHierarchyInternal(); private: /** local transformation relative to parent */ salt::Matrix mLocalTransform; /** world transform generated by multiplying the parent's world transform with the local transform */ salt::Matrix mWorldTransform; /** Transform mark from the SceneServer; this value is updated with the the current value if the local transform matrix is modified */ int mChangedMark; /** the previous transformation relative to the parent */ salt::Matrix mOldLocalTransform; }; DECLARE_CLASS(Transform); } //namespace oxygen #endif //OXYGEN_TRANSFORM_H --- NEW FILE: fpscontroller_c.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2003 Koblenz University $Id: fpscontroller_c.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "fpscontroller.h" using namespace boost; using namespace oxygen; FUNCTION(FPSController,setAcceleration) { float inAccel; if ( (in.GetSize() != 1) || (! in.GetValue(in.begin(),inAccel)) ) { return false; } obj->SetAcceleration(inAccel); return true; } FUNCTION(FPSController,getAcceleration) { return obj->GetAcceleration(); } void CLASS(FPSController)::DefineClass() { DEFINE_BASECLASS(oxygen/BodyController); DEFINE_FUNCTION(setAcceleration); DEFINE_FUNCTION(getAcceleration); } --- NEW FILE: fpscontroller.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: fpscontroller.h,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef OXYGEN_FPSCONTROLLER_H #define OXYGEN_FPSCONTROLLER_H #include <oxygen/physicsserver/bodycontroller.h> namespace oxygen { /** \class FPSController is a BodyController, that provides first * person shooter (FPS) movement, i.e. moving forward, backward, * strafing etc. The node maintains a state for each movement. This * state can either be activated or deactivated with some accessor * functions. As long as a state is activated the node performs the * associated action during each time step. */ class FPSController : public BodyController { // // Functions // public: FPSController(); virtual ~FPSController(); /** adds a delta increment to the current horizontal angle */ void AdjustHAngle(const float delta); /** adds a delta increment to the current vertical angle */ void AdjustVAngle(const float delta); /** enables or disables forward movement */ void Forward(const bool state); /** enables or disables backwad movement */ void Backward(const bool state); /** enables or disables left strafing */ void StrafeLeft(const bool state); /** enables or disables right strafing */ void StrafeRight(const bool state); /** enables or disables up movement */ void Up(const bool state); /** enables or disables down movement */ void Down(const bool state); /** sets the applied acceleration */ void SetAcceleration(const float accel); /** returns the applied acceleration */ float GetAcceleration() const; protected: /** calculates and applies the force needed to perfom the * activated movements */ virtual void PrePhysicsUpdateInternal(float deltaTime); // // Members // protected: /** the acceleration of the controller */ float mAcceleration; /** the current horizontal angle */ float mHAngle; /** the current vertical angle */ float mVAngle; // event states /** event state 'forward' */ bool mForward; /** event state 'backward' */ bool mBackward; /** event state 'left' */ bool mLeft; /** event state 'right' */ bool mRight; /** event state 'up' */ bool mUp; /** event state 'down' */ bool mDown; }; DECLARE_CLASS(FPSController); } //namespace oxygen #endif //OXYGEN_FPSCONTROLLER_H --- NEW FILE: sceneimporter_c.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: sceneimporter_c.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "sceneimporter.h" using namespace oxygen; void CLASS(SceneImporter)::DefineClass() { DEFINE_BASECLASS(zeitgeist/Leaf); } --- NEW FILE: camera.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: camera.h,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef KEROSIN_CAMERA_H #define KEROSIN_CAMERA_H #include "basenode.h" #include <salt/frustum.h> namespace oxygen { /** Camera encapsualtes all data needed to describe the viewpoint from * which a scene is rendered. The active camera is responsible to * construct a frustum needed to render the scene. */ class Camera : public BaseNode { // // Functions // public: Camera(); virtual ~Camera(); // set properties /** sets viewpoint properties */ void SetViewport(int x, int y, int width, int height); int GetViewportX(); int GetViewportY(); int GetViewportWidth(); int GetViewportHeight(); /** sets the field of view (FOV) */ void SetFOV(const float fov); /** sets the distance of the Z near plane */ void SetZNear(const float zNear); /** sets the distance of the Z far plane */ void SetZFar(const float zFar); /** adjusts the current FOV, i.e. adds a delta increment */ void AdjustFOV(const float fov); /** adjusts the distance of the Z near plane, i.e adds a delta increment */ void AdjustZNear(const float zNear); /** adjusts the distance of the Z far plane, i.e adds a delta increment */ void AdjustZFar(const float zFar); /** returns the field of View */ float GetFOV() const; /** returns the distance of the Z near plane */ float GetZNear() const; /** returns the distance of the Z far plane */ float GetZFar() const; /** returns the view transformation matrix */ const salt::Matrix& GetViewTransform() const; /** returns the projection matrix */ const salt::Matrix& GetProjectionTransform() const; /** fills in a frustum object with the correct parameters for this camera */ void DescribeFrustum(salt::Frustum& frustum) const; /** sets the view transform to be the inverted WorldTransform and sets up the projection transform matrix **/ void Bind(); protected: /** gets the right viewport resolution */ virtual void OnLink(); private: /** calculates the view matrix (world->view space transformation) */ virtual void UpdateHierarchyInternal(); // // Members // protected: /** horizontal field of view, default is 60 degrees */ float mFOV; /** near clipping plane, default is 1 */ float mZNear; /** far clipping plane, default is 2000 */ float mZFar; /** x-position of upper left viewport corner, default is 0 */ int mX; /** y-position of upper left viewport corner, default is 0 */ int mY; /** width of viewport, default is the engine window width */ int mWidth; /** height of viewport, default is the egine window height */ int mHeight; float mHalfWorldWidth; float mHalfWorldHeight; /** the view transformation matrix */ salt::Matrix mViewTransform; /** the projection matrix */ salt::Matrix mProjectionTransform; }; DECLARE_CLASS(Camera); } //namespace kerosin #endif //KEROSIN_CAMERA_H --- NEW FILE: scene.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: scene.h,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Scene NOTE: HISTORY: 05.11.02 - MK - Initial version TODO: TOFIX: */ #ifndef OXYGEN_SCENE_H #define OXYGEN_SCENE_H #include "basenode.h" namespace oxygen { /** Scene is the root node of a simulatable/displayable hierarchy. It is usually created via the scene server. */ class Scene : public BaseNode { public: Scene(); ~Scene(); /** returns the world transform of this node (always identity, terminates upward recursion) */ virtual const salt::Matrix& GetWorldTransform() const; /** sets the world transform of this node */ virtual void SetWorldTransform(const salt::Matrix &transform); /** marks the scene as modified, i.e. scene nodes were added or removed since the last update. This useful for monitors to decide between an incremental or a full state update */ void SetModified(bool modified); /** returns true iff the scene is marked modified */ bool GetModified(); protected: /** true, if the scene is modified */ bool mModified; }; DECLARE_CLASS(Scene); } //namespace oxygen #endif //OXYGEN_SCENE_H --- NEW FILE: sceneimporter.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: sceneimporter.h,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef OXYGEN_SCENEIMPORTER #define OXYGEN_SCENEIMPORTER #include <zeitgeist/class.h> #include <zeitgeist/leaf.h> #include <salt/fileclasses.h> namespace oxygen { class BaseNode; class SceneImporter : public zeitgeist::Leaf { public: SceneImporter() : zeitgeist::Leaf() {} virtual ~SceneImporter() {}; /** import a scene from a file */ virtual bool ImportScene(const std::string& fileName, boost::shared_ptr<BaseNode> root, boost::shared_ptr<zeitgeist::ParameterList> parameter) = 0; /** import a scene from a string description */ virtual bool ParseScene(const std::string& scene, boost::shared_ptr<BaseNode> root, boost::shared_ptr<zeitgeist::ParameterList> parameter) = 0; }; DECLARE_ABSTRACTCLASS(SceneImporter); } // namespace oxygen #endif // OXYGEN_SCENEIMPORTER --- NEW FILE: sceneserver.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: sceneserver.h,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. SceneServer NOTE: HISTORY: 05.11.02 - MK - Initial version TODO: TOFIX: */ #ifndef OXYGEN_SCENESERVER_H #define OXYGEN_SCENESERVER_H #include <zeitgeist/class.h> #include <zeitgeist/node.h> namespace oxygen { #if 0 } #endif class Scene; class Space; class World; class BaseNode; class Transform; /** The scene server manages displayable subtrees within the object hierarchy. Each subtree begins with a Scene node. The scene server knows which scene node is currently active and updates that node (and its corresponding subtree). */ class SceneServer : public zeitgeist::Node { // // Functions // public: SceneServer(); ~SceneServer(); /** creates a new scene hierarchy at a specific location, new hierarchy is also made current */ boost::shared_ptr<Scene> CreateScene(const std::string &location); /** sets the active scene */ bool SetActiveScene(const std::string &location); /** returns a reference to the current active scene */ boost::shared_ptr<Scene> GetActiveScene() { return mActiveScene; } /** updates the state of the current active scene (deltaTime is in seconds) */ void Update(float deltaTime); /** imports a scene from a file below the given BaseNode */ bool ImportScene(const std::string& fileName, boost::shared_ptr<BaseNode> root, boost::shared_ptr<zeitgeist::ParameterList> parameter); /** creates an instance of \param importerName and registers it as a SceneImporter to the SceneServer */ bool InitSceneImporter(const std::string& importerName); /** returns the current label for modified transform nodes */ static int GetTransformMark(); protected: // // Members // /** gets missing references */ void UpdateCache(); /** resets all cached references */ void ResetCache(); /** resets all cached references */ virtual void OnUnlink(); /** reparents all children of node to the parent of node; Their local transform matrix is multiplied with the local transform matrix of node */ void ReparentTransformChildren(boost::shared_ptr<Transform> node); /** recursively reparents all transform nodes whose only children are also transform node */ void RemoveTransformPaths(boost::shared_ptr<zeitgeist::Leaf> root); private: /** the current active scene */ boost::shared_ptr<Scene> mActiveScene; /** cached reference to the Space node below the active scene */ boost::shared_ptr<Space> mActiveSpace; /** cached reference to the World node below the active scene */ boost::shared_ptr<World> mActiveWorld; /** modified transform nodes are labeled with this value, the value is incremented each cycle to avoid a resetting */ static int mTransformMark; }; DECLARE_CLASS(SceneServer); } //namespace oxygen #endif //OXYGEN_SCENESERVER_H --- NEW FILE: sceneserver_c.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: sceneserver_c.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. SceneServer The scene server manages displayable subtrees within the object hierarchy. Each subtree begins with a Scene node. The scene server knows which scene node is currently active and updates/displays that node (and its corresponding subtree). */ #include "sceneserver.h" using namespace boost; using namespace oxygen; using namespace zeitgeist; using namespace std; FUNCTION(SceneServer,createScene) { string inLocation; if ( (in.GetSize() != 1) || (! in.GetValue(in.begin(),inLocation)) ) { return false; } obj->CreateScene(inLocation); return true; } FUNCTION(SceneServer,setActiveScene) { string inLocation; if ( (in.GetSize() != 1) || (! in.GetValue(in.begin(),inLocation)) ) { return false; } obj->SetActiveScene(inLocation); return true; } FUNCTION(SceneServer,initSceneImporter) { string inImporterName; if ( (in.GetSize() != 1) || (! in.GetValue(in.begin(),inImporterName)) ) { return false; } return obj->InitSceneImporter(inImporterName); } void CLASS(SceneServer)::DefineClass() { DEFINE_BASECLASS(zeitgeist/Node); DEFINE_FUNCTION(createScene); DEFINE_FUNCTION(setActiveScene); DEFINE_FUNCTION(initSceneImporter); } --- NEW FILE: transform_c.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: transform_c.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "transform.h" using namespace boost; using namespace oxygen; using namespace zeitgeist; using namespace salt; FUNCTION(Transform,setLocalPos) { Vector3f inPos; if ( (in.GetSize() == 0) || (! in.GetValue(in.begin(), inPos)) ) { return false; } obj->SetLocalPos(inPos); return true; } FUNCTION(Transform,setLocalRotation) { Vector3f inRot; if ( (in.GetSize() == 0) || (! in.GetValue(in.begin(), inRot)) ) { return false; } obj->SetLocalRotation(inRot); return true; } FUNCTION(Transform,setLocalTransform) { // float InM00, float InM01, float InM02, float InM03, // float InM10, float InM11, float InM12, float InM13, // float InM20, float InM21, float InM22, float InM23, // float InM30, float InM31, float InM32, float InM33 if (in.GetSize() != 16) { return false; } float m[16]; ParameterList::TVector::const_iterator iter = in.begin(); for (int i=0;i<16;++i) { if (! in.GetValue(iter,m[i])) { return false; } ++iter; } obj->SetLocalTransform(Matrix(m)); return true; } void CLASS(Transform)::DefineClass() { DEFINE_BASECLASS(oxygen/BaseNode); DEFINE_FUNCTION(setLocalPos); DEFINE_FUNCTION(setLocalRotation); DEFINE_FUNCTION(setLocalTransform); } --- NEW FILE: fpscontroller.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2003 Koblenz University $Id: fpscontroller.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "fpscontroller.h" #include <oxygen/physicsserver/body.h> #include <zeitgeist/logserver/logserver.h> using namespace boost; using namespace oxygen; using namespace salt; FPSController::FPSController() : BodyController() { mHAngle = 0.0f; mVAngle = 0.0f; mForward = false; mBackward = false; mLeft = false; mRight = false; mUp = false; mDown = false; mAcceleration = 10; } FPSController::~FPSController() { } void FPSController::PrePhysicsUpdateInternal(float /*deltaTime*/) { if (mBody.get() == 0) { return; } // determine force direction Vector3f vec(0.0f,0.0f,0.0f); if (mForward) vec.y() += 1.0f; if (mBackward) vec.y() -= 1.0f; if (mRight) vec.x() += 1.0f; if (mLeft) vec.x() -= 1.0f; if (mUp) vec.z() += 1.0f; if (mDown) vec.z() -= 1.0f; // constrain angles if(mVAngle > 88.0f) { mVAngle = 88.0f; } else if(mVAngle<-88.0f) { mVAngle = -88.0f; } Matrix matrix; float hAngle = gDegToRad(-mHAngle); float vAngle = gDegToRad(-mVAngle); matrix.RotationZ(hAngle); matrix.RotateX(vAngle); mBody->SetRotation(matrix); if (vec.SquareLength() > 0) { float force = mBody->GetMass() * mAcceleration; vec *= force; Matrix fwd; fwd.RotationZ(hAngle); mBody->AddForce(vec.y() * fwd.Up()); Matrix side; side.RotationX(vAngle); mBody->AddForce(vec.x() * fwd.Right()); mBody->AddForce(vec.z() * Vector3f(0,0,1)); } } void FPSController::AdjustHAngle(const float delta) { mHAngle += delta; } void FPSController::AdjustVAngle(const float delta) { mVAngle += delta; } void FPSController::Forward(const bool state) { mForward = state; } void FPSController::Backward(const bool state) { mBackward = state; } void FPSController::StrafeLeft(const bool state) { mLeft = state; } void FPSController::StrafeRight(const bool state) { mRight= state; } void FPSController::Up(const bool state) { mUp = state; } void FPSController::Down(const bool state) { mDown = state; } void FPSController::SetAcceleration(const float accel) { mAcceleration = accel; } float FPSController::GetAcceleration() const { return mAcceleration; } --- NEW FILE: basenode.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: basenode.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. BaseNode */ #include "basenode.h" #include "sceneserver.h" #include "scene.h" #include <zeitgeist/logserver/logserver.h> using namespace boost; using namespace oxygen; using namespace salt; using namespace zeitgeist; using namespace std; const salt::Matrix BaseNode::mIdentityMatrix(salt::Matrix::GetIdentity()); BaseNode::BaseNode() : zeitgeist::Node(), mDebugMode(false) { } BaseNode::~BaseNode() { } const salt::Matrix& BaseNode::GetLocalTransform() const { return mIdentityMatrix; } const salt::Matrix& BaseNode::GetWorldTransform() const { shared_ptr<BaseNode> parent = shared_static_cast<BaseNode> (make_shared(mParent)); // no parent, return identity if (parent.get() == 0) { return mIdentityMatrix; } else { return parent->GetWorldTransform(); } } void BaseNode::SetLocalTransform(const salt::Matrix& /*transform*/) { } void BaseNode::SetWorldTransform(const salt::Matrix& transform) { shared_ptr<BaseNode> parent = shared_static_cast<BaseNode> (make_shared(mParent)); if (parent.get() == 0) { return; } parent->SetWorldTransform(transform); } // This routine is responsible for updating the local bounding box of // the node. The default behavior is to treat the node as a point. // Note that this is always called from Compute(). void BaseNode::ComputeBoundingBox() { mLocalBoundingBox.minVec.Set(0,0,0); mLocalBoundingBox.maxVec.Set(0,0,0); } void BaseNode::PrePhysicsUpdate(float deltaTime) { // perform update on hierarchy TLeafList baseNodes; ListChildrenSupportingClass<BaseNode>(baseNodes); for (TLeafList::iterator i = baseNodes.begin(); i!= baseNodes.end(); ++i) { shared_static_cast<BaseNode>(*i)->PrePhysicsUpdate(deltaTime); } // do the internal update. This can be overridden by derived classes // to add custom behavior PrePhysicsUpdateInternal(deltaTime); ComputeBoundingBox(); } void BaseNode::PostPhysicsUpdate() { // perform update on hierarchy TLeafList baseNodes; ListChildrenSupportingClass<BaseNode>(baseNodes); for (TLeafList::iterator i = baseNodes.begin(); i!= baseNodes.end(); ++i) { shared_static_cast<BaseNode>(*i)->PostPhysicsUpdate(); } // do the internal update this can be overridden by derived classes // to add custom behavior PostPhysicsUpdateInternal(); } void BaseNode::UpdateHierarchy() { // do the internal update this can be overridden by derived classes // to add custom behavior UpdateHierarchyInternal(); // generate the bounding volume of this node Matrix worldTransform = GetWorldTransform(); mWorldBoundingBox = mLocalBoundingBox; mWorldBoundingBox.TransformBy(worldTransform); // perform update on hierarchy TLeafList baseNodes; ListChildrenSupportingClass<BaseNode>(baseNodes); for (TLeafList::iterator i = baseNodes.begin(); i!= baseNodes.end(); ++i) { shared_ptr<BaseNode> node = shared_static_cast<BaseNode>(*i); node->UpdateHierarchy(); // here we merge our world bounding volume with the child // volumes mWorldBoundingBox.Encapsulate(node->GetWorldBoundingBox()); } } shared_ptr<Scene> BaseNode::GetScene() { // is this node the scene node ? shared_ptr<Scene> self = shared_dynamic_cast<Scene>(make_shared(GetSelf())); if (self.get() != 0) { return self; } // move up the hierarchy until we find a scene node return make_shared(FindParentSupportingClass<Scene>()); } void BaseNode::EnableDebugMode() { mDebugMode = true; } void BaseNode::DisableDebugMode() { mDebugMode = false; } void BaseNode::PrePhysicsUpdateInternal(float /*deltaTime*/) { } void BaseNode::PostPhysicsUpdateInternal() { } void BaseNode::UpdateHierarchyInternal() { } const salt::AABB3& BaseNode::GetWorldBoundingBox() const { return mWorldBoundingBox; } bool BaseNode::ImportScene(const string& fileName, shared_ptr<ParameterList> parameter) { shared_ptr<SceneServer> sceneServer = shared_dynamic_cast<SceneServer> (GetCore()->Get("/sys/server/scene")); if (sceneServer.get() == 0) { GetLog()->Error() << "(BaseNode) ERROR: SceneServer not found\n"; return false; } shared_ptr<BaseNode> node = shared_dynamic_cast<BaseNode> (make_shared(GetSelf())); return sceneServer->ImportScene(fileName,node,parameter); } salt::Vector3f BaseNode::GetLocalPos(const salt::Vector3f& worldPos) { Matrix invWorld = GetWorldTransform(); invWorld.InvertRotationMatrix(); return invWorld.Transform(worldPos); } --- NEW FILE: scene_c.cpp --- /* -*- mode: c++ -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2003 Koblenz University $Id: scene_c.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "scene.h" using namespace boost; using namespace oxygen; using namespace zeitgeist; void CLASS(Scene)::DefineClass() { DEFINE_BASECLASS(oxygen/BaseNode); } --- NEW FILE: camera.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2003 Koblenz University $Id: camera.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "camera.h" #include <salt/matrix.h> #include <zeitgeist/logserver/logserver.h> #include <zeitgeist/scriptserver/scriptserver.h> using namespace oxygen; using namespace salt; Camera::Camera() : BaseNode() { mViewTransform.Identity(); mFOV = 60.0f; mZNear = 1.0f; mZFar = 2000.0f; mX = 0; mY = 0; mWidth = 640; mHeight = 480; SetName("camera"); } Camera::~Camera() { } /** This is some dangerous looking code, but it's not as bad as it seems. The code extracts a frustum given the projection and view transforms. It is really fast and very generic because of that. */ void Camera::DescribeFrustum(Frustum& frustum) const { // concatenate projection and view transform Matrix frustumMatrix = mProjectionTransform * mViewTransform; // Get plane parameters float* m = frustumMatrix.m; Plane *p = &frustum.mPlanes[Frustum::PI_RIGHT]; p->normal.Set(m[3]-m[0], m[7]-m[4], m[11]-m[8]); p->d = m[15]-m[12]; p = &frustum.mPlanes[Frustum::PI_LEFT]; p->normal.Set(m[3]+m[0], m[7]+m[4], m[11]+m[8]); p->d = m[15]+m[12]; p = &frustum.mPlanes[Frustum::PI_BOTTOM]; p->normal.Set(m[3]+m[1], m[7]+m[5], m[11]+m[9]); p->d = m[15]+m[13]; p = &frustum.mPlanes[Frustum::PI_TOP]; p->normal.Set(m[3]-m[1], m[7]-m[5], m[11]-m[9]); p->d = m[15]-m[13]; p = &frustum.mPlanes[Frustum::PI_NEAR]; p->normal.Set(m[3]-m[2], m[7]-m[6], m[11]-m[10]); p->d = m[15]-m[14]; p = &frustum.mPlanes[Frustum::PI_FAR]; p->normal.Set(m[3]+m[2], m[7]+m[6], m[11]+m[10]); p->d = m[15]+m[14]; // Normalize all plane normals for(int i=0;i<6;++i) { frustum.mPlanes[i].Normalize(); } // set base position frustum.mBasePos = GetWorldTransform().Pos(); } void Camera::Bind() { mViewTransform = GetWorldTransform(); mViewTransform.RotateX(90); mViewTransform.InvertRotationMatrix(); // setup the projection matrix mProjectionTransform.CalcInfiniteFrustum( -mHalfWorldWidth, mHalfWorldWidth, -mHalfWorldHeight, mHalfWorldHeight, mZNear); } void Camera::OnLink() { bool gotSetup = ( GetScript()->GetVariable("Viewport.XRes", mWidth) && GetScript()->GetVariable("Viewport.YRes", mHeight) ); if (! gotSetup) { GetLog()->Error() << "(Camera) unable to read setup from ScriptServer\n"; } } void Camera::UpdateHierarchyInternal() { // make sure values are within bounds gClamp(mFOV, 10.0f, 170.0f); mHalfWorldWidth = mZNear * (float)tan(gDegToRad(mFOV*0.5f)); mHalfWorldHeight = mHalfWorldWidth * (mHeight/(float)mWidth); } void Camera::SetViewport(int x, int y, int width, int height) { mX = x; mY = y; mWidth = width; mHeight = height; } int Camera::GetViewportX() { return mX; } int Camera::GetViewportY() { return mY; } int Camera::GetViewportWidth() { return mWidth; } int Camera::GetViewportHeight() { return mHeight; } void Camera::SetFOV(const float fov) { mFOV = fov; } void Camera::SetZNear(const float zNear) { mZNear = zNear; } void Camera::SetZFar(const float zFar) { mZFar = zFar; } void Camera::AdjustFOV(const float fov) { mFOV+=fov; } void Camera::AdjustZNear(const float zNear) { mZNear+=zNear; } void Camera::AdjustZFar(const float zFar) { mZFar+=zFar; } float Camera::GetFOV() const { return mFOV; } float Camera::GetZNear() const { return mZNear; } float Camera::GetZFar()const { return mZFar; } const salt::Matrix& Camera::GetViewTransform() const { return mViewTransform; } const salt::Matrix& Camera::GetProjectionTransform() const { return mProjectionTransform; } --- NEW FILE: sceneserver.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: sceneserver.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "sceneserver.h" #include <zeitgeist/logserver/logserver.h> #include <zeitgeist/corecontext.h> #include <zeitgeist/fileserver/fileserver.h> #include <salt/vector.h> #include <salt/frustum.h> #include "transform.h" #include "scene.h" #include "sceneimporter.h" #include <oxygen/physicsserver/world.h> #include <oxygen/physicsserver/space.h> using namespace boost; using namespace oxygen; using namespace salt; using namespace zeitgeist; using namespace std; int SceneServer::mTransformMark = 0; SceneServer::SceneServer() : Node() { } SceneServer::~SceneServer() { } boost::shared_ptr<Scene> SceneServer::CreateScene(const std::string &location) { shared_ptr<CoreContext> context = GetCore()->CreateContext(); shared_ptr<Scene> scene = shared_static_cast<Scene> (context->New("oxygen/Scene", location)); if (scene.get() != 0) { ResetCache(); mActiveScene = scene; } return scene; } bool SceneServer::SetActiveScene(const std::string &location) { shared_ptr<Scene> scene = shared_dynamic_cast<Scene>(GetCore()->Get(location)); if (scene.get() != 0) { ResetCache(); mActiveScene = scene; return true; } return false; } void SceneServer::ResetCache() { mActiveScene.reset(); mActiveSpace.reset(); mActiveWorld.reset(); } void SceneServer::UpdateCache() { if (mActiveScene.get() == 0) { ResetCache(); return; } if (mActiveSpace.get() == 0) { // cache the space reference mActiveSpace = shared_dynamic_cast<Space> (mActiveScene->GetChildOfClass("Space")); } if (mActiveWorld.get() == 0) { // cache the world reference mActiveWorld = shared_dynamic_cast<World> (mActiveScene->GetChildOfClass("World")); } } void SceneServer::OnUnlink() { ResetCache(); } int SceneServer::GetTransformMark() { return mTransformMark; } /** Update the scene graph. We do not make the distinction between 'controllers' and 'scene graph nodes'. This design forces us to perform several update passes through the hierarchy. Nevertheless, the more homogenuous structure is worth it. An example Hierarchy: scene |- transform |- body | |- quakecontroller | |- camera The following passes are performed: 1st pass: PrePhysicsUpdate(deltaTime) The first update pass is responsible for updating the internal state of an object. For example, the quakecontroller has received input from the main application in terms of state changes like StrafeLeft, or Forward. As the controller is physics driven, it has to translate these commands to actual forces, which act on the body. This is done during this pass. After the first pass pyhsics simulation and collision are calculated using ODE. 2nd pass: PostPhysicsUpdate() This pass can be used to affect other nodes. For example, 'Body' has undergone physics simulation and collision detection. It has reached its final 'simulated' position, which has to be passed to the parent Transform node. 3rd pass: UpdateHierarchy() As the second pass affects the position of objects, we have to recalculate the transformation hierarchy before we can display the scene. */ void SceneServer::Update(float deltaTime) { if ( (deltaTime == 0.0f) || (mActiveScene.get() == 0) ) { return; } UpdateCache(); ++mTransformMark; mActiveScene->PrePhysicsUpdate(deltaTime); // determine collisions if (mActiveSpace.get() != 0) { mActiveSpace->Collide(); } // do physics if (mActiveWorld.get() != 0) { mActiveWorld->Step(deltaTime); } mActiveScene->PostPhysicsUpdate(); mActiveScene->UpdateHierarchy(); } bool SceneServer::ImportScene(const string& fileName, shared_ptr<BaseNode> root, shared_ptr<ParameterList> parameter) { if (! GetFile()->Exist(fileName)) { GetLog()->Error() << "(SceneServer) ERROR: cannot locate file '" << fileName << "'\n"; return false; } TLeafList importer; ListChildrenSupportingClass<SceneImporter>(importer); if (importer.size() == 0) { GetLog()->Error() << "(SceneServer) Warning: no SceneImporter registered\n"; } for ( TLeafList::iterator iter = importer.begin(); iter != importer.end(); ++iter ) { shared_ptr<SceneImporter> importer = shared_static_cast<SceneImporter>(*iter); if (importer->ImportScene(fileName,root,parameter)) { GetLog()->Normal() << "(SceneServer) imported scene file '" << fileName << " with '" << importer->GetName() << " at " << root->GetFullPath() << endl; RemoveTransformPaths(root); // mark the corresponding scene as modified shared_ptr<Scene> scene = root->GetScene(); if (scene.get() != 0) { scene->SetModified(true); } return true; } } GetLog()->Error() << "(SceneServer) ERROR: cannot import scene file '" << fileName << "'\n"; return false; } void SceneServer::ReparentTransformChildren(shared_ptr<Transform> node) { shared_ptr<BaseNode> parent = shared_dynamic_cast<BaseNode>(make_shared(node->GetParent())); // while not empty while (node->begin() != node->end()) { shared_ptr<Leaf> child = (*node->begin()); shared_ptr<Transform> tChild = shared_dynamic_cast<Transform>(child); if (tChild.get() != 0) { tChild->SetLocalTransform (node->GetLocalTransform() * tChild->GetLocalTransform()); } child->Unlink(); parent->AddChildReference(child); } } void SceneServer::RemoveTransformPaths(shared_ptr<Leaf> root) { if (root.get() == 0) { return; } // go top down and remove Transform nodes that only have Transform // node children and reparent them; note that reparented transform // nodes are automatically checked in the parent loop, as they are // appended to the child list in subsequent calls to // RemoveTransformPaths; this process leaves some transform node // without children, that are removed in a second pass for ( TLeafList::iterator iter = root->begin(); iter != root->end(); ++iter ) { RemoveTransformPaths(*iter); } shared_ptr<Transform> trans = shared_dynamic_cast<Transform>(root); bool tRoot = (trans.get() != 0); bool tChildOnly = true; TLeafList::iterator iter = root->begin(); while (iter != root->end()) { shared_ptr<Transform> tChild = shared_dynamic_cast<Transform>(*iter); if (tChild.get() == 0) { tChildOnly = false; } else { if (tChild->begin() == tChild->end()) { // remove a transform node without // children tChild->Unlink(); // restart as iter is now invalidated iter = root->begin(); continue; } } ++iter; } if ( (tRoot) && (tChildOnly)) { ReparentTransformChildren(trans); } } bool SceneServer::InitSceneImporter(const std::string& importerName) { shared_ptr<SceneImporter> importer = shared_dynamic_cast<SceneImporter>(GetCore()->New(importerName)); if (importer.get() == 0) { GetLog()->Error() << "ERROR (SceneServer::InitSceneImporter) " << "Unable to create '" << importerName << "'\n"; return false; } importer->SetName(importerName); AddChildReference(importer); GetLog()->Normal() << "(SceneServer) SceneImporter '" << importerName << "' registered\n"; return true; } --- NEW FILE: camera_c.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2003 Koblenz University $Id: camera_c.cpp,v 1.1 2005/12/05 21:21:17 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULA... [truncated message content] |