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  */
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  */
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::
101  LightMutexHolder holder(BulletWorld::get_global_lock());
102 
103  return (PN_stdfloat)_vehicle->getCurrentSpeedKmHour();
104 }
105 
106 /**
107  * Resets the vehicle's suspension.
108  */
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  */
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  */
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  */
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  */
174 create_wheel() {
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  */
235 do_sync_b2p() {
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 
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.
void do_sync_b2p()
Assumes the lock(bullet global lock) is held by the caller.
void set_steering_value(PN_stdfloat steering, int idx)
Sets the steering value (in degrees) of the wheel with index idx.
get_wheel
Returns the BulletWheel with index idx.
Definition: bulletVehicle.h:92
get_forward_vector
Returns the forward vector representing the car's actual direction of movement.
Definition: bulletVehicle.h:99
PN_stdfloat get_steering_value(int idx) const
Returns the steering angle of the wheel with index idx in degrees.
BulletRigidBodyNode * do_get_chassis()
Returns the chassis of this vehicle.
get_num_wheels
Returns the number of wheels this vehicle has.
Definition: bulletVehicle.h:92
void apply_engine_force(PN_stdfloat force, int idx)
Applies force at the wheel with index idx for acceleration.
get_chassis
Returns the chassis of this vehicle.
Definition: bulletVehicle.h:97
void reset_suspension()
Resets the vehicle's suspension.
get_current_speed_km_hour
Returns the current speed in kilometers per hour.
Definition: bulletVehicle.h:98
BulletVehicle(BulletWorld *world, BulletRigidBodyNode *chassis)
Creates a new BulletVehicle instance in the given world and with a chassis node.
void set_brake(PN_stdfloat brake, int idx)
Applies braking force to the wheel with index idx.
void set_coordinate_system(BulletUpAxis up)
Specifies which axis is "up".
BulletWheel create_wheel()
Factory method for creating wheels for this vehicle instance.
One wheel of a BulletVehicle.
Definition: bulletWheel.h:62
static BulletWheel empty()
Named constructor intended to be used for asserts with have to return a concrete value.
Definition: bulletWheel.I:35
Similar to MutexHolder, but for a light mutex.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
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
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 set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Changes the complete transform object on this node.
Definition: nodePath.I:565
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
Indicates a coordinate-system transform on vertices.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.