15 #include "config_ode.h"
18 #include "odeCollisionEntry.h"
19 #include "odeSimpleSpace.h"
20 #include "odeQuadTreeSpace.h"
21 #include "odeHashSpace.h"
23 #include "throw_event.h"
27 const int OdeSpace::MAX_CONTACTS = 16;
28 OdeWorld* OdeSpace::_static_auto_collide_world;
29 OdeSpace* OdeSpace::_static_auto_collide_space;
30 dJointGroupID OdeSpace::_static_auto_collide_joint_group;
33 OdeSpace(dSpaceID
id) :
35 _auto_collide_world = NULL;
36 _auto_collide_joint_group = NULL;
50 query(
const OdeGeom& geom)
const {
52 return dSpaceQuery(_id, geom.
get_id());
58 return dSpaceQuery(_id, (dGeomID)space.
get_id());
64 dSpaceAdd(_id, (dGeomID)space.
get_id());
70 dSpaceRemove(_id, (dGeomID)space.
get_id());
76 dSpaceAdd(_id, geom.
get_id());
82 dSpaceRemove(_id, geom.
get_id());
94 return OdeGeom(dSpaceGetGeom(_id, i));
99 write(ostream &out,
unsigned int indent)
const {
100 out.width(indent); out <<
"" << get_type() <<
"(id = " << _id <<
")";
104 operator bool ()
const {
105 return (_id != NULL);
109 set_auto_collide_world(
OdeWorld &world) {
110 _auto_collide_world = &world;
115 _auto_collide_joint_group = joint_group.get_id();
120 if (_auto_collide_world == NULL) {
121 odespace_cat.error() <<
"No collide world has been set!\n";
123 nassertv(_id != NULL);
124 _static_auto_collide_space =
this;
125 _static_auto_collide_world = _auto_collide_world;
126 _static_auto_collide_joint_group = _auto_collide_joint_group;
127 dSpaceCollide(_id,
this, &auto_callback);
132 auto_callback(
void *data, dGeomID o1, dGeomID o2) {
135 dBodyID b1 = dGeomGetBody(o1);
136 dBodyID b2 = dGeomGetBody(o2);
138 dContact contact[OdeSpace::MAX_CONTACTS];
140 int surface1 = _static_auto_collide_space->get_surface_type(o1);
141 int surface2 = _static_auto_collide_space->get_surface_type(o2);
143 nassertv(_static_auto_collide_world != NULL);
145 collide_params = _static_auto_collide_world->get_surface(surface1, surface2);
147 for (i=0; i < OdeSpace::MAX_CONTACTS; i++) {
148 contact[i].surface.mode = collide_params.colparams.mode;
149 contact[i].surface.mu = collide_params.colparams.mu;
150 contact[i].surface.mu2 = collide_params.colparams.mu2;
151 contact[i].surface.bounce = collide_params.colparams.bounce;
152 contact[i].surface.bounce_vel = collide_params.colparams.bounce_vel;
153 contact[i].surface.soft_cfm = collide_params.colparams.soft_cfm;
157 numc = dCollide(o1, o2, OdeSpace::MAX_CONTACTS, &contact[0].geom,
sizeof(dContact));
160 odespace_cat.debug() <<
"collision between geoms " << o1 <<
" and " << o2 <<
"\n";
161 odespace_cat.debug() <<
"collision between body " << b1 <<
" and " << b2 <<
"\n";
162 odespace_cat.debug() <<
"surface1= "<< surface1 <<
" surface2=" << surface2 <<
"\n";
165 if (!_static_auto_collide_space->_collision_event.empty()) {
171 entry->_num_contacts = numc;
175 for(i=0; i < numc; i++) {
176 dJointID c = dJointCreateContact(_static_auto_collide_world->
get_id(), _static_auto_collide_joint_group, contact + i);
177 if ((_static_auto_collide_space->get_collide_id(o1) >= 0) && (_static_auto_collide_space->get_collide_id(o2) >= 0)) {
178 dJointAttach(c, b1, b2);
180 if (!_static_auto_collide_space->_collision_event.empty()) {
181 entry->_contact_geoms[i] = contact[i].geom;
184 _static_auto_collide_world->set_dampen_on_bodies(b1, b2, collide_params.dampen);
186 if (!_static_auto_collide_space->_collision_event.empty()) {
187 throw_event(_static_auto_collide_space->_collision_event,
EventParameter(entry));
193 convert_to_simple_space()
const {
195 nassertr(get_class() == OdeGeom::GC_simple_space,
OdeSimpleSpace((dSpaceID)0));
200 convert_to_hash_space()
const {
202 nassertr(get_class() == OdeGeom::GC_hash_space,
OdeHashSpace((dSpaceID)0));
207 convert_to_quad_tree_space()
const {
209 nassertr(get_class() == OdeGeom::GC_quad_tree_space,
OdeQuadTreeSpace((dSpaceID)0));
215 set_surface_type(
int surfaceType, dGeomID
id){
216 _geom_surface_map[id]= surfaceType;
220 set_surface_type(
OdeGeom& geom,
int surfaceType){
221 dGeomID
id = geom.
get_id();
222 set_surface_type(surfaceType,
id);
226 get_surface_type(dGeomID
id) {
227 GeomSurfaceMap::iterator iter = _geom_surface_map.find(
id);
228 if (iter != _geom_surface_map.end()) {
235 get_surface_type(
OdeGeom& geom) {
236 dGeomID
id = geom.
get_id();
237 return get_surface_type(
id);
242 set_collide_id(
int collide_id, dGeomID
id) {
243 _geom_collide_id_map[id]= collide_id;
244 return _geom_collide_id_map[id];
248 set_collide_id(
OdeGeom& geom,
int collide_id) {
249 dGeomID
id = geom.
get_id();
250 return set_collide_id(collide_id,
id);
254 get_collide_id(
OdeGeom& geom) {
255 dGeomID
id = geom.
get_id();
256 return get_collide_id(
id);
261 get_collide_id(dGeomID
id) {
262 GeomCollideIdMap::iterator iter = _geom_collide_id_map.find(
id);
263 if (iter != _geom_collide_id_map.end()) {
An optional parameter associated with an event.
A class used to hold information about a collision that has occurred.
dSpaceID get_id() const
Returns the underlying dSpaceID.
dWorldID get_id() const
Returns the underlying dWorldID.
TypeHandle is the identifier used to differentiate C++ class types.
dGeomID get_id() const
Returns the underlying dGeomID.