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 }
An optional parameter associated with an event.
A class used to hold information about a collision that has occurred.
dGeomID get_id() const
Returns the underlying dGeomID.
Definition: odeGeom.I:28
dSpaceID get_id() const
Returns the underlying dSpaceID.
Definition: odeSpace.I:28
dWorldID get_id() const
Returns the underlying dWorldID.
Definition: odeWorld.I:28
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.