Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/ogreode/OgreOdeCollision.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: 10.6 KB
Line 
1
2#include "OgreOdePrecompiledHeaders.h"
3
4#include "OgreOdeCollision.h"
5#include "OgreOdeSpace.h"
6#include "OgreOdeGeometry.h"
7
8using namespace OgreOde;
9using namespace Ogre;
10
11//------------------------------------------------------------------------------------------------
12CollisionListener::CollisionListener()
13{
14}
15//------------------------------------------------------------------------------------------------
16CollisionListener::~CollisionListener()
17{
18}
19
20//------------------------------------------------------------------------------------------------
21CollisionCallback::CollisionCallback()
22{
23}
24
25//------------------------------------------------------------------------------------------------
26CollisionCallback::~CollisionCallback()
27{
28}
29
30//-----------------------------------------------------------------------
31void CollisionCallback::collisionCallback(Space* spaceFirst, Space* spaceSecond)
32{
33        spaceFirst->collide(static_cast<CollisionCallback*>(this), spaceSecond);
34}
35       
36//-----------------------------------------------------------------------
37void CollisionCallback::collisionCallback(Space* space, Geometry* geometry)
38{
39        space->collide(static_cast<CollisionCallback*>(this), geometry);
40}
41       
42//-----------------------------------------------------------------------
43void CollisionCallback::collisionCallback(Space* space)
44{
45        space->collide(static_cast<CollisionCallback*>(this));
46}
47       
48//-----------------------------------------------------------------------
49void CollisionCallback::collisionCallback(Geometry* geometryFirst, Geometry* geometrySecond)
50{
51        geometryFirst->collide(geometrySecond, static_cast<CollisionListener*>(this));
52}
53
54//-----------------------------------------------------------------------
55void CollisionCallback::collisionCallback(void *data, dGeomID geom_a, dGeomID geom_b)
56{
57        CollisionCallback* colCallback = (CollisionCallback*) data;
58
59        const bool a_space = (dGeomIsSpace(geom_a))?true:false;
60        const bool b_space = (dGeomIsSpace(geom_b))?true:false;
61       
62        void* const ptr_a = dGeomGetData(geom_a);
63        void* const ptr_b = dGeomGetData(geom_b);
64
65        if(a_space  || b_space )
66        {
67                // Collide a space with a space
68                if(a_space && b_space) 
69                        colCallback->collisionCallback(static_cast<Space*>(ptr_a), static_cast<Space*>(ptr_b));
70                        //static_cast<Space*>(ptr_a)->collide(static_cast<Space*>(ptr_b), colCallback);
71                else if(a_space) 
72                        colCallback->collisionCallback(static_cast<Space*>(ptr_a), static_cast<Geometry*>(ptr_b));
73                        //static_cast<Space*>(ptr_a)->collide(static_cast<Geometry*>(ptr_b), colCallback);
74                else 
75                        colCallback->collisionCallback(static_cast<Space*>(ptr_b), static_cast<Geometry*>(ptr_a));
76                        //static_cast<Space*>(ptr_b)->collide(static_cast<Geometry*>(ptr_a), colCallback);
77
78                // Collide geometries internal to the spaces
79                if(a_space) 
80            static_cast<Space*>(ptr_a)->collide(colCallback);
81
82                if(b_space) 
83            static_cast<Space*>(ptr_b)->collide(colCallback);
84        }
85    else
86        {
87                // Collide a geom with a geom, i.e. generate contacts
88                colCallback->collisionCallback(static_cast<Geometry*>(ptr_a), static_cast<Geometry*>(ptr_b));
89                //static_cast<Geometry*>(ptr_a)->collide(static_cast<Geometry*>(ptr_b), static_cast<CollisionListener*>(colCallback));
90        }
91}
92
93
94//------------------------------------------------------------------------------------------------
95Contact::Contact()
96{
97}
98//------------------------------------------------------------------------------------------------
99Contact::~Contact()
100{
101}
102//------------------------------------------------------------------------------------------------
103const Ogre::Vector3& Contact::getPosition()
104{
105        _position.x = (Real)(_contact->geom.pos[0]);
106        _position.y = (Real)(_contact->geom.pos[1]);
107        _position.z = (Real)(_contact->geom.pos[2]);
108        return _position;
109}
110//------------------------------------------------------------------------------------------------
111const Ogre::Vector3& Contact::getNormal()
112{
113        _normal.x = (Real)(_contact->geom.normal[0]);
114        _normal.y = (Real)(_contact->geom.normal[1]);
115        _normal.z = (Real)(_contact->geom.normal[2]);
116        return _normal;
117}
118//------------------------------------------------------------------------------------------------
119Real Contact::getPenetrationDepth()
120{
121        return (Real)(_contact->geom.depth);
122}
123//------------------------------------------------------------------------------------------------
124Geometry* Contact::getFirstGeometry()
125{
126        dGeomID g = _contact->geom.g1;
127        if(!g) return 0;
128
129        return (Geometry*)dGeomGetData(g);
130}
131//------------------------------------------------------------------------------------------------
132Geometry* Contact::getSecondGeometry()
133{
134        dGeomID g = _contact->geom.g2;
135        if(!g) return 0;
136
137        return (Geometry*)dGeomGetData(g);
138}
139//------------------------------------------------------------------------------------------------
140int Contact::getFirstSide()
141{
142   return _contact->geom.side1;
143}
144//------------------------------------------------------------------------------------------------
145int Contact::getSecondSide()
146{
147   return _contact->geom.side2;
148} 
149//------------------------------------------------------------------------------------------------
150void Contact::setFirstFrictionDirection(const Ogre::Vector3& vector)
151{
152        _contact->fdir1[0] = (dReal)vector.x;
153        _contact->fdir1[1] = (dReal)vector.y;
154        _contact->fdir1[2] = (dReal)vector.z;
155
156        _contact->surface.mode |= (int)Flag_UseFirstFrictionDirection;
157}
158//------------------------------------------------------------------------------------------------
159void Contact::setCoulombFriction(Real mu,Real additional_mu)
160{
161        _contact->surface.mu = mu;
162       
163        if(additional_mu >= 0.0)
164        {
165                _contact->surface.mu2 = additional_mu;
166                _contact->surface.mode |= (int)Flag_UseAdditionalFriction;
167        }
168}
169//------------------------------------------------------------------------------------------------
170void Contact::setBouncyness(Real bouncyness,Real velocity_threshold)
171{
172        _contact->surface.bounce = bouncyness;
173        if(velocity_threshold >= 0.0)
174        {
175                _contact->surface.bounce_vel = velocity_threshold;
176        }
177        _contact->surface.mode |= (int)Flag_SurfaceIsBouncy;
178}
179//------------------------------------------------------------------------------------------------
180void Contact::setSoftness(Real ERP,Real CFM)
181{
182        _contact->surface.soft_erp = ERP;
183        _contact->surface.soft_cfm = CFM;
184
185        _contact->surface.mode |= (int)Flag_UseERP;
186        _contact->surface.mode |= (int)Flag_UseCFM;
187}
188//------------------------------------------------------------------------------------------------
189void Contact::setIndependentMotion(Real velocity,Real additional_velocity)
190{
191        _contact->surface.motion1 = velocity;
192        _contact->surface.mode |= (int)Flag_IndependentMotion; 
193
194        if(additional_velocity >= 0.0)
195        {
196                _contact->surface.motion2 = additional_velocity;
197                _contact->surface.mode |= (int)Flag_AdditionalIndependentMotion;
198        }
199}
200//------------------------------------------------------------------------------------------------
201void Contact::setForceDependentSlip(Real FDS)
202{
203        _contact->surface.slip1 = FDS;
204        _contact->surface.mode |= (int)Flag_UseFDS;
205}
206//------------------------------------------------------------------------------------------------
207void Contact::setAdditionalFDS(Real FDS)
208{
209        _contact->surface.slip2 = FDS;
210        _contact->surface.mode |= (int)Flag_UseAdditionalFDS;
211}
212//------------------------------------------------------------------------------------------------
213void Contact::setFrictionMode(Contact::Flag flag)
214{
215        assert((flag == Flag_FrictionPyramid)||(flag == Flag_BothFrictionPyramids)||(flag == Flag_AdditionalFrictionPyramid));
216        _contact->surface.mode |= (int)flag;                   
217}
218//------------------------------------------------------------------------------------------------
219ContactMapCollisionListener::ContactMapCollisionListener()
220{
221}
222//------------------------------------------------------------------------------------------------
223bool ContactMapCollisionListener::collision(Contact* contact)
224{
225        return false;
226        /*
227        size_t mt1 = contact->getFirstGeometry()->getMaterialType();
228        if(!mt1) return false;
229       
230        size_t mt2 = contact->getSecondGeometry()->getMaterialType();
231        if(!mt2) return false;
232
233        Contact *c = getContactPtr(mt1,mt2);
234        if(!c) return false;
235
236        contact->_contact->fdir1[0] = c->_contact->fdir1[0];
237        contact->_contact->fdir1[1] = c->_contact->fdir1[1];
238        contact->_contact->fdir1[2] = c->_contact->fdir1[2];
239
240        contact->_contact->surface.mu = c->_contact->surface.mu;
241        contact->_contact->surface.mu2 = c->_contact->surface.mu2;
242
243        contact->_contact->surface.bounce = c->_contact->surface.bounce;
244        contact->_contact->surface.bounce_vel = c->_contact->surface.bounce_vel;
245
246        contact->_contact->surface.soft_erp = c->_contact->surface.soft_erp;
247        contact->_contact->surface.soft_cfm = c->_contact->surface.soft_cfm;
248
249        contact->_contact->surface.motion1 = c->_contact->surface.motion1;
250        contact->_contact->surface.motion2 = c->_contact->surface.motion2;
251
252        contact->_contact->surface.slip1 = c->_contact->surface.slip1;
253        contact->_contact->surface.slip2 = c->_contact->surface.slip2;
254
255        contact->_contact->surface.mode = c->_contact->surface.mode;
256
257        return true;
258        */
259}
260//------------------------------------------------------------------------------------------------
261void ContactMapCollisionListener::createContact(MaterialID materialA,MaterialID materialB)
262{
263        std::map<MaterialID,MaterialMap* >::iterator i = _map.find(materialA);
264        if(i == _map.end())
265        {
266                _map.insert(MaterialMapPair(materialA,new MaterialMap()));
267                i = _map.find(materialA);
268        }
269
270        MaterialMap::iterator j = i->second->find(materialB);
271        if(j == i->second->end())
272        {
273                Contact *c = new Contact();
274                memset(c->_contact,0,sizeof(dContact));
275
276                i->second->insert(std::pair<MaterialID,Contact*>(materialB,c));
277        }
278}
279//------------------------------------------------------------------------------------------------
280Contact *ContactMapCollisionListener::getContactPtr(MaterialID materialA,MaterialID materialB)
281{
282        Contact *c = 0;
283        MaterialID A = materialA;
284        MaterialID B = materialB;
285
286        std::map<MaterialID,MaterialMap* >::iterator i = _map.find(A);
287        if(i == _map.end())
288        {
289                B = materialA;
290                A = materialB;
291
292                i = _map.find(A);
293        }
294
295        if(i != _map.end())
296        {
297                MaterialMap::iterator j = i->second->find(B);
298                if(j != i->second->end())
299                {
300                        c = j->second;
301                }
302        }
303
304        return c;
305}
306//------------------------------------------------------------------------------------------------
307ContactMapCollisionListener::~ContactMapCollisionListener()
308{
309        std::map<MaterialID,MaterialMap* >::iterator i = _map.begin();
310        std::map<MaterialID,MaterialMap* >::iterator i_end = _map.end();
311
312        for(;i != i_end;++i)
313        {
314                MaterialMap::iterator j = i->second->begin();
315                MaterialMap::iterator j_end = i->second->end();
316
317                for(;j != j_end;++j) 
318                        delete j->second;
319
320                delete i->second;
321        }
322}
323//------------------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.