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  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";
163 
164  PT(OdeCollisionEntry) entry;
165  if (!_static_auto_collide_space->_collision_event.empty()) {
166  entry = new OdeCollisionEntry;
167  entry->_geom1 = o1;
168  entry->_geom2 = o2;
169  entry->_body1 = b1;
170  entry->_body2 = b2;
171  entry->_num_contacts = numc;
172  entry->_contact_geoms = new OdeContactGeom[numc];
173  }
174 
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);
179  }
180  if (!_static_auto_collide_space->_collision_event.empty()) {
181  entry->_contact_geoms[i] = contact[i].geom;
182  }
183  }
184  _static_auto_collide_world->set_dampen_on_bodies(b1, b2, collide_params.dampen);
185 
186  if (!_static_auto_collide_space->_collision_event.empty()) {
187  throw_event(_static_auto_collide_space->_collision_event, EventParameter(entry));
188  }
189  }
190 }
191 
192 OdeSimpleSpace OdeSpace::
193 convert_to_simple_space() const {
194  nassertr(_id != nullptr, OdeSimpleSpace(nullptr));
195  nassertr(get_class() == OdeGeom::GC_simple_space, OdeSimpleSpace(nullptr));
196  return OdeSimpleSpace(_id);
197 }
198 
199 OdeHashSpace OdeSpace::
200 convert_to_hash_space() const {
201  nassertr(_id != nullptr, OdeHashSpace(nullptr));
202  nassertr(get_class() == OdeGeom::GC_hash_space, OdeHashSpace(nullptr));
203  return OdeHashSpace(_id);
204 }
205 
206 OdeQuadTreeSpace OdeSpace::
207 convert_to_quad_tree_space() const {
208  nassertr(_id != nullptr, OdeQuadTreeSpace(nullptr));
209  nassertr(get_class() == OdeGeom::GC_quad_tree_space, OdeQuadTreeSpace(nullptr));
210  return OdeQuadTreeSpace(_id);
211 }
212 
213 
214 void OdeSpace::
215 set_surface_type( int surfaceType, dGeomID id){
216  _geom_surface_map[id]= surfaceType;
217 }
218 
219 void OdeSpace::
220 set_surface_type(OdeGeom& geom, int surfaceType){
221  dGeomID id = geom.get_id();
222  set_surface_type(surfaceType, id);
223 }
224 
225 int OdeSpace::
226 get_surface_type(dGeomID id) {
227  GeomSurfaceMap::iterator iter = _geom_surface_map.find(id);
228  if (iter != _geom_surface_map.end()) {
229  return iter->second;
230  }
231  return 0;
232 }
233 
234 int OdeSpace::
235 get_surface_type(OdeGeom& geom) {
236  dGeomID id = geom.get_id();
237  return get_surface_type(id);
238 }
239 
240 
241 int OdeSpace::
242 set_collide_id( int collide_id, dGeomID id) {
243  _geom_collide_id_map[id]= collide_id;
244  return _geom_collide_id_map[id];
245 }
246 
247 int OdeSpace::
248 set_collide_id( OdeGeom& geom, int collide_id) {
249  dGeomID id = geom.get_id();
250  return set_collide_id(collide_id, id);
251 }
252 
253 int OdeSpace::
254 get_collide_id(OdeGeom& geom) {
255  dGeomID id = geom.get_id();
256  return get_collide_id(id);
257 }
258 
259 
260 int OdeSpace::
261 get_collide_id(dGeomID id) {
262  GeomCollideIdMap::iterator iter = _geom_collide_id_map.find(id);
263  if (iter != _geom_collide_id_map.end()) {
264  return iter->second;
265  }
266  return 0;
267 }
dSpaceID get_id() const
Returns the underlying dSpaceID.
Definition: odeSpace.I:28
An optional parameter associated with an event.
dWorldID get_id() const
Returns the underlying dWorldID.
Definition: odeWorld.I:28
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dGeomID get_id() const
Returns the underlying dGeomID.
Definition: odeGeom.I:28
A class used to hold information about a collision that has occurred.
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.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.