Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Cleaned up the heavy mess with header file includes in OgreOde. It should now compile a lot faster.

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