Panda3D
Loading...
Searching...
No Matches
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
22TypeHandle 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 */
44set_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 */
67LVector3 BulletVehicle::
68get_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 */
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 */
99PN_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 */
120get_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 */
131set_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 */
142apply_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 */
153set_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 */
163void BulletVehicle::
164set_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 */
174create_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 */
194btVector3 BulletVehicle::
195get_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 */
213get_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 */
224get_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 */
235do_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 */
264void BulletVehicleTuning::
265set_suspension_stiffness(PN_stdfloat value) {
266 LightMutexHolder holder(BulletWorld::get_global_lock());
267
268 _.m_suspensionStiffness = (btScalar)value;
269}
270
271/**
272 *
273 */
274void BulletVehicleTuning::
275set_suspension_compression(PN_stdfloat value) {
276 LightMutexHolder holder(BulletWorld::get_global_lock());
277
278 _.m_suspensionCompression = (btScalar)value;
279}
280
281/**
282 *
283 */
284void BulletVehicleTuning::
285set_suspension_damping(PN_stdfloat value) {
286 LightMutexHolder holder(BulletWorld::get_global_lock());
287
288 _.m_suspensionDamping = (btScalar)value;
289}
290
291/**
292 *
293 */
294void BulletVehicleTuning::
295set_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 */
304void BulletVehicleTuning::
305set_friction_slip(PN_stdfloat value) {
306 LightMutexHolder holder(BulletWorld::get_global_lock());
307
308 _.m_frictionSlip = (btScalar)value;
309}
310
311/**
312 *
313 */
314void BulletVehicleTuning::
315set_max_suspension_force(PN_stdfloat value) {
316 LightMutexHolder holder(BulletWorld::get_global_lock());
317
318 _.m_maxSuspensionForce = (btScalar)value;
319}
320
321/**
322 *
323 */
324PN_stdfloat BulletVehicleTuning::
325get_suspension_stiffness() const {
326 LightMutexHolder holder(BulletWorld::get_global_lock());
327
328 return (PN_stdfloat)_.m_suspensionStiffness;
329}
330
331/**
332 *
333 */
334PN_stdfloat BulletVehicleTuning::
335get_suspension_compression() const {
336 LightMutexHolder holder(BulletWorld::get_global_lock());
337
338 return (PN_stdfloat)_.m_suspensionCompression;
339}
340
341/**
342 *
343 */
344PN_stdfloat BulletVehicleTuning::
345get_suspension_damping() const {
346 LightMutexHolder holder(BulletWorld::get_global_lock());
347
348 return (PN_stdfloat)_.m_suspensionDamping;
349}
350
351/**
352 *
353 */
354PN_stdfloat BulletVehicleTuning::
355get_max_suspension_travel_cm() const {
356 LightMutexHolder holder(BulletWorld::get_global_lock());
357
358 return (PN_stdfloat)_.m_maxSuspensionTravelCm;
359}
360
361/**
362 *
363 */
364PN_stdfloat BulletVehicleTuning::
365get_friction_slip() const {
366 LightMutexHolder holder(BulletWorld::get_global_lock());
367
368 return (PN_stdfloat)_.m_frictionSlip;
369}
370
371/**
372 *
373 */
374PN_stdfloat BulletVehicleTuning::
375get_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.
get_forward_vector
Returns the forward vector representing the car's actual direction of movement.
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.
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.
void reset_suspension()
Resets the vehicle's suspension.
get_current_speed_km_hour
Returns the current speed in kilometers per hour.
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.
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:208
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.