Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics_new/src/ogreode/OgreOdeCollision.cpp @ 2119

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

Merged physics branch into physics_new branch.

  • 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.