Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2303 was 2303, checked in by rgrieder, 15 years ago
  • Added support for attaching physical WorldEntities to each other. Currently you can only add static objects to kinematic/dynamic/static other objects. Future plans involve attaching kinematic objects to static/kinematic ones. All other combinations don't make sense at all.
  • Added CollisionShape, SphereCollisionShape and CompoundCollisionShape

Usage for collision shapes (example):

<LinearEntity collisionType="kinematic">

<attached>

<Model position="0,0,0" scale=10 mesh="ast1.mesh" />
<StaticEntity position="0,10,0" collisionType="static"> # Everything else than "static" fails!

<collisionShapes>

<SphereCollisionShape radius=40 position="10,10,-10"/>
<CompoundCollisionShape position="4,4,4"> # You can also make compound shapes directly

<SphereCollisionShape radius=10/>

</CompoundCollisionShape>

</collisionShapes>

</StaticEntity>

</attached>

</LinearEntity>

  • Property svn:eol-style set to native
File size: 7.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 *      ...
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        // finally add all rigid bodies to the physics engine
129        if (hasPhysics())
130        {
131            for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
132            {
133                WorldEntity* temp = dynamic_cast<WorldEntity*>(*it);
134                if (temp)
135                {
136                    if (temp->getCollisionType() != WorldEntity::None)
137                        this->physicalWorld_->addRigidBody(temp->getPhysicalBody());
138                }
139            }
140        }
141    }
142
143    void Scene::registerVariables()
144    {
145        REGISTERSTRING(this->skybox_,     network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
146        REGISTERDATA(this->ambientLight_, network::direction::toclient, new network::NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
147    }
148
149    void Scene::setPhysicalWorld(bool wantPhysics, const Vector3& worldAabbMin, const Vector3& worldAabbMax)
150    {
151        if (wantPhysics && !hasPhysics())
152        {
153            btVector3 worldAabbMin(worldAabbMin.x, worldAabbMin.y, worldAabbMin.z);
154            btVector3 worldAabbMax(worldAabbMax.x, worldAabbMax.y, worldAabbMax.z);
155
156            btDefaultCollisionConfiguration*     collisionConfig = new btDefaultCollisionConfiguration();
157            btCollisionDispatcher*               dispatcher      = new btCollisionDispatcher(collisionConfig);
158            bt32BitAxisSweep3*                   broadphase      = new bt32BitAxisSweep3(worldAabbMin,worldAabbMax);
159            btSequentialImpulseConstraintSolver* solver          = new btSequentialImpulseConstraintSolver;
160
161            this->physicalWorld_ =  new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);
162
163            // Disable Gravity for space
164            this->physicalWorld_->setGravity(btVector3(0,0,0));
165        }
166        else
167        {
168            // TODO: Destroy Bullet physics
169        }
170    }
171
172    void Scene::tick(float dt)
173    {
174        if (physicalWorld_)
175            physicalWorld_->stepSimulation(dt,(int)(dt/0.0166666f));
176    }
177
178    void Scene::setSkybox(const std::string& skybox)
179    {
180        if (Core::showsGraphics() && this->sceneManager_)
181            this->sceneManager_->setSkyBox(true, skybox);
182
183        this->skybox_ = skybox;
184    }
185
186    void Scene::setAmbientLight(const ColourValue& colour)
187    {
188        if (Core::showsGraphics() && this->sceneManager_)
189            this->sceneManager_->setAmbientLight(colour);
190
191        this->ambientLight_ = colour;
192    }
193
194    void Scene::setShadow(bool bShadow)
195    {
196        if (Core::showsGraphics() && this->sceneManager_)
197        {
198            if (bShadow)
199                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
200            else
201                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_NONE);
202        }
203
204        this->bShadows_ = bShadow;
205    }
206
207    void Scene::addObject(BaseObject* object)
208    {
209        this->objects_.push_back(object);
210        object->setScene(this);
211    }
212
213    BaseObject* Scene::getObject(unsigned int index) const
214    {
215        unsigned int i = 0;
216        for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
217        {
218            if (i == index)
219                return (*it);
220            ++i;
221        }
222        return 0;
223    }
224}
Note: See TracBrowser for help on using the repository browser.