Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ReferenceApplication/ReferenceAppLayer/src/OgreRefAppWorld.cpp @ 2

Last change on this file since 2 was 1, checked in by landauf, 17 years ago
File size: 11.4 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of the OGRE Reference Application, a layer built
4on top of OGRE(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreRefAppWorld.h"
30#include "OgreRefAppOgreHead.h"
31#include "OgreRefAppPlane.h"
32#include "OgreRefAppBall.h"
33#include "OgreRefAppJointSubtypes.h"
34#include "OgreRefAppBox.h"
35#include "OgreRefAppCollideCamera.h"
36
37//-------------------------------------------------------------------------
38template<> OgreRefApp::World* Ogre::Singleton<OgreRefApp::World>::ms_Singleton = 0;
39OgreRefApp::World* OgreRefApp::World::getSingletonPtr(void)
40{
41    return ms_Singleton;
42}
43OgreRefApp::World& OgreRefApp::World::getSingleton(void)
44{ 
45    assert( ms_Singleton );  return ( *ms_Singleton ); 
46}
47//-------------------------------------------------------------------------
48namespace OgreRefApp
49{
50    //-------------------------------------------------------------------------
51    World::World(SceneManager* sceneMgr, WorldType worldType)
52        : mSceneMgr(sceneMgr), mWorldType(worldType)
53    {
54        mSimulationStepSize = 0.01f;
55
56        // Create the dynamics world
57        mOdeWorld = new dWorld();
58        mOdeContactGroup = new dJointGroup();
59
60        mIntersectionQuery = mSceneMgr->createIntersectionQuery();
61        switch (worldType)
62        {
63        case World::WT_REFAPP_GENERIC:
64            mIntersectionQuery->setWorldFragmentType(SceneQuery::WFT_NONE);
65            break;
66        case World::WT_REFAPP_BSP:
67            mIntersectionQuery->setWorldFragmentType(SceneQuery::WFT_PLANE_BOUNDED_REGION);
68            break;
69        };
70
71    }
72    //-------------------------------------------------------------------------
73    World::~World()
74    {
75                clear();
76
77                delete mIntersectionQuery;
78
79        // Destroy dynamix world
80                delete mOdeContactGroup;
81        delete mOdeWorld;
82
83    }
84    //-------------------------------------------------------------------------
85    SceneManager* World::getSceneManager(void)
86    {
87        return mSceneMgr;
88    }
89    //-------------------------------------------------------------------------
90    OgreHead* World::createOgreHead(const String& name, 
91        const Vector3& pos, const Quaternion& orientation)
92    {
93        OgreHead* head = new OgreHead(name);
94        head->setPosition(pos);
95        head->setOrientation(orientation);
96
97        mObjects[name] = head;
98
99        return head;
100    }
101    //-------------------------------------------------------------------------
102    FinitePlane* World::createPlane(const String& name, Real width, Real height, const Vector3& pos, 
103        const Quaternion& orientation)
104    {
105        FinitePlane* plane = new FinitePlane(name, width, height);
106        plane->setPosition(pos);
107        plane->setOrientation(orientation);
108
109        mObjects[name] = plane;
110
111        return plane;
112    }
113    //-------------------------------------------------------------------------
114    Ball* World::createBall(const String& name, Real radius, const Vector3& pos, 
115        const Quaternion& orientation)
116    {
117        OgreRefApp::Ball* ball = new OgreRefApp::Ball(name, radius);
118        ball->setPosition(pos);
119        ball->setOrientation(orientation);
120
121        mObjects[name] = ball;
122
123        return ball;
124    }
125    //-------------------------------------------------------------------------
126    void World::clear(void)
127    {
128        ObjectMap::iterator i;
129        for (i = mObjects.begin(); i != mObjects.end(); ++i)
130        {
131            delete i->second;
132        }
133        mObjects.clear();
134
135        JointMap::iterator ji;
136        for (ji = mJoints.begin(); ji != mJoints.end(); ++ji)
137        {
138            delete ji->second;
139        }
140        mJoints.clear();
141    }
142    //-------------------------------------------------------------------------
143    dWorld* World::getOdeWorld(void)
144    {
145        return mOdeWorld;
146    }
147    //-------------------------------------------------------------------------
148    void World::_applyDynamics(Real timeElapsed)
149    {
150        if (timeElapsed != 0.0f)
151        {
152            // ODE will throw an error if timestep = 0
153
154            mOdeWorld->step(dReal(timeElapsed));
155            // Now update the objects in the world
156            ObjectSet::iterator i, iend;
157            iend = mDynamicsObjects.end();
158            for (i = mDynamicsObjects.begin(); i != iend; ++i)
159            {
160                (*i)->_updateFromDynamics();
161            }
162            // Clear contacts
163            mOdeContactGroup->empty();
164        }
165
166    }
167    //-------------------------------------------------------------------------
168    void World::_notifyDynamicsStateForObject(ApplicationObject* obj, bool dynamicsEnabled)
169    {
170        // NB std::set prevents duplicates & errors on erasing non-existent objects
171        if (dynamicsEnabled)
172        {
173            mDynamicsObjects.insert(obj);
174        }
175        else
176        {
177            mDynamicsObjects.erase(obj);
178        }
179    }
180    //-------------------------------------------------------------------------
181    void World::setGravity(const Vector3& vec)
182    {
183        mGravity = vec;
184        mOdeWorld->setGravity(vec.x, vec.y, vec.z);
185    }
186    //-------------------------------------------------------------------------
187    const Vector3& World::getGravity(void)
188    {
189        return mGravity;
190    }
191    //-------------------------------------------------------------------------
192    dJointGroup* World::getOdeContactJointGroup(void)
193    {
194        return mOdeContactGroup;
195    }
196    //-------------------------------------------------------------------------
197    void World::_applyCollision(void)
198    {
199        // Collision detection
200        IntersectionSceneQueryResult& results = mIntersectionQuery->execute();
201
202        // Movables to Movables
203        SceneQueryMovableIntersectionList::iterator it, itend;
204        itend = results.movables2movables.end();
205        for (it = results.movables2movables.begin(); it != itend; ++it)
206        {
207            /* debugging
208            MovableObject *mo1, *mo2;
209            mo1 = it->first;
210            mo2 = it->second;
211            */
212
213            // Get user defined objects (generic in OGRE)
214            UserDefinedObject *uo1, *uo2;
215            uo1 = it->first->getUserObject();
216            uo2 = it->second->getUserObject();
217
218            // Only perform collision if we have UserDefinedObject links
219            if (uo1 && uo2)
220            {
221                // Cast to ApplicationObject
222                ApplicationObject *ao1, *ao2;
223                ao1 = static_cast<ApplicationObject*>(uo1);
224                ao2 = static_cast<ApplicationObject*>(uo2);
225                // Do detailed collision test
226                ao1->testCollide(ao2);
227            }
228        }
229
230        // Movables to World
231        SceneQueryMovableWorldFragmentIntersectionList::iterator wit, witend;
232        witend = results.movables2world.end();
233        for (wit = results.movables2world.begin(); wit != witend; ++wit)
234        {
235            MovableObject *mo = wit->first;
236            SceneQuery::WorldFragment *wf = wit->second;
237
238            // Get user defined objects (generic in OGRE)
239            UserDefinedObject *uo = mo->getUserObject();
240
241            // Only perform collision if we have UserDefinedObject link
242            if (uo)
243            {
244                // Cast to ApplicationObject
245                ApplicationObject *ao = static_cast<ApplicationObject*>(uo);
246                // Do detailed collision test
247                ao->testCollide(wf);
248            }
249        }
250
251    }
252    //-------------------------------------------------------------------------
253    Joint* World::createJoint(const String& name, Joint::JointType jtype,
254        ApplicationObject* obj1, ApplicationObject* obj2)
255    {
256        Joint* ret;
257        switch (jtype)
258        {
259        case Joint::JT_BALL:
260            ret = new BallJoint(jtype, obj1, obj2);
261            break;
262        case Joint::JT_HINGE:
263            ret = new HingeJoint(jtype, obj1, obj2);
264            break;
265        case Joint::JT_HINGE2:
266            ret = new Hinge2Joint(jtype, obj1, obj2);
267            break;
268        case Joint::JT_SLIDER:
269            ret = new SliderJoint(jtype, obj1, obj2);
270            break;
271        case Joint::JT_UNIVERSAL:
272            ret = new UniversalJoint(jtype, obj1, obj2);
273            break;
274
275        }
276
277        mJoints[name] = ret;
278        return ret;
279    }
280    //-------------------------------------------------------------------------
281    void World::setSimulationStepSize(Real step)
282    {
283        mSimulationStepSize = step;
284    }
285    //-------------------------------------------------------------------------
286    Real World::getSimulationStepSize(void)
287    {
288        return mSimulationStepSize;
289    }
290    //-------------------------------------------------------------------------
291    void World::simulationStep(Real timeElapsed)
292    {
293        /* Hmm, gives somewhat jerky results*/
294        static Real leftOverTime = 0.0f;
295
296                Real time = timeElapsed + leftOverTime; 
297                unsigned int steps = (unsigned int)(time / mSimulationStepSize);
298                for(unsigned int  i=0; i < steps; ++i)
299        {
300                        _applyCollision();
301            _applyDynamics(mSimulationStepSize);
302        }
303                leftOverTime = time - (steps * mSimulationStepSize);
304        /*
305                _applyCollision();
306        _applyDynamics(timeElapsed);
307        */
308
309
310    }
311    //-------------------------------------------------------------------------
312    OgreRefApp::Box* World::createBox(const String& name, 
313        Real width, Real height, Real depth,
314        const Vector3& pos, const Quaternion& orientation)
315    {
316        OgreRefApp::Box* box = new OgreRefApp::Box(name, width, height, depth);
317        box->setPosition(pos);
318        box->setOrientation(orientation);
319
320        mObjects[name] = box;
321
322        return box;
323    }
324    //-------------------------------------------------------------------------
325    CollideCamera* World::createCamera(const String& name, const Vector3& pos,
326        const Quaternion& orientation )
327    {
328        CollideCamera* cam = new CollideCamera(name);
329        cam->setPosition(pos);
330        cam->setOrientation(orientation);
331
332        mObjects[name] = cam;
333
334        return cam;
335
336    }
337}
338
Note: See TracBrowser for help on using the repository browser.