Panda3D
 All Classes Functions Variables Enumerations
odeWorld.cxx
1 // Filename: odeWorld.cxx
2 // Created by: joswilso (27Dec06)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "config_ode.h"
16 #include "odeWorld.h"
17 #include "odeBody.h"
18 
19 TypeHandle OdeWorld::_type_handle;
20 
21 OdeWorld::
22 OdeWorld() :
23  _id(dWorldCreate()) {
24  odeworld_cat.debug() << get_type() << "(" << _id << ")" << "\n";
25  _num_surfaces = 0;
26 
27 }
28 
29 OdeWorld::
30 OdeWorld(const OdeWorld &copy) :
31  _id(copy._id) {
32  _num_surfaces = 0;
33 
34 }
35 
36 OdeWorld::
37 ~OdeWorld() {
38  odeworld_cat.debug() << "~" << get_type() << "(" << _id << ")" << "\n";
39 }
40 
41 void OdeWorld::
42 destroy() {
43  if(_num_surfaces > 0) {
44  delete _surface_table;
45  }
46  nassertv(_id);
47  dWorldDestroy(_id);
48 }
49 
50 /*
51 void OdeWorld::
52 assign_surface_body(OdeBody& body, int surface) {
53  // odeworld_cat.debug() << "assign_surface_body body.Id =" << body.get_id() << " surface=" << surface << "\n";
54  _body_dampen_map[body.get_id()].surfaceType = surface;
55  _body_dampen_map[body.get_id()].dampen = 0.0f;
56 }
57 */
58 
59 void OdeWorld::
60 add_body_dampening(OdeBody& body, int surface) {
61  _body_dampen_map[body.get_id()].dampen = 0.0f;
62 }
63 
64 
65 void OdeWorld::
66 init_surface_table(PN_uint8 num_surfaces) {
67  _surface_table = new sSurfaceParams[num_surfaces * num_surfaces];
68  //_dampen_table = new sSurfaceParams[num_surfaces * num_surfaces];
69  _num_surfaces = num_surfaces;
70 }
71 
72 void OdeWorld::
73 set_surface(int pos1, int pos2, sSurfaceParams& entry) {
74  odeworld_cat.debug() << " pos1 " << pos1 << " pos2 " << pos2 << " num surfaces " << (int)_num_surfaces << " endline\n";
75  if((_num_surfaces <= pos1) || (_num_surfaces <= pos2)) {
76  odeworld_cat.error() << "surface position exceeds size of surface table, set num_surface in initSurfaceTable higher." << "\n";
77  return;
78  }
79  int true_pos = (pos1 * _num_surfaces) + pos2;
80  _surface_table[true_pos].colparams.mode = entry.colparams.mode;
81  _surface_table[true_pos].colparams.mu = entry.colparams.mu;
82  _surface_table[true_pos].colparams.mu2 = entry.colparams.mu2;
83  _surface_table[true_pos].colparams.bounce = entry.colparams.bounce;
84  _surface_table[true_pos].colparams.bounce_vel = entry.colparams.bounce_vel;
85  _surface_table[true_pos].colparams.soft_cfm = entry.colparams.soft_cfm;
86  _surface_table[true_pos].colparams.motion1 = entry.colparams.motion1;
87  _surface_table[true_pos].colparams.motion2 = entry.colparams.motion2;
88  _surface_table[true_pos].colparams.slip1 = entry.colparams.slip1;
89  _surface_table[true_pos].colparams.slip2 = entry.colparams.slip2;
90  _surface_table[true_pos].dampen = entry.dampen;
91 }
92 
93 
94 sSurfaceParams& OdeWorld::
95 get_surface(PN_uint8 surface1, PN_uint8 surface2) {
96  int true_pos = 0;
97  if(surface1 >= surface2) {
98  true_pos = (surface1 * _num_surfaces) + surface2;
99  } else {
100  true_pos = (surface2 * _num_surfaces) + surface1;
101  }
102  if((_num_surfaces <= surface1) || (_num_surfaces <= surface2)) {
103  odeworld_cat.error() << "surface position exceeds size of surface table, set num_surface in initSurfaceTable higher." << "\n";
104  //nassertr_always((_num_surfaces > surface1 && _num_surfaces > surface2), _surface_table[true_pos]);
105  }
106  return _surface_table[true_pos];
107 }
108 
109 void OdeWorld::
110 set_surface_entry(PN_uint8 pos1, PN_uint8 pos2,
111  dReal mu,
112  dReal bounce,
113  dReal bounce_vel,
114  dReal soft_erp,
115  dReal soft_cfm,
116  dReal slip,
117  dReal dampen) {
118  //todo: add mode
119  sSurfaceParams new_params;
120  int someMode = 0;
121  if (bounce > 0.0001) {
122  someMode |= dContactBounce;
123  }
124  if (soft_erp > 0.0001) {
125  someMode |= dContactSoftERP;
126  }
127  if (soft_cfm > 0.0001) {
128  someMode |= dContactSoftCFM;
129  }
130  if (slip > 0.0001) {
131  someMode = someMode | dContactSlip1 | dContactSlip2;
132  }
133  new_params.colparams.mode = dContactBounce | dContactSoftCFM | dContactApprox1;// | dContactSoftERP;
134  new_params.colparams.mu = mu;
135  new_params.colparams.mu2 = mu;
136  new_params.colparams.bounce = bounce;
137  new_params.colparams.bounce_vel = bounce_vel;
138  new_params.colparams.soft_erp = soft_erp;
139  new_params.colparams.soft_cfm = soft_cfm;
140  new_params.colparams.slip1 = slip;
141  new_params.colparams.slip2 = slip;
142  new_params.colparams.motion1 = 0.0;
143  new_params.colparams.motion2 = 0.0;
144  new_params.dampen = dampen;
145  //todo: a bit of wasted space here
146  set_surface(pos1, pos2, new_params);
147 
148  if(pos1 >= pos2) {
149  set_surface(pos1, pos2, new_params);
150  } else {
151  set_surface(pos2, pos1, new_params);
152  }
153 }
154 
155 
156 
157 void OdeWorld::
158 set_dampen_on_bodies(dBodyID id1, dBodyID id2,dReal damp) {
159  if(_body_dampen_map[id1].dampen < damp) {
160  _body_dampen_map[id1].dampen = damp;
161  }
162  if(_body_dampen_map[id2].dampen < damp) {
163  _body_dampen_map[id2].dampen = damp;
164  }
165 }
166 
167 float OdeWorld::
168 apply_dampening(float dt, OdeBody& body) {
169  dBodyID bodyId = body.get_id();
170  dReal damp = _body_dampen_map[bodyId].dampen;
171  float dampening = 1.00 - (damp * dt);
172  body.set_angular_vel(body.get_angular_vel() * dampening);
173  body.set_linear_vel(body.get_linear_vel() * dampening);
174  _body_dampen_map[bodyId].dampen = 0.0;
175  return dampening;
176 }
177 
178 OdeWorld::
179 operator bool () const {
180  return (_id != NULL);
181 }
dBodyID get_id() const
Returns the underlying dBodyID.
Definition: odeBody.I:34
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85