Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Merged physics branch into physics_new branch.

  • Property svn:eol-style set to native
File size: 13.2 KB
Line 
1#include "OgreOdePrecompiledHeaders.h"
2#include "OgreOdeSpace.h"
3
4#include <OgreSceneManager.h>
5
6#include "OgreOdeBody.h"
7#include "OgreOdeGeometry.h"
8#include "OgreOdeWorld.h"
9#include "OgreOdeCollision.h"
10
11using namespace OgreOde;
12using namespace Ogre;
13
14//------------------------------------------------------------------------------------------------
15Space::Space(World *world, const Space* space) :
16    _internal_collisions (true),
17    _world(world)
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.