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 */
28 BulletVehicle::
29 BulletVehicle(BulletWorld *world, BulletRigidBodyNode *chassis) {
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 */
78 BulletRigidBodyNode *BulletVehicle::
79 do_get_chassis() {
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::
110 reset_suspension() {
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 */
173 BulletWheel BulletVehicle::
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 */
223 BulletWheel BulletVehicle::
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::
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
bulletRigidBodyNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bulletVehicle.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bulletWheel.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bulletWorld.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BulletRigidBodyNode
Definition: bulletRigidBodyNode.h:31
BulletVehicle::do_sync_b2p
void do_sync_b2p()
Assumes the lock(bullet global lock) is held by the caller.
Definition: bulletVehicle.cxx:235
BulletVehicle::set_steering_value
void set_steering_value(PN_stdfloat steering, int idx)
Sets the steering value (in degrees) of the wheel with index idx.
Definition: bulletVehicle.cxx:131
BulletVehicle::get_wheel
get_wheel
Returns the BulletWheel with index idx.
Definition: bulletVehicle.h:92
BulletVehicle::get_forward_vector
get_forward_vector
Returns the forward vector representing the car's actual direction of movement.
Definition: bulletVehicle.h:99
BulletVehicle::get_steering_value
PN_stdfloat get_steering_value(int idx) const
Returns the steering angle of the wheel with index idx in degrees.
Definition: bulletVehicle.cxx:120
BulletVehicle::do_get_chassis
BulletRigidBodyNode * do_get_chassis()
Returns the chassis of this vehicle.
Definition: bulletVehicle.cxx:79
BulletVehicle::get_num_wheels
get_num_wheels
Returns the number of wheels this vehicle has.
Definition: bulletVehicle.h:92
BulletVehicle::apply_engine_force
void apply_engine_force(PN_stdfloat force, int idx)
Applies force at the wheel with index idx for acceleration.
Definition: bulletVehicle.cxx:142
BulletVehicle::get_chassis
get_chassis
Returns the chassis of this vehicle.
Definition: bulletVehicle.h:97
BulletVehicle::reset_suspension
void reset_suspension()
Resets the vehicle's suspension.
Definition: bulletVehicle.cxx:110
BulletVehicle::get_current_speed_km_hour
get_current_speed_km_hour
Returns the current speed in kilometers per hour.
Definition: bulletVehicle.h:98
BulletVehicle::BulletVehicle
BulletVehicle(BulletWorld *world, BulletRigidBodyNode *chassis)
Creates a new BulletVehicle instance in the given world and with a chassis node.
Definition: bulletVehicle.cxx:29
BulletVehicle::set_brake
void set_brake(PN_stdfloat brake, int idx)
Applies braking force to the wheel with index idx.
Definition: bulletVehicle.cxx:153
BulletVehicle::set_coordinate_system
void set_coordinate_system(BulletUpAxis up)
Specifies which axis is "up".
Definition: bulletVehicle.cxx:44
BulletVehicle::create_wheel
BulletWheel create_wheel()
Factory method for creating wheels for this vehicle instance.
Definition: bulletVehicle.cxx:174
BulletWheel
One wheel of a BulletVehicle.
Definition: bulletWheel.h:62
BulletWheel::empty
static BulletWheel empty()
Named constructor intended to be used for asserts with have to return a concrete value.
Definition: bulletWheel.I:35
BulletWorld
Definition: bulletWorld.h:51
LightMutexHolder
Similar to MutexHolder, but for a light mutex.
Definition: lightMutexHolder.h:25
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
NodePath::any_path
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
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
NodePath::set_transform
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
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
TransformState
Indicates a coordinate-system transform on vertices.
Definition: transformState.h:54
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
config_bullet.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.