Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/ogreode/OgreOdeSpace.cpp @ 1919

Last change on this file since 1919 was 1919, checked in by rgrieder, 16 years ago

Added OgreODE to our source repository because already we really need the newest version. And there is no hope to find any packages under linux.
The files included should compile and link with Ogre 1.4/1.6 and ODE 0.9/0.10. I was only able to test Ogre 1.4 and ODE 0.9/.10 under msvc until now.

  • Property svn:eol-style set to native
File size: 13.2 KB
Line 
1
2#include "OgreOdePrecompiledHeaders.h"
3
4#include "OgreOdeBody.h"
5#include "OgreOdeSpace.h"
6#include "OgreOdeGeometry.h"
7#include "OgreOdeWorld.h"
8
9#include "OgreOdeCollision.h"
10
11using namespace OgreOde;
12using namespace Ogre;
13
14//------------------------------------------------------------------------------------------------
15Space::Space(World *world, const Space* space) :
16    _world(world),
17    _internal_collisions (true)
18{
19}
20//------------------------------------------------------------------------------------------------
21#if ODE_VERSION_MINOR > 9
22Space::Class Space::getClass()
23{
24        return (Space::Class)(dSpaceGetClass(_space));
25}
26#endif
27//------------------------------------------------------------------------------------------------
28dSpaceID Space::getSpaceID() const
29{
30        return _space;
31}
32//------------------------------------------------------------------------------------------------
33dSpaceID Space::getSpaceID(const Space* space) const
34{
35        if(space) 
36        return space->getSpaceID();
37        return 0;
38}
39//------------------------------------------------------------------------------------------------
40void Space::setAutoCleanup(bool on)
41{
42        dSpaceSetCleanup(_space,(on)?1:0);
43}
44//------------------------------------------------------------------------------------------------
45bool Space::getAutoCleanup()
46{
47        return ((dSpaceGetCleanup(_space))?true:false); 
48}
49//------------------------------------------------------------------------------------------------
50void Space::addGeometry(const Geometry& geometry)
51{
52        dSpaceAdd(_space,geometry.getGeometryID()); 
53}
54//------------------------------------------------------------------------------------------------
55void Space::removeGeometry(const Geometry& geometry)
56{
57        dSpaceRemove(_space,geometry.getGeometryID()); 
58}
59//------------------------------------------------------------------------------------------------
60bool Space::containsGeometry(const Geometry& geometry)
61{
62        return ((dSpaceQuery(_space,geometry.getGeometryID()))?true:false); 
63}
64//------------------------------------------------------------------------------------------------
65int Space::getGeometryCount()
66{
67        return dSpaceGetNumGeoms(_space); 
68}
69//------------------------------------------------------------------------------------------------
70Geometry* Space::getGeometry(int index)
71{
72        return (Geometry*) _world->getGeometryList().findItem((size_t)dSpaceGetGeom(_space,index)); 
73}
74//------------------------------------------------------------------------------------------------
75void Space::registerSpace()
76{
77        _world->getSpaceList().registerItem(this);
78        dGeomSetData((dGeomID)_space,(void*)this);
79}
80//------------------------------------------------------------------------------------------------
81void Space::collide(void* data)
82{
83        if(_internal_collisions)
84        {
85                dSpaceCollide(_space,data,World::collisionCallback);
86        }
87}
88//------------------------------------------------------------------------------------------------
89void Space::collide(Space* space,void* data)
90{
91        dSpaceCollide2((dGeomID)_space,(dGeomID)(space->getSpaceID()),data,World::collisionCallback);
92}
93//------------------------------------------------------------------------------------------------
94void Space::collide(Geometry* geometry,void* data)
95{
96        dSpaceCollide2((dGeomID)_space,geometry->getGeometryID(),data,World::collisionCallback);
97}
98
99//------------------------------------------------------------------------------------------------
100void Space::collide(CollisionCallback* colCallback, bool useInternalCollisionFlag)
101{
102        if(useInternalCollisionFlag && !_internal_collisions)
103        {
104                return;
105        }
106        void* data = colCallback;       
107        dSpaceCollide(_space, data, CollisionCallback::collisionCallback);
108}
109//------------------------------------------------------------------------------------------------
110void Space::collide(CollisionCallback* colCallback, Space* space)
111{
112        void* data = colCallback;       
113        dSpaceCollide2((dGeomID)_space,(dGeomID)(space->getSpaceID()),data, CollisionCallback::collisionCallback);
114}
115//------------------------------------------------------------------------------------------------
116void Space::collide(CollisionCallback* colCallback, Geometry* geometry, bool useInternalCollisionFlag)
117{
118        if(useInternalCollisionFlag && !_internal_collisions && geometry->getSpace() == this )
119                return;
120
121        void* data = colCallback;       
122        dSpaceCollide2((dGeomID)_space, geometry->getGeometryID(), data, CollisionCallback::collisionCallback);
123}
124
125//------------------------------------------------------------------------------------------------
126void Space::setInternalCollisions(bool collide)
127{
128        _internal_collisions = collide;
129}
130//------------------------------------------------------------------------------------------------
131bool Space::getInternalCollisions()
132{
133        return _internal_collisions;
134}
135//------------------------------------------------------------------------------------------------
136const AxisAlignedBox& Space::getAxisAlignedBox()
137{
138        dReal aabb[6];
139        dGeomGetAABB((dGeomID)_space,aabb);
140        _bounding_box.setExtents((Real)aabb[0],(Real)aabb[2],(Real)aabb[4],(Real)aabb[1],(Real)aabb[3],(Real)aabb[5]);
141        return _bounding_box;
142}
143//------------------------------------------------------------------------------------------------
144size_t Space::getID()
145{
146        return (size_t)_space;
147}
148//------------------------------------------------------------------------------------------------
149Space::~Space()
150{
151        _world->getSpaceList().unregisterItem((size_t)_space);
152        dSpaceDestroy(_space); 
153}
154//------------------------------------------------------------------------------------------------
155SimpleSpace::SimpleSpace(World *world, const Space* space) : Space (world, space)
156{
157        _space = dSimpleSpaceCreate(getSpaceID(space)); 
158        registerSpace();
159}
160//------------------------------------------------------------------------------------------------
161SimpleSpace::~SimpleSpace()
162{
163}
164//------------------------------------------------------------------------------------------------
165HashTableSpace::HashTableSpace(World *world, const Space* space) : Space (world, space)
166{
167        _space = dHashSpaceCreate(getSpaceID(space)); 
168        registerSpace();
169}
170//------------------------------------------------------------------------------------------------
171void HashTableSpace::setLevels(int min_level,int max_level)
172{
173        dHashSpaceSetLevels(_space,min_level,max_level); 
174}
175//------------------------------------------------------------------------------------------------
176int HashTableSpace::getMinimumLevel()
177{
178        int min_level,max_level;
179        dHashSpaceGetLevels(_space,&min_level,&max_level);
180        return min_level;
181}
182//------------------------------------------------------------------------------------------------
183int HashTableSpace::getMaximumLevel()
184{
185        int min_level,max_level;
186        dHashSpaceGetLevels(_space,&min_level,&max_level);
187        return max_level;
188}
189//------------------------------------------------------------------------------------------------
190HashTableSpace::~HashTableSpace()
191{
192}
193//------------------------------------------------------------------------------------------------
194#if ODE_VERSION_MINOR > 9
195SweepAndPruneSpace::SweepAndPruneSpace(AxisOrder axisOrder, World *world, const Space* space) : Space (world, space)
196{
197        _space = dSweepAndPruneSpaceCreate(getSpaceID(space), axisOrder);
198        registerSpace();
199}
200#endif
201//------------------------------------------------------------------------------------------------
202QuadTreeSpace::QuadTreeSpace(const Ogre::Vector3& center,const Ogre::Vector3& extents,int depth,World *world, const Space* space) : Space (world, space)
203{
204        dVector3 c,e;
205       
206        c[0] = (dReal)center.x;
207        c[1] = (dReal)center.y;
208        c[2] = (dReal)center.z;
209
210        e[0] = (dReal)extents.x;
211        e[1] = (dReal)extents.y;
212        e[2] = (dReal)extents.z;
213
214        _space = dQuadTreeSpaceCreate(getSpaceID(space),c,e,depth); 
215        registerSpace();
216}
217//------------------------------------------------------------------------------------------------
218QuadTreeSpace::~QuadTreeSpace()
219{
220}
221//------------------------------------------------------------------------------------------------
222OgreSceneManagerSpace::OgreSceneManagerSpace(const Ogre::Vector3& center,
223                                             const Ogre::Vector3& extents,
224                                             int depth,
225                                             Ogre::SceneManager *_scn_mgr,
226                                             World *world, const Space* space) : 
227        Space (world, space),
228        _scn_mgr(_scn_mgr)
229{
230    _intersection_query = _scn_mgr->createIntersectionQuery();
231
232    const std::set<Ogre::SceneQuery::WorldFragmentType> *supportedQueryTypes = _intersection_query->getSupportedWorldFragmentTypes();
233    std::set<Ogre::SceneQuery::WorldFragmentType>::const_iterator it = 
234        supportedQueryTypes->find (Ogre::SceneQuery::WFT_PLANE_BOUNDED_REGION);
235    if (it != supportedQueryTypes->end())
236    {
237        _intersection_query->setWorldFragmentType(Ogre::SceneQuery::WFT_PLANE_BOUNDED_REGION);
238        _scene_geometry = true;
239    }
240    else
241    {
242        _intersection_query->setWorldFragmentType(Ogre::SceneQuery::WFT_NONE);
243        _scene_geometry = false;
244    }
245
246    // for now register a dummy space in ode.
247    // perhaps this step can be avoided.dVector3 c,e;
248
249    dVector3 c;
250    c[0] = (dReal)center.x;
251    c[1] = (dReal)center.y;
252    c[2] = (dReal)center.z;
253
254    dVector3 e;
255    e[0] = (dReal)extents.x;
256    e[1] = (dReal)extents.y;
257    e[2] = (dReal)extents.z;
258
259    _space = dQuadTreeSpaceCreate(getSpaceID(space), c, e,depth); 
260    registerSpace();
261}
262//------------------------------------------------------------------------------------------------
263OgreSceneManagerSpace::~OgreSceneManagerSpace()
264{
265    delete _intersection_query;
266}
267//------------------------------------------------------------------------------------------------
268void OgreSceneManagerSpace::collide(void* data)
269{
270    if(_internal_collisions)
271    {
272        // Collision detection
273        Ogre::IntersectionSceneQueryResult& results = _intersection_query->execute();
274
275        Body *body1, *body2;
276        Geometry *geom;
277        Ogre::UserDefinedObject *uo1, *uo2;
278
279        // Movables to Movables
280        Ogre::SceneQueryMovableIntersectionList::iterator it, itend;
281        itend = results.movables2movables.end();
282        for (it = results.movables2movables.begin(); it != itend; ++it)
283        {
284            /* debugging
285            MovableObject *mo1, *mo2;
286            mo1 = it->first;
287            mo2 = it->second;
288            */
289
290            // Get user defined objects (generic in OGRE)
291            uo1 = it->first->getUserObject();
292            uo2 = it->second->getUserObject();
293
294            // Only perform collision if we have UserDefinedObject links
295            if (uo1 && uo2)
296            {
297                bool isBody1 = false;
298                if (uo1->getTypeName () == "Body")
299                    isBody1 = true;
300
301                bool isBody2 = false;
302                if (uo2->getTypeName () == "Body")
303                    isBody2 = true;
304                if (isBody1 || isBody2)
305                {
306                    if (isBody2 && isBody1)
307                    {
308                        // Both are dynamic object
309                       body1 = static_cast<Body*>(uo1);
310                       body2 = static_cast<Body*>(uo2);
311
312                        // Do detailed collision test
313                        body1->collide (data, body2);
314                    }
315                    else
316                    {
317                        // Both are dynamic object
318                        if (isBody1)
319                        {
320                            body1 = static_cast<Body*>     (uo1);
321                            geom  = static_cast<Geometry*> (uo2);
322                        }
323                        else
324                        {
325                            geom  = static_cast<Geometry*> (uo1);
326                            body1 = static_cast<Body*>     (uo2);
327                        }
328
329                        // Do detailed collision test
330                        body1->collide(data, geom);
331                    }
332                }
333            }
334        }
335
336        // Movables to World
337        if (_scene_geometry)
338        {
339            Ogre::MovableObject *mo;
340            Ogre::SceneQuery::WorldFragment *wf;
341
342            Ogre::SceneQueryMovableWorldFragmentIntersectionList::iterator wit, witend;
343            witend = results.movables2world.end();
344            for (wit = results.movables2world.begin(); wit != witend; ++wit)
345            {
346                mo = wit->first;
347                wf = wit->second;
348
349                // Get user defined objects (generic in OGRE)
350                uo1 = mo->getUserObject();
351                // Only perform collision if we have UserDefinedObject link
352                // otherwise ...
353                if (uo1)
354                {
355                    // Cast to ApplicationObject
356                    if (uo1->getTypeName () == "Body")
357                    {
358                        body1 = static_cast<Body*>(uo1);
359                        body1->collidePlaneBounds(data, wf);
360                    }
361//                     else // static objects don't collide against Scene Geometry
362//                     {
363//                         geom = static_cast<Geometry*>(uo);
364//                         // Do detailed collision test
365//                     }
366                }
367            }
368        }
369        // no need to use that one.
370        // dSpaceCollide(_space,data, World::collisionCallback);
371    }
372}
Note: See TracBrowser for help on using the repository browser.