Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/orxonox/objects/Scene.cc @ 2518

Last change on this file since 2518 was 2374, checked in by rgrieder, 16 years ago

Trying to synchronise phyiscs over the network.

  • Removed derivation of CollisionShape from WorldEntity (BaseObject instead).
  • Property svn:eol-style set to native
File size: 9.9 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Reto Grieder (physics)
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "Scene.h"
31
32#include <OgreRoot.h>
33#include <OgreSceneManagerEnumerator.h>
34#include <OgreSceneNode.h>
35#include <OgreLight.h>
36
37#include "BulletCollision/BroadphaseCollision/btAxisSweep3.h"
38#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h"
39#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
40#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
41
42#include "core/CoreIncludes.h"
43#include "core/Core.h"
44#include "core/XMLPort.h"
45#include "tools/BulletConversions.h"
46#include "objects/worldentities/WorldEntity.h"
47
48namespace orxonox
49{
50    CreateFactory(Scene);
51
52    Scene::Scene(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)
53    {
54        RegisterObject(Scene);
55
56        this->setScene(this);
57        this->bShadows_ = false;
58
59        if (Core::showsGraphics())
60        {
61            if (Ogre::Root::getSingletonPtr())
62            {
63                this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
64                this->rootSceneNode_ = this->sceneManager_->getRootSceneNode();
65            }
66            else
67            {
68                this->sceneManager_ = 0;
69                this->rootSceneNode_ = 0;
70            }
71        }
72        else
73        {
74            // create a dummy SceneManager of our own since we don't have Ogre::Root.
75            this->sceneManager_ = new Ogre::DefaultSceneManager("");
76            this->rootSceneNode_ = this->sceneManager_->getRootSceneNode();
77        }
78
79        // No physics for default
80        this->physicalWorld_ = 0;
81
82        // test test test
83        if (Core::showsGraphics() && this->sceneManager_)
84        {
85            Ogre::Light* light;
86            light = this->sceneManager_->createLight("Light-1");
87            light->setType(Ogre::Light::LT_DIRECTIONAL);
88            light->setDiffuseColour(ColourValue(1.0, 0.9, 0.6, 1.0));
89            light->setSpecularColour(ColourValue(1.0, 0.9, 0.6, 1.0));
90            light->setDirection(1, -0.3, 0.3);
91        }
92        // test test test
93
94        this->registerVariables();
95    }
96
97    Scene::~Scene()
98    {
99        if (this->isInitialized())
100        {
101            if (Ogre::Root::getSingletonPtr())
102            {
103                Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
104            }
105            else if (!Core::showsGraphics())
106            {
107                delete this->sceneManager_;
108            }
109        }
110    }
111
112    void Scene::XMLPort(Element& xmlelement, XMLPort::Mode mode)
113    {
114        SUPER(Scene, XMLPort, xmlelement, mode);
115
116        XMLPortParam(Scene, "skybox", setSkybox, getSkybox, xmlelement, mode);
117        XMLPortParam(Scene, "ambientlight", setAmbientLight, getAmbientLight, xmlelement, mode).defaultValues(ColourValue(0.2, 0.2, 0.2, 1));
118        XMLPortParam(Scene, "shadow", setShadow, getShadow, xmlelement, mode).defaultValues(true);
119
120        //const int defaultMaxWorldSize = 100000;
121        //Vector3 worldAabbMin(-defaultMaxWorldSize, -defaultMaxWorldSize, -defaultMaxWorldSize);
122        //Vector3 worldAabbMax( defaultMaxWorldSize,  defaultMaxWorldSize,  defaultMaxWorldSize);
123        //XMLPortParamVariable(Scene, "negativeWorldRange", worldAabbMin, xmlelement, mode);
124        //XMLPortParamVariable(Scene, "positiveWorldRange", worldAabbMax, xmlelement, mode);
125        XMLPortParam(Scene, "hasPhysics", setPhysicalWorld, hasPhysics, xmlelement, mode).defaultValue(0, true);//.defaultValue(1, worldAabbMin).defaultValue(2, worldAabbMax);
126
127        XMLPortObjectExtended(Scene, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
128    }
129
130    void Scene::registerVariables()
131    {
132        REGISTERSTRING(this->skybox_,     network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
133        REGISTERDATA(this->ambientLight_, network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
134        REGISTERDATA(this->bHasPhysics_,  network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_hasPhysics));
135    }
136
137    void Scene::setPhysicalWorld(bool wantPhysics)//, const Vector3& worldAabbMin, const Vector3& worldAabbMax)
138    {
139        this->bHasPhysics_ = wantPhysics;
140        if (wantPhysics && !hasPhysics())
141        {
142            //float x = worldAabbMin.x;
143            //float y = worldAabbMin.y;
144            //float z = worldAabbMin.z;
145            btVector3 worldAabbMin(-100000, -100000, -100000);
146            //x = worldAabbMax.x;
147            //y = worldAabbMax.y;
148            //z = worldAabbMax.z;
149            btVector3 worldAabbMax(100000, 100000, 100000);
150
151            btDefaultCollisionConfiguration*     collisionConfig = new btDefaultCollisionConfiguration();
152            btCollisionDispatcher*               dispatcher      = new btCollisionDispatcher(collisionConfig);
153            bt32BitAxisSweep3*                   broadphase      = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax);
154            btSequentialImpulseConstraintSolver* solver          = new btSequentialImpulseConstraintSolver;
155
156            this->physicalWorld_ =  new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);
157
158            // Disable Gravity for space
159            this->physicalWorld_->setGravity(btVector3(0,0,0));
160        }
161        else
162        {
163            // TODO: Destroy Bullet physics
164        }
165    }
166
167    void Scene::tick(float dt)
168    {
169        if (physicalWorld_)
170        {
171            if (this->physicsQueue_.size() > 0)
172            {
173                // Add all scheduled WorldEntities
174                for (std::set<btRigidBody*>::const_iterator it = this->physicsQueue_.begin();
175                    it != this->physicsQueue_.end(); ++it)
176                {
177                    if (!(*it)->isInWorld())
178                    {
179                        //COUT(0) << "body position: " << omni_cast<Vector3>((*it)->getWorldTransform().getOrigin()) << std::endl;
180                        //COUT(0) << "body velocity: " << omni_cast<Vector3>((*it)->getLinearVelocity()) << std::endl;
181                        //COUT(0) << "body orientation: " << omni_cast<Quaternion>((*it)->getWorldTransform().getRotation()) << std::endl;
182                        //COUT(0) << "body angular: " << omni_cast<Vector3>((*it)->getAngularVelocity()) << std::endl;
183                        //COUT(0) << "body mass: " << omni_cast<float>((*it)->getInvMass()) << std::endl;
184                        //COUT(0) << "body inertia: " << omni_cast<Vector3>((*it)->getInvInertiaDiagLocal()) << std::endl;
185                        this->physicalWorld_->addRigidBody(*it);
186                    }
187                }
188                this->physicsQueue_.clear();
189            }
190
191            // TODO: This is not stable! If physics cannot be calculated real time anymore,
192            //       framerate will drop exponentially.
193            physicalWorld_->stepSimulation(dt,(int)(dt/0.0166666f + 1.0f));
194        }
195    }
196
197    void Scene::setSkybox(const std::string& skybox)
198    {
199        if (Core::showsGraphics() && this->sceneManager_)
200            this->sceneManager_->setSkyBox(true, skybox);
201
202        this->skybox_ = skybox;
203    }
204
205    void Scene::setAmbientLight(const ColourValue& colour)
206    {
207        if (Core::showsGraphics() && this->sceneManager_)
208            this->sceneManager_->setAmbientLight(colour);
209
210        this->ambientLight_ = colour;
211    }
212
213    void Scene::setShadow(bool bShadow)
214    {
215        if (Core::showsGraphics() && this->sceneManager_)
216        {
217            if (bShadow)
218                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
219            else
220                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_NONE);
221        }
222
223        this->bShadows_ = bShadow;
224    }
225
226    void Scene::addObject(BaseObject* object)
227    {
228        this->objects_.push_back(object);
229        object->setScene(this);
230    }
231
232    BaseObject* Scene::getObject(unsigned int index) const
233    {
234        unsigned int i = 0;
235        for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
236        {
237            if (i == index)
238                return (*it);
239            ++i;
240        }
241        return 0;
242    }
243
244    void Scene::addRigidBody(btRigidBody* body)
245    {
246        if (!this->physicalWorld_)
247            COUT(1) << "Error: Cannot add WorldEntity body to physical Scene: No physics." << std::endl;
248        else if (body)
249            this->physicsQueue_.insert(body);
250    }
251
252    void Scene::removeRigidBody(btRigidBody* body)
253    {
254        if (!this->physicalWorld_)
255            COUT(1) << "Error: Cannot remove WorldEntity body from physical Scene: No physics." << std::endl;
256        else if (body)
257        {
258            this->physicalWorld_->removeRigidBody(body);
259            // Also check queue
260            std::set<btRigidBody*>::iterator it = this->physicsQueue_.find(body);
261            if (it != this->physicsQueue_.end())
262                this->physicsQueue_.erase(it);
263        }
264    }
265}
Note: See TracBrowser for help on using the repository browser.