Panda3D
bulletVehicle.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 bulletVehicle.cxx
10  * @author enn0x
11  * @date 2010-02-16
12  */
13 
14 #include "bulletVehicle.h"
15 
16 #include "config_bullet.h"
17 
18 #include "bulletWorld.h"
19 #include "bulletRigidBodyNode.h"
20 #include "bulletWheel.h"
21 
22 TypeHandle BulletVehicle::_type_handle;
23 
24 /**
25  * Creates a new BulletVehicle instance in the given world and with a chassis
26  * node.
27  */
30 
31  btRigidBody *body = btRigidBody::upcast(chassis->get_object());
32 
33  _raycaster = new btDefaultVehicleRaycaster(world->get_world());
34  _vehicle = new btRaycastVehicle(_tuning._, body, _raycaster);
35 
36  set_coordinate_system(get_default_up_axis());
37 }
38 
39 /**
40  * Specifies which axis is "up". Nessecary for the vehicle's suspension to
41  * work properly!
42  */
43 void BulletVehicle::
44 set_coordinate_system(BulletUpAxis up) {
45  LightMutexHolder holder(BulletWorld::get_global_lock());
46 
47  switch (up) {
48  case X_up:
49  _vehicle->setCoordinateSystem(1, 0, 2);
50  break;
51  case Y_up:
52  _vehicle->setCoordinateSystem(0, 1, 2);
53  break;
54  case Z_up:
55  _vehicle->setCoordinateSystem(0, 2, 1);
56  break;
57  default:
58  bullet_cat.error() << "invalid up axis:" << up << std::endl;
59  break;
60  }
61 }
62 
63 /**
64  * Returns the forward vector representing the car's actual direction of
65  * movement. The forward vetcor is given in global coordinates.
66  */
67 LVector3 BulletVehicle::
68 get_forward_vector() const {
69  LightMutexHolder holder(BulletWorld::get_global_lock());
70 
71  return btVector3_to_LVector3(_vehicle->getForwardVector());
72 }
73 
74 /**
75  * Returns the chassis of this vehicle. The chassis is a rigid body node.
76  * Assumes the lock(bullet global lock) is held by the caller
77  */
80 
81  btRigidBody *bodyPtr = _vehicle->getRigidBody();
82  return (bodyPtr) ? (BulletRigidBodyNode *)bodyPtr->getUserPointer() : nullptr;
83 }
84 
85 /**
86  * Returns the chassis of this vehicle. The chassis is a rigid body node.
87  */
88 BulletRigidBodyNode *BulletVehicle::
89 get_chassis() {
90  LightMutexHolder holder(BulletWorld::get_global_lock());
91 
92  return do_get_chassis();
93 }
94 
95 /**
96  * Returns the current speed in kilometers per hour. Convert to miles using:
97  * km/h * 0.62 = mph
98  */
99 PN_stdfloat BulletVehicle::
100 get_current_speed_km_hour() const {
101  LightMutexHolder holder(BulletWorld::get_global_lock());
102 
103  return (PN_stdfloat)_vehicle->getCurrentSpeedKmHour();
104 }
105 
106 /**
107  * Resets the vehicle's suspension.
108  */
109 void BulletVehicle::
111  LightMutexHolder holder(BulletWorld::get_global_lock());
112 
113  _vehicle->resetSuspension();
114 }
115 
116 /**
117  * Returns the steering angle of the wheel with index idx in degrees.
118  */
119 PN_stdfloat BulletVehicle::
120 get_steering_value(int idx) const {
121  LightMutexHolder holder(BulletWorld::get_global_lock());
122 
123  nassertr(idx < _vehicle->getNumWheels(), 0.0f);
124  return rad_2_deg(_vehicle->getSteeringValue(idx));
125 }
126 
127 /**
128  * Sets the steering value (in degrees) of the wheel with index idx.
129  */
130 void BulletVehicle::
131 set_steering_value(PN_stdfloat steering, int idx) {
132  LightMutexHolder holder(BulletWorld::get_global_lock());
133 
134  nassertv(idx < _vehicle->getNumWheels());
135  _vehicle->setSteeringValue(deg_2_rad(steering), idx);
136 }
137 
138 /**
139  * Applies force at the wheel with index idx for acceleration.
140  */
141 void BulletVehicle::
142 apply_engine_force(PN_stdfloat force, int idx) {
143  LightMutexHolder holder(BulletWorld::get_global_lock());
144 
145  nassertv(idx < _vehicle->getNumWheels());
146  _vehicle->applyEngineForce(force, idx);
147 }
148 
149 /**
150  * Applies braking force to the wheel with index idx.
151  */
152 void BulletVehicle::
153 set_brake(PN_stdfloat brake, int idx) {
154  LightMutexHolder holder(BulletWorld::get_global_lock());
155 
156  nassertv(idx < _vehicle->getNumWheels());
157  _vehicle->setBrake(brake, idx);
158 }
159 
160 /**
161  *
162  */
163 void BulletVehicle::
164 set_pitch_control(PN_stdfloat pitch) {
165  LightMutexHolder holder(BulletWorld::get_global_lock());
166 
167  _vehicle->setPitchControl(pitch);
168 }
169 
170 /**
171  * Factory method for creating wheels for this vehicle instance.
172  */
175  LightMutexHolder holder(BulletWorld::get_global_lock());
176 
177  btVector3 pos(0.0, 0.0, 0.0);
178  btVector3 direction = get_axis(_vehicle->getUpAxis());
179  btVector3 axle = get_axis(_vehicle->getRightAxis());
180 
181  btScalar suspension(0.4);
182  btScalar radius(0.3);
183 
184  btWheelInfo &info = _vehicle->addWheel(pos, direction, axle, suspension, radius, _tuning._, false);
185 
186  info.m_clientInfo = nullptr;
187 
188  return BulletWheel(info);
189 }
190 
191 /**
192  *
193  */
194 btVector3 BulletVehicle::
195 get_axis(int idx) {
196 
197  switch (idx) {
198  case 0:
199  return btVector3(1.0, 0.0, 0.0);
200  case 1:
201  return btVector3(0.0, 1.0, 0.0);
202  case 2:
203  return btVector3(0.0, 0.0, 1.0);
204  default:
205  return btVector3(0.0, 0.0, 0.0);
206  }
207 }
208 
209 /**
210  * Returns the number of wheels this vehicle has.
211  */
212 int BulletVehicle::
213 get_num_wheels() const {
214  LightMutexHolder holder(BulletWorld::get_global_lock());
215 
216  return _vehicle->getNumWheels();
217 }
218 
219 /**
220  * Returns the BulletWheel with index idx. Causes an AssertionError if idx is
221  * equal or larger than the number of wheels.
222  */
224 get_wheel(int idx) const {
225  LightMutexHolder holder(BulletWorld::get_global_lock());
226 
227  nassertr(idx < _vehicle->getNumWheels(), BulletWheel::empty());
228  return BulletWheel(_vehicle->getWheelInfo(idx));
229 }
230 
231 /**
232  * Assumes the lock(bullet global lock) is held by the caller
233  */
234 void BulletVehicle::
236 
237  for (int i=0; i < _vehicle->getNumWheels(); i++) {
238  btWheelInfo &info = _vehicle->getWheelInfo(i);
239 
240  // synchronize the wheels with the (interpolated) chassis worldtransform.
241  // It resets the m_isInContact flag, so restore that afterwards.
242  bool in_contact = info.m_raycastInfo.m_isInContact;
243  _vehicle->updateWheelTransform(i, true);
244  info.m_raycastInfo.m_isInContact = in_contact;
245 
246  PandaNode *node = (PandaNode *)info.m_clientInfo;
247  if (node) {
248 
249  CPT(TransformState) ts = btTrans_to_TransformState(info.m_worldTransform);
250 
251  // <A> Transform relative to wheel node's parent
252  // node->set_transform(ts);
253 
254  // <B> Transform absolute
255  NodePath np = NodePath::any_path(node);
256  np.set_transform(np.get_top(), ts);
257  }
258  }
259 }
260 
261 /**
262  *
263  */
264 void BulletVehicleTuning::
265 set_suspension_stiffness(PN_stdfloat value) {
266  LightMutexHolder holder(BulletWorld::get_global_lock());
267 
268  _.m_suspensionStiffness = (btScalar)value;
269 }
270 
271 /**
272  *
273  */
274 void BulletVehicleTuning::
275 set_suspension_compression(PN_stdfloat value) {
276  LightMutexHolder holder(BulletWorld::get_global_lock());
277 
278  _.m_suspensionCompression = (btScalar)value;
279 }
280 
281 /**
282  *
283  */
284 void BulletVehicleTuning::
285 set_suspension_damping(PN_stdfloat value) {
286  LightMutexHolder holder(BulletWorld::get_global_lock());
287 
288  _.m_suspensionDamping = (btScalar)value;
289 }
290 
291 /**
292  *
293  */
294 void BulletVehicleTuning::
295 set_max_suspension_travel_cm(PN_stdfloat value) {
296  LightMutexHolder holder(BulletWorld::get_global_lock());
297 
298  _.m_maxSuspensionTravelCm = (btScalar)value;
299 }
300 
301 /**
302  *
303  */
304 void BulletVehicleTuning::
305 set_friction_slip(PN_stdfloat value) {
306  LightMutexHolder holder(BulletWorld::get_global_lock());
307 
308  _.m_frictionSlip = (btScalar)value;
309 }
310 
311 /**
312  *
313  */
314 void BulletVehicleTuning::
315 set_max_suspension_force(PN_stdfloat value) {
316  LightMutexHolder holder(BulletWorld::get_global_lock());
317 
318  _.m_maxSuspensionForce = (btScalar)value;
319 }
320 
321 /**
322  *
323  */
324 PN_stdfloat BulletVehicleTuning::
325 get_suspension_stiffness() const {
326  LightMutexHolder holder(BulletWorld::get_global_lock());
327 
328  return (PN_stdfloat)_.m_suspensionStiffness;
329 }
330 
331 /**
332  *
333  */
334 PN_stdfloat BulletVehicleTuning::
335 get_suspension_compression() const {
336  LightMutexHolder holder(BulletWorld::get_global_lock());
337 
338  return (PN_stdfloat)_.m_suspensionCompression;
339 }
340 
341 /**
342  *
343  */
344 PN_stdfloat BulletVehicleTuning::
345 get_suspension_damping() const {
346  LightMutexHolder holder(BulletWorld::get_global_lock());
347 
348  return (PN_stdfloat)_.m_suspensionDamping;
349 }
350 
351 /**
352  *
353  */
354 PN_stdfloat BulletVehicleTuning::
355 get_max_suspension_travel_cm() const {
356  LightMutexHolder holder(BulletWorld::get_global_lock());
357 
358  return (PN_stdfloat)_.m_maxSuspensionTravelCm;
359 }
360 
361 /**
362  *
363  */
364 PN_stdfloat BulletVehicleTuning::
365 get_friction_slip() const {
366  LightMutexHolder holder(BulletWorld::get_global_lock());
367 
368  return (PN_stdfloat)_.m_frictionSlip;
369 }
370 
371 /**
372  *
373  */
374 PN_stdfloat BulletVehicleTuning::
375 get_max_suspension_force() const {
376  LightMutexHolder holder(BulletWorld::get_global_lock());
377 
378  return (PN_stdfloat)_.m_maxSuspensionForce;
379 }
380 
void reset_suspension()
Resets the vehicle's suspension.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
void set_coordinate_system(BulletUpAxis up)
Specifies which axis is "up".
get_wheel
Returns the BulletWheel with index idx.
Definition: bulletVehicle.h:92
Indicates a coordinate-system transform on vertices.
BulletWheel create_wheel()
Factory method for creating wheels for this vehicle instance.
BulletVehicle(BulletWorld *world, BulletRigidBodyNode *chassis)
Creates a new BulletVehicle instance in the given world and with a chassis node.
static BulletWheel empty()
Named constructor intended to be used for asserts with have to return a concrete value.
Definition: bulletWheel.I:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Changes the complete transform object on this node.
Definition: nodePath.I:565
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node.
Definition: nodePath.I:62
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Similar to MutexHolder, but for a light mutex.
BulletRigidBodyNode * do_get_chassis()
Returns the chassis of this vehicle.
void do_sync_b2p()
Assumes the lock(bullet global lock) is held by the caller.
void set_brake(PN_stdfloat brake, int idx)
Applies braking force to the wheel with index idx.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PN_stdfloat get_steering_value(int idx) const
Returns the steering angle of the wheel with index idx in degrees.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_steering_value(PN_stdfloat steering, int idx)
Sets the steering value (in degrees) of the wheel with index idx.
NodePath get_top(Thread *current_thread=Thread::get_current_thread()) const
Returns a singleton NodePath that represents the top of the path, or empty NodePath if this path is e...
Definition: nodePath.cxx:209
void apply_engine_force(PN_stdfloat force, int idx)
Applies force at the wheel with index idx for acceleration.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
One wheel of a BulletVehicle.
Definition: bulletWheel.h:62
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.