Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics_merge/src/orxonox/objects/Scene.cc @ 2442

Last change on this file since 2442 was 2442, checked in by rgrieder, 15 years ago

Finally merged physics stuff. Target is physics_merge because I'll have to do some testing first.

  • Property svn:eol-style set to native
File size: 10.0 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), 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        registerVariable(this->skybox_,       variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
133        registerVariable(this->ambientLight_, variableDirection::toclient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
134        registerVariable(this->bHasPhysics_,  variableDirection::toclient, new 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 (!Core::showsGraphics())
170        {
171            // We need to update the scene nodes if we don't render
172            this->rootSceneNode_->_update(true, false);
173        }
174        if (physicalWorld_)
175        {
176            if (this->physicsQueue_.size() > 0)
177            {
178                // Add all scheduled WorldEntities
179                for (std::set<btRigidBody*>::const_iterator it = this->physicsQueue_.begin();
180                    it != this->physicsQueue_.end(); ++it)
181                {
182                    if (!(*it)->isInWorld())
183                    {
184                        //COUT(0) << "body position: " << omni_cast<Vector3>((*it)->getWorldTransform().getOrigin()) << std::endl;
185                        //COUT(0) << "body velocity: " << omni_cast<Vector3>((*it)->getLinearVelocity()) << std::endl;
186                        //COUT(0) << "body orientation: " << omni_cast<Quaternion>((*it)->getWorldTransform().getRotation()) << std::endl;
187                        //COUT(0) << "body angular: " << omni_cast<Vector3>((*it)->getAngularVelocity()) << std::endl;
188                        //COUT(0) << "body mass: " << omni_cast<float>((*it)->getInvMass()) << std::endl;
189                        //COUT(0) << "body inertia: " << omni_cast<Vector3>((*it)->getInvInertiaDiagLocal()) << std::endl;
190                        this->physicalWorld_->addRigidBody(*it);
191                    }
192                }
193                this->physicsQueue_.clear();
194            }
195
196            // TODO: This is not stable! If physics cannot be calculated real time anymore,
197            //       framerate will drop exponentially.
198            physicalWorld_->stepSimulation(dt,(int)(dt/0.0166666f + 1.0f));
199        }
200    }
201
202    void Scene::setSkybox(const std::string& skybox)
203    {
204        if (Core::showsGraphics() && this->sceneManager_)
205            this->sceneManager_->setSkyBox(true, skybox);
206
207        this->skybox_ = skybox;
208    }
209
210    void Scene::setAmbientLight(const ColourValue& colour)
211    {
212        if (Core::showsGraphics() && this->sceneManager_)
213            this->sceneManager_->setAmbientLight(colour);
214
215        this->ambientLight_ = colour;
216    }
217
218    void Scene::setShadow(bool bShadow)
219    {
220        if (Core::showsGraphics() && this->sceneManager_)
221        {
222            if (bShadow)
223                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
224            else
225                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_NONE);
226        }
227
228        this->bShadows_ = bShadow;
229    }
230
231    void Scene::addObject(BaseObject* object)
232    {
233        this->objects_.push_back(object);
234        object->setScene(this);
235    }
236
237    BaseObject* Scene::getObject(unsigned int index) const
238    {
239        unsigned int i = 0;
240        for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
241        {
242            if (i == index)
243                return (*it);
244            ++i;
245        }
246        return 0;
247    }
248
249    void Scene::addRigidBody(btRigidBody* body)
250    {
251        if (!this->physicalWorld_)
252            COUT(1) << "Error: Cannot add WorldEntity body to physical Scene: No physics." << std::endl;
253        else if (body)
254            this->physicsQueue_.insert(body);
255    }
256
257    void Scene::removeRigidBody(btRigidBody* body)
258    {
259        if (!this->physicalWorld_)
260            COUT(1) << "Error: Cannot remove WorldEntity body from physical Scene: No physics." << std::endl;
261        else if (body)
262        {
263            this->physicalWorld_->removeRigidBody(body);
264            // Also check queue
265            std::set<btRigidBody*>::iterator it = this->physicsQueue_.find(body);
266            if (it != this->physicsQueue_.end())
267                this->physicsQueue_.erase(it);
268        }
269    }
270}
Note: See TracBrowser for help on using the repository browser.