Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Hackfixed compiler problem with gcc.

  • Property svn:eol-style set to native
File size: 8.8 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 "objects/worldentities/WorldEntity.h"
46
47namespace orxonox
48{
49    CreateFactory(Scene);
50
51    Scene::Scene(BaseObject* creator) : BaseObject(creator), network::Synchronisable(creator)
52    {
53        RegisterObject(Scene);
54
55        this->setScene(this);
56        this->bShadows_ = false;
57
58        if (Core::showsGraphics())
59        {
60            if (Ogre::Root::getSingletonPtr())
61            {
62                this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
63                this->rootSceneNode_ = this->sceneManager_->getRootSceneNode();
64            }
65            else
66            {
67                this->sceneManager_ = 0;
68                this->rootSceneNode_ = 0;
69            }
70        }
71        else
72        {
73            // create a dummy SceneManager of our own since we don't have Ogre::Root.
74            this->sceneManager_ = new Ogre::DefaultSceneManager("");
75            this->rootSceneNode_ = this->sceneManager_->getRootSceneNode();
76        }
77
78        // No physics for default
79        this->physicalWorld_ = 0;
80
81        // test test test
82        if (Core::showsGraphics() && this->sceneManager_)
83        {
84            Ogre::Light* light;
85            light = this->sceneManager_->createLight("Light-1");
86            light->setType(Ogre::Light::LT_DIRECTIONAL);
87            light->setDiffuseColour(ColourValue(1.0, 0.9, 0.6, 1.0));
88            light->setSpecularColour(ColourValue(1.0, 0.9, 0.6, 1.0));
89            light->setDirection(1, -0.3, 0.3);
90        }
91        // test test test
92
93        this->registerVariables();
94    }
95
96    Scene::~Scene()
97    {
98        if (this->isInitialized())
99        {
100            if (Ogre::Root::getSingletonPtr())
101            {
102                Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
103            }
104            else if (!Core::showsGraphics())
105            {
106                delete this->sceneManager_;
107            }
108        }
109    }
110
111    void Scene::XMLPort(Element& xmlelement, XMLPort::Mode mode)
112    {
113        SUPER(Scene, XMLPort, xmlelement, mode);
114
115        XMLPortParam(Scene, "skybox", setSkybox, getSkybox, xmlelement, mode);
116        XMLPortParam(Scene, "ambientlight", setAmbientLight, getAmbientLight, xmlelement, mode).defaultValues(ColourValue(0.2, 0.2, 0.2, 1));
117        XMLPortParam(Scene, "shadow", setShadow, getShadow, xmlelement, mode).defaultValues(true);
118
119        const int defaultMaxWorldSize = 100000;
120        Vector3 worldAabbMin(-defaultMaxWorldSize, -defaultMaxWorldSize, -defaultMaxWorldSize);
121        Vector3 worldAabbMax( defaultMaxWorldSize,  defaultMaxWorldSize,  defaultMaxWorldSize);
122        XMLPortParamVariable(Scene, "negativeWorldRange", worldAabbMin, xmlelement, mode);
123        XMLPortParamVariable(Scene, "positiveWorldRange", worldAabbMax, xmlelement, mode);
124        XMLPortParam(Scene, "hasPhysics", setPhysicalWorld, hasPhysics, xmlelement, mode).defaultValue(0, true).defaultValue(1, worldAabbMin).defaultValue(2, worldAabbMax);
125
126        XMLPortObjectExtended(Scene, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
127    }
128
129    void Scene::registerVariables()
130    {
131        REGISTERSTRING(this->skybox_,     network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
132        REGISTERDATA(this->ambientLight_, network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
133    }
134
135    void Scene::setPhysicalWorld(bool wantPhysics, const Vector3& worldAabbMin, const Vector3& worldAabbMax)
136    {
137        if (wantPhysics && !hasPhysics())
138        {
139                        float x = worldAabbMin.x;
140                        float y = worldAabbMin.y;
141                        float z = worldAabbMin.z;
142            btVector3 worldAabbMin(x,y,z);
143                        x = worldAabbMax.x;
144                        y = worldAabbMax.y;
145                        z = worldAabbMax.z;
146            btVector3 worldAabbMax(x,y,z);
147
148            btDefaultCollisionConfiguration*     collisionConfig = new btDefaultCollisionConfiguration();
149            btCollisionDispatcher*               dispatcher      = new btCollisionDispatcher(collisionConfig);
150            bt32BitAxisSweep3*                   broadphase      = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax);
151            btSequentialImpulseConstraintSolver* solver          = new btSequentialImpulseConstraintSolver;
152
153            this->physicalWorld_ =  new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);
154
155            // Disable Gravity for space
156            this->physicalWorld_->setGravity(btVector3(0,0,0));
157        }
158        else
159        {
160            // TODO: Destroy Bullet physics
161        }
162    }
163
164    void Scene::tick(float dt)
165    {
166        if (physicalWorld_)
167        {
168            if (this->physicsQueue_.size() > 0)
169            {
170                // Add all scheduled WorldEntities
171                for (std::set<btRigidBody*>::const_iterator it = this->physicsQueue_.begin();
172                    it != this->physicsQueue_.end(); ++it)
173                {
174                    if (!(*it)->isInWorld())
175                        this->physicalWorld_->addRigidBody(*it);
176                }
177                this->physicsQueue_.clear();
178            }
179
180            // TODO: This is not stable! If physics cannot be calculated real time anymore,
181            //       framerate will drop exponentially.
182            physicalWorld_->stepSimulation(dt,(int)(dt/0.0166666f + 1.0f));
183        }
184    }
185
186    void Scene::setSkybox(const std::string& skybox)
187    {
188        if (Core::showsGraphics() && this->sceneManager_)
189            this->sceneManager_->setSkyBox(true, skybox);
190
191        this->skybox_ = skybox;
192    }
193
194    void Scene::setAmbientLight(const ColourValue& colour)
195    {
196        if (Core::showsGraphics() && this->sceneManager_)
197            this->sceneManager_->setAmbientLight(colour);
198
199        this->ambientLight_ = colour;
200    }
201
202    void Scene::setShadow(bool bShadow)
203    {
204        if (Core::showsGraphics() && this->sceneManager_)
205        {
206            if (bShadow)
207                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
208            else
209                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_NONE);
210        }
211
212        this->bShadows_ = bShadow;
213    }
214
215    void Scene::addObject(BaseObject* object)
216    {
217        this->objects_.push_back(object);
218        object->setScene(this);
219    }
220
221    BaseObject* Scene::getObject(unsigned int index) const
222    {
223        unsigned int i = 0;
224        for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
225        {
226            if (i == index)
227                return (*it);
228            ++i;
229        }
230        return 0;
231    }
232
233    void Scene::addRigidBody(btRigidBody* body)
234    {
235        if (!this->physicalWorld_)
236            COUT(1) << "Error: Cannot WorldEntity body to physical Scene: No physics." << std::endl;
237        else if (body)
238            this->physicsQueue_.insert(body);
239    }
240
241    void Scene::removeRigidBody(btRigidBody* body)
242    {
243        if (!this->physicalWorld_)
244            COUT(1) << "Error: Cannot WorldEntity body to physical Scene: No physics." << std::endl;
245        else if (body)
246        {
247            this->physicalWorld_->removeRigidBody(body);
248            // Also check queue
249            std::set<btRigidBody*>::iterator it = this->physicsQueue_.find(body);
250            if (it != this->physicsQueue_.end())
251                this->physicsQueue_.erase(it);
252        }
253    }
254}
Note: See TracBrowser for help on using the repository browser.