source: OGRE/trunk/ogrenew/ReferenceApplication/ReferenceAppLayer/src/OgreRefAppWorld.cpp @ 692

Revision 692, 11.2 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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-2005 The OGRE Team
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-----------------------------------------------------------------------------
24*/
25#include "OgreRefAppWorld.h"
26#include "OgreRefAppOgreHead.h"
27#include "OgreRefAppPlane.h"
28#include "OgreRefAppBall.h"
29#include "OgreRefAppJointSubtypes.h"
30#include "OgreRefAppBox.h"
31#include "OgreRefAppCollideCamera.h"
32
33//-------------------------------------------------------------------------
34template<> OgreRefApp::World* Ogre::Singleton<OgreRefApp::World>::ms_Singleton = 0;
35OgreRefApp::World* OgreRefApp::World::getSingletonPtr(void)
36{
37    return ms_Singleton;
38}
39OgreRefApp::World& OgreRefApp::World::getSingleton(void)
40
41    assert( ms_Singleton );  return ( *ms_Singleton ); 
42}
43//-------------------------------------------------------------------------
44namespace OgreRefApp
45{
46    //-------------------------------------------------------------------------
47    World::World(SceneManager* sceneMgr, WorldType worldType)
48        : mSceneMgr(sceneMgr), mWorldType(worldType)
49    {
50        mSimulationStepSize = 0.01f;
51
52        // Create the dynamics world
53        mOdeWorld = new dWorld();
54        mOdeContactGroup = new dJointGroup();
55
56        mIntersectionQuery = mSceneMgr->createIntersectionQuery();
57        switch (worldType)
58        {
59        case World::WT_REFAPP_GENERIC:
60            mIntersectionQuery->setWorldFragmentType(SceneQuery::WFT_NONE);
61            break;
62        case World::WT_REFAPP_BSP:
63            mIntersectionQuery->setWorldFragmentType(SceneQuery::WFT_PLANE_BOUNDED_REGION);
64            break;
65        };
66
67    }
68    //-------------------------------------------------------------------------
69    World::~World()
70    {
71                clear();
72
73                delete mIntersectionQuery;
74
75        // Destroy dynamix world
76                delete mOdeContactGroup;
77        delete mOdeWorld;
78
79    }
80    //-------------------------------------------------------------------------
81    SceneManager* World::getSceneManager(void)
82    {
83        return mSceneMgr;
84    }
85    //-------------------------------------------------------------------------
86    OgreHead* World::createOgreHead(const String& name,
87        const Vector3& pos, const Quaternion& orientation)
88    {
89        OgreHead* head = new OgreHead(name);
90        head->setPosition(pos);
91        head->setOrientation(orientation);
92
93        mObjects[name] = head;
94
95        return head;
96    }
97    //-------------------------------------------------------------------------
98    FinitePlane* World::createPlane(const String& name, Real width, Real height, const Vector3& pos,
99        const Quaternion& orientation)
100    {
101        FinitePlane* plane = new FinitePlane(name, width, height);
102        plane->setPosition(pos);
103        plane->setOrientation(orientation);
104
105        mObjects[name] = plane;
106
107        return plane;
108    }
109    //-------------------------------------------------------------------------
110    Ball* World::createBall(const String& name, Real radius, const Vector3& pos,
111        const Quaternion& orientation)
112    {
113        OgreRefApp::Ball* ball = new OgreRefApp::Ball(name, radius);
114        ball->setPosition(pos);
115        ball->setOrientation(orientation);
116
117        mObjects[name] = ball;
118
119        return ball;
120    }
121    //-------------------------------------------------------------------------
122    void World::clear(void)
123    {
124        ObjectMap::iterator i;
125        for (i = mObjects.begin(); i != mObjects.end(); ++i)
126        {
127            delete i->second;
128        }
129        mObjects.clear();
130
131        JointMap::iterator ji;
132        for (ji = mJoints.begin(); ji != mJoints.end(); ++ji)
133        {
134            delete ji->second;
135        }
136        mJoints.clear();
137    }
138    //-------------------------------------------------------------------------
139    dWorld* World::getOdeWorld(void)
140    {
141        return mOdeWorld;
142    }
143    //-------------------------------------------------------------------------
144    void World::_applyDynamics(Real timeElapsed)
145    {
146        if (timeElapsed != 0.0f)
147        {
148            // ODE will throw an error if timestep = 0
149
150            mOdeWorld->step(dReal(timeElapsed));
151            // Now update the objects in the world
152            ObjectSet::iterator i, iend;
153            iend = mDynamicsObjects.end();
154            for (i = mDynamicsObjects.begin(); i != iend; ++i)
155            {
156                (*i)->_updateFromDynamics();
157            }
158            // Clear contacts
159            mOdeContactGroup->empty();
160        }
161
162    }
163    //-------------------------------------------------------------------------
164    void World::_notifyDynamicsStateForObject(ApplicationObject* obj, bool dynamicsEnabled)
165    {
166        // NB std::set prevents duplicates & errors on erasing non-existent objects
167        if (dynamicsEnabled)
168        {
169            mDynamicsObjects.insert(obj);
170        }
171        else
172        {
173            mDynamicsObjects.erase(obj);
174        }
175    }
176    //-------------------------------------------------------------------------
177    void World::setGravity(const Vector3& vec)
178    {
179        mGravity = vec;
180        mOdeWorld->setGravity(vec.x, vec.y, vec.z);
181    }
182    //-------------------------------------------------------------------------
183    const Vector3& World::getGravity(void)
184    {
185        return mGravity;
186    }
187    //-------------------------------------------------------------------------
188    dJointGroup* World::getOdeContactJointGroup(void)
189    {
190        return mOdeContactGroup;
191    }
192    //-------------------------------------------------------------------------
193    void World::_applyCollision(void)
194    {
195        // Collision detection
196        IntersectionSceneQueryResult& results = mIntersectionQuery->execute();
197
198        // Movables to Movables
199        SceneQueryMovableIntersectionList::iterator it, itend;
200        itend = results.movables2movables.end();
201        for (it = results.movables2movables.begin(); it != itend; ++it)
202        {
203            /* debugging
204            MovableObject *mo1, *mo2;
205            mo1 = it->first;
206            mo2 = it->second;
207            */
208
209            // Get user defined objects (generic in OGRE)
210            UserDefinedObject *uo1, *uo2;
211            uo1 = it->first->getUserObject();
212            uo2 = it->second->getUserObject();
213
214            // Only perform collision if we have UserDefinedObject links
215            if (uo1 && uo2)
216            {
217                // Cast to ApplicationObject
218                ApplicationObject *ao1, *ao2;
219                ao1 = static_cast<ApplicationObject*>(uo1);
220                ao2 = static_cast<ApplicationObject*>(uo2);
221                // Do detailed collision test
222                ao1->testCollide(ao2);
223            }
224        }
225
226        // Movables to World
227        SceneQueryMovableWorldFragmentIntersectionList::iterator wit, witend;
228        witend = results.movables2world.end();
229        for (wit = results.movables2world.begin(); wit != witend; ++wit)
230        {
231            MovableObject *mo = wit->first;
232            SceneQuery::WorldFragment *wf = wit->second;
233
234            // Get user defined objects (generic in OGRE)
235            UserDefinedObject *uo = mo->getUserObject();
236
237            // Only perform collision if we have UserDefinedObject link
238            if (uo)
239            {
240                // Cast to ApplicationObject
241                ApplicationObject *ao = static_cast<ApplicationObject*>(uo);
242                // Do detailed collision test
243                ao->testCollide(wf);
244            }
245        }
246
247    }
248    //-------------------------------------------------------------------------
249    Joint* World::createJoint(const String& name, Joint::JointType jtype,
250        ApplicationObject* obj1, ApplicationObject* obj2)
251    {
252        Joint* ret;
253        switch (jtype)
254        {
255        case Joint::JT_BALL:
256            ret = new BallJoint(jtype, obj1, obj2);
257            break;
258        case Joint::JT_HINGE:
259            ret = new HingeJoint(jtype, obj1, obj2);
260            break;
261        case Joint::JT_HINGE2:
262            ret = new Hinge2Joint(jtype, obj1, obj2);
263            break;
264        case Joint::JT_SLIDER:
265            ret = new SliderJoint(jtype, obj1, obj2);
266            break;
267        case Joint::JT_UNIVERSAL:
268            ret = new UniversalJoint(jtype, obj1, obj2);
269            break;
270
271        }
272
273        mJoints[name] = ret;
274        return ret;
275    }
276    //-------------------------------------------------------------------------
277    void World::setSimulationStepSize(Real step)
278    {
279        mSimulationStepSize = step;
280    }
281    //-------------------------------------------------------------------------
282    Real World::getSimulationStepSize(void)
283    {
284        return mSimulationStepSize;
285    }
286    //-------------------------------------------------------------------------
287    void World::simulationStep(Real timeElapsed)
288    {
289        /* Hmm, gives somewhat jerky results*/
290        static Real leftOverTime = 0.0f;
291
292                Real time = timeElapsed + leftOverTime;
293                unsigned int steps = (unsigned int)(time / mSimulationStepSize);
294                for(unsigned int  i=0; i < steps; ++i)
295        {
296                        _applyCollision();
297            _applyDynamics(mSimulationStepSize);
298        }
299                leftOverTime = time - (steps * mSimulationStepSize);
300        /*
301                _applyCollision();
302        _applyDynamics(timeElapsed);
303        */
304
305
306    }
307    //-------------------------------------------------------------------------
308    OgreRefApp::Box* World::createBox(const String& name,
309        Real width, Real height, Real depth,
310        const Vector3& pos, const Quaternion& orientation)
311    {
312        OgreRefApp::Box* box = new OgreRefApp::Box(name, width, height, depth);
313        box->setPosition(pos);
314        box->setOrientation(orientation);
315
316        mObjects[name] = box;
317
318        return box;
319    }
320    //-------------------------------------------------------------------------
321    CollideCamera* World::createCamera(const String& name, const Vector3& pos,
322        const Quaternion& orientation )
323    {
324        CollideCamera* cam = new CollideCamera(name);
325        cam->setPosition(pos);
326        cam->setOrientation(orientation);
327
328        mObjects[name] = cam;
329
330        return cam;
331
332    }
333}
334
Note: See TracBrowser for help on using the repository browser.