Panda3D
odeSpace.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file odeSpace.cxx
10  * @author joswilso
11  * @date 2006-12-27
12  */
13 
14 #include "config_ode.h"
15 #include "odeSpace.h"
16 #include "odeGeom.h"
17 #include "odeCollisionEntry.h"
18 #include "odeSimpleSpace.h"
19 #include "odeQuadTreeSpace.h"
20 #include "odeHashSpace.h"
21 
22 #include "throw_event.h"
23 
24 TypeHandle OdeSpace::_type_handle;
25 // this data is used in auto_collide
26 const int OdeSpace::MAX_CONTACTS = 16;
27 OdeWorld* OdeSpace::_static_auto_collide_world;
28 OdeSpace* OdeSpace::_static_auto_collide_space;
29 dJointGroupID OdeSpace::_static_auto_collide_joint_group;
30 
31 OdeSpace::
32 OdeSpace(dSpaceID id) :
33  _id(id) {
34  _auto_collide_world = nullptr;
35  _auto_collide_joint_group = nullptr;
36 }
37 
38 OdeSpace::
39 ~OdeSpace() {
40 }
41 
42 void OdeSpace::
43 destroy() {
44  nassertv(_id);
45  dSpaceDestroy(_id);
46 }
47 
48 int OdeSpace::
49 query(const OdeGeom& geom) const {
50  nassertr(_id, 0);
51  return dSpaceQuery(_id, geom.get_id());
52 }
53 
54 int OdeSpace::
55 query(const OdeSpace& space) const {
56  nassertr(_id, 0);
57  return dSpaceQuery(_id, (dGeomID)space.get_id());
58 }
59 
60 void OdeSpace::
61 add(OdeSpace& space) {
62  nassertv(_id);
63  dSpaceAdd(_id, (dGeomID)space.get_id());
64 }
65 
66 void OdeSpace::
67 remove(OdeSpace& space) {
68  nassertv(_id);
69  dSpaceRemove(_id, (dGeomID)space.get_id());
70 }
71 
72 void OdeSpace::
73 add(OdeGeom& geom) {
74  nassertv(_id);
75  dSpaceAdd(_id, geom.get_id());
76 }
77 
78 void OdeSpace::
79 remove(OdeGeom& geom) {
80  nassertv(_id);
81  dSpaceRemove(_id, geom.get_id());
82 }
83 
84 void OdeSpace::
85 clean() {
86  nassertv(_id);
87  dSpaceClean(_id);
88 }
89 
90 OdeGeom OdeSpace::
91 get_geom(int i) {
92  nassertr(_id, OdeGeom(nullptr));
93  return OdeGeom(dSpaceGetGeom(_id, i));
94 }
95 
96 
97 void OdeSpace::
98 write(std::ostream &out, unsigned int indent) const {
99  out.width(indent); out << "" << get_type() << "(id = " << _id << ")";
100 }
101 
102 OdeSpace::
103 operator bool () const {
104  return (_id != nullptr);
105 }
106 
107 void OdeSpace::
108 set_auto_collide_world(OdeWorld &world) {
109  _auto_collide_world = &world;
110 }
111 
112 void OdeSpace::
113 set_auto_collide_joint_group(OdeJointGroup &joint_group) {
114  _auto_collide_joint_group = joint_group.get_id();
115 }
116 
117 void OdeSpace::
118 auto_collide() {
119  if (_auto_collide_world == nullptr) {
120  odespace_cat.error() << "No collide world has been set!\n";
121  } else {
122  nassertv(_id != nullptr);
123  _static_auto_collide_space = this;
124  _static_auto_collide_world = _auto_collide_world;
125  _static_auto_collide_joint_group = _auto_collide_joint_group;
126  dSpaceCollide(_id, this, &auto_callback);
127  }
128 }
129 
130 void OdeSpace::
131 auto_callback(void *data, dGeomID o1, dGeomID o2) {
132 // uses data stored on the world to resolve collisions so you don't have to
133 // use near_callbacks in python
134  int i;
135  dBodyID b1 = dGeomGetBody(o1);
136  dBodyID b2 = dGeomGetBody(o2);
137 
138  dContact contact[OdeSpace::MAX_CONTACTS];
139 
140  int surface1 = _static_auto_collide_space->get_surface_type(o1);
141  int surface2 = _static_auto_collide_space->get_surface_type(o2);
142 
143  nassertv(_static_auto_collide_world != nullptr);
144  sSurfaceParams collide_params;
145  collide_params = _static_auto_collide_world->get_surface(surface1, surface2);
146 
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;
154  }
155 
156  static int numc = 0;
157  numc = dCollide(o1, o2, OdeSpace::MAX_CONTACTS, &contact[0].geom, sizeof(dContact));
158 
159  if (numc) {
160  if (odespace_cat.is_debug()) {
161  odespace_cat.debug() << "collision between geoms " << o1 << " and " << o2 << "\n";
162  odespace_cat.debug() << "collision between body " << b1 << " and " << b2 << "\n";
163  odespace_cat.debug() << "surface1= "<< surface1 << " surface2=" << surface2 << "\n";
164  }
165 
166  PT(OdeCollisionEntry) entry;
167  if (!_static_auto_collide_space->_collision_event.empty()) {
168  entry = new OdeCollisionEntry;
169  entry->_geom1 = o1;
170  entry->_geom2 = o2;
171  entry->_body1 = b1;
172  entry->_body2 = b2;
173  entry->_num_contacts = numc;
174  entry->_contact_geoms = new OdeContactGeom[numc];
175  }
176 
177  for(i=0; i < numc; i++) {
178  dJointID c = dJointCreateContact(_static_auto_collide_world->get_id(), _static_auto_collide_joint_group, contact + i);
179  if ((_static_auto_collide_space->get_collide_id(o1) >= 0) && (_static_auto_collide_space->get_collide_id(o2) >= 0)) {
180  dJointAttach(c, b1, b2);
181  }
182  if (!_static_auto_collide_space->_collision_event.empty()) {
183  entry->_contact_geoms[i] = contact[i].geom;
184  }
185  }
186  _static_auto_collide_world->set_dampen_on_bodies(b1, b2, collide_params.dampen);
187 
188  if (!_static_auto_collide_space->_collision_event.empty()) {
189  throw_event(_static_auto_collide_space->_collision_event, EventParameter(entry));
190  }
191  }
192 }
193 
194 OdeSimpleSpace OdeSpace::
195 convert_to_simple_space() const {
196  nassertr(_id != nullptr, OdeSimpleSpace(nullptr));
197  nassertr(get_class() == OdeGeom::GC_simple_space, OdeSimpleSpace(nullptr));
198  return OdeSimpleSpace(_id);
199 }
200 
201 OdeHashSpace OdeSpace::
202 convert_to_hash_space() const {
203  nassertr(_id != nullptr, OdeHashSpace(nullptr));
204  nassertr(get_class() == OdeGeom::GC_hash_space, OdeHashSpace(nullptr));
205  return OdeHashSpace(_id);
206 }
207 
208 OdeQuadTreeSpace OdeSpace::
209 convert_to_quad_tree_space() const {
210  nassertr(_id != nullptr, OdeQuadTreeSpace(nullptr));
211  nassertr(get_class() == OdeGeom::GC_quad_tree_space, OdeQuadTreeSpace(nullptr));
212  return OdeQuadTreeSpace(_id);
213 }
214 
215 
216 void OdeSpace::
217 set_surface_type( int surfaceType, dGeomID id){
218  _geom_surface_map[id]= surfaceType;
219 }
220 
221 void OdeSpace::
222 set_surface_type(OdeGeom& geom, int surfaceType){
223  dGeomID id = geom.get_id();
224  set_surface_type(surfaceType, id);
225 }
226 
227 int OdeSpace::
228 get_surface_type(dGeomID id) {
229  GeomSurfaceMap::iterator iter = _geom_surface_map.find(id);
230  if (iter != _geom_surface_map.end()) {
231  return iter->second;
232  }
233  return 0;
234 }
235 
236 int OdeSpace::
237 get_surface_type(OdeGeom& geom) {
238  dGeomID id = geom.get_id();
239  return get_surface_type(id);
240 }
241 
242 
243 int OdeSpace::
244 set_collide_id( int collide_id, dGeomID id) {
245  _geom_collide_id_map[id]= collide_id;
246  return _geom_collide_id_map[id];
247 }
248 
249 int OdeSpace::
250 set_collide_id( OdeGeom& geom, int collide_id) {
251  dGeomID id = geom.get_id();
252  return set_collide_id(collide_id, id);
253 }
254 
255 int OdeSpace::
256 get_collide_id(OdeGeom& geom) {
257  dGeomID id = geom.get_id();
258  return get_collide_id(id);
259 }
260 
261 
262 int OdeSpace::
263 get_collide_id(dGeomID id) {
264  GeomCollideIdMap::iterator iter = _geom_collide_id_map.find(id);
265  if (iter != _geom_collide_id_map.end()) {
266  return iter->second;
267  }
268  return 0;
269 }
OdeGeom::get_id
dGeomID get_id() const
Returns the underlying dGeomID.
Definition: odeGeom.I:28
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
OdeWorld::get_id
dWorldID get_id() const
Returns the underlying dWorldID.
Definition: odeWorld.I:28
throw_event.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
odeHashSpace.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
OdeJointGroup
Definition: odeJointGroup.h:26
odeGeom.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
odeSpace.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
OdeSpace
Definition: odeSpace.h:37
OdeHashSpace
Definition: odeHashSpace.h:28
sSurfaceParams
Definition: odeHelperStructs.h:4
OdeSimpleSpace
Definition: odeSimpleSpace.h:27
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
OdeQuadTreeSpace
Definition: odeQuadTreeSpace.h:27
OdeContactGeom
Definition: odeContactGeom.h:30
odeSimpleSpace.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
OdeSpace::get_id
dSpaceID get_id() const
Returns the underlying dSpaceID.
Definition: odeSpace.I:28
OdeCollisionEntry
A class used to hold information about a collision that has occurred.
Definition: odeCollisionEntry.h:27
odeQuadTreeSpace.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_ode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
EventParameter
An optional parameter associated with an event.
Definition: eventParameter.h:35
odeCollisionEntry.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
OdeWorld
Definition: odeWorld.h:33
OdeGeom
Definition: odeGeom.h:45