Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/ogreode/OgreOdeCollision.cpp @ 1922

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

Minor adjustments to OgreODE when compiling under gcc.

  • 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//------------------------------------------------------------------------------------------------
324
Note: See TracBrowser for help on using the repository browser.