bullet3 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +194 -0
  4. data/data/cube.urdf +22 -0
  5. data/data/plane.urdf +19 -0
  6. data/ext/bullet3/CMakeLists.txt +224 -0
  7. data/ext/bullet3/bullet3.cpp +34 -0
  8. data/ext/bullet3/collision/rb_collision.cpp +428 -0
  9. data/ext/bullet3/collision/rb_collision.hpp +87 -0
  10. data/ext/bullet3/collision/shapes/rb_collision_shape.cpp +485 -0
  11. data/ext/bullet3/collision/shapes/rb_collision_shape.hpp +5 -0
  12. data/ext/bullet3/constraints/rb_constraints.cpp +1310 -0
  13. data/ext/bullet3/constraints/rb_constraints.hpp +226 -0
  14. data/ext/bullet3/dynamics/rb_dynamics.cpp +862 -0
  15. data/ext/bullet3/dynamics/rb_dynamics.hpp +180 -0
  16. data/ext/bullet3/extconf.rb +57 -0
  17. data/ext/bullet3/io/rb_io.cpp +108 -0
  18. data/ext/bullet3/io/rb_io.hpp +40 -0
  19. data/ext/bullet3/linear_math/rb_matrix3x3.cpp +93 -0
  20. data/ext/bullet3/linear_math/rb_matrix3x3.hpp +5 -0
  21. data/ext/bullet3/linear_math/rb_quaternion.cpp +134 -0
  22. data/ext/bullet3/linear_math/rb_quaternion.hpp +5 -0
  23. data/ext/bullet3/linear_math/rb_transform.cpp +157 -0
  24. data/ext/bullet3/linear_math/rb_transform.hpp +34 -0
  25. data/ext/bullet3/linear_math/rb_vector3.cpp +123 -0
  26. data/ext/bullet3/linear_math/rb_vector3.hpp +5 -0
  27. data/ext/bullet3/multi_body/rb_multi_body.cpp +1000 -0
  28. data/ext/bullet3/multi_body/rb_multi_body.hpp +190 -0
  29. data/ext/bullet3/soft_body/rb_soft_body.cpp +720 -0
  30. data/ext/bullet3/soft_body/rb_soft_body.hpp +122 -0
  31. data/ext/bullet3/util/rb_debug_draw.cpp +250 -0
  32. data/ext/bullet3/util/rb_debug_draw.hpp +47 -0
  33. data/ext/bullet3/util/ruby_cpp_compat.hpp +29 -0
  34. data/ext/bullet3/util/type_conversions.hpp +107 -0
  35. data/ext/bullet3/vehicle/rb_vehicle.cpp +467 -0
  36. data/ext/bullet3/vehicle/rb_vehicle.hpp +115 -0
  37. data/lib/bullet3/collision.rb +6 -0
  38. data/lib/bullet3/constraints.rb +6 -0
  39. data/lib/bullet3/data.rb +39 -0
  40. data/lib/bullet3/debug_draw.rb +73 -0
  41. data/lib/bullet3/dynamics.rb +4 -0
  42. data/lib/bullet3/io.rb +110 -0
  43. data/lib/bullet3/linear_math/matrix3x3.rb +69 -0
  44. data/lib/bullet3/linear_math/quaternion.rb +187 -0
  45. data/lib/bullet3/linear_math/transform.rb +48 -0
  46. data/lib/bullet3/linear_math/vector3.rb +199 -0
  47. data/lib/bullet3/linear_math.rb +6 -0
  48. data/lib/bullet3/multi_body.rb +6 -0
  49. data/lib/bullet3/simulation.rb +1170 -0
  50. data/lib/bullet3/soft_body.rb +6 -0
  51. data/lib/bullet3/vehicle.rb +4 -0
  52. data/lib/bullet3/version.rb +5 -0
  53. data/lib/bullet3.rb +49 -0
  54. metadata +124 -0
@@ -0,0 +1,467 @@
1
+ #include "rb_vehicle.hpp"
2
+
3
+ #include <stdexcept>
4
+
5
+ #include "../util/type_conversions.hpp"
6
+
7
+ namespace bullet3 {
8
+ VehicleTuning::VehicleTuning() = default;
9
+
10
+ btRaycastVehicle::btVehicleTuning& VehicleTuning::get()
11
+ {
12
+ return tuning_;
13
+ }
14
+
15
+ const btRaycastVehicle::btVehicleTuning& VehicleTuning::get() const
16
+ {
17
+ return tuning_;
18
+ }
19
+
20
+ btScalar VehicleTuning::suspension_stiffness() const
21
+ {
22
+ return tuning_.m_suspensionStiffness;
23
+ }
24
+
25
+ btScalar VehicleTuning::set_suspension_stiffness(btScalar value)
26
+ {
27
+ tuning_.m_suspensionStiffness = value;
28
+ return value;
29
+ }
30
+
31
+ btScalar VehicleTuning::suspension_compression() const
32
+ {
33
+ return tuning_.m_suspensionCompression;
34
+ }
35
+
36
+ btScalar VehicleTuning::set_suspension_compression(btScalar value)
37
+ {
38
+ tuning_.m_suspensionCompression = value;
39
+ return value;
40
+ }
41
+
42
+ btScalar VehicleTuning::suspension_damping() const
43
+ {
44
+ return tuning_.m_suspensionDamping;
45
+ }
46
+
47
+ btScalar VehicleTuning::set_suspension_damping(btScalar value)
48
+ {
49
+ tuning_.m_suspensionDamping = value;
50
+ return value;
51
+ }
52
+
53
+ btScalar VehicleTuning::max_suspension_travel_cm() const
54
+ {
55
+ return tuning_.m_maxSuspensionTravelCm;
56
+ }
57
+
58
+ btScalar VehicleTuning::set_max_suspension_travel_cm(btScalar value)
59
+ {
60
+ tuning_.m_maxSuspensionTravelCm = value;
61
+ return value;
62
+ }
63
+
64
+ btScalar VehicleTuning::friction_slip() const
65
+ {
66
+ return tuning_.m_frictionSlip;
67
+ }
68
+
69
+ btScalar VehicleTuning::set_friction_slip(btScalar value)
70
+ {
71
+ tuning_.m_frictionSlip = value;
72
+ return value;
73
+ }
74
+
75
+ btScalar VehicleTuning::max_suspension_force() const
76
+ {
77
+ return tuning_.m_maxSuspensionForce;
78
+ }
79
+
80
+ btScalar VehicleTuning::set_max_suspension_force(btScalar value)
81
+ {
82
+ tuning_.m_maxSuspensionForce = value;
83
+ return value;
84
+ }
85
+
86
+ WheelInfo::WheelInfo(btRaycastVehicle* vehicle, int index)
87
+ : vehicle_(vehicle),
88
+ index_(index)
89
+ {
90
+ if (vehicle_ == nullptr) {
91
+ throw std::invalid_argument("expected a RaycastVehicle");
92
+ }
93
+ get();
94
+ }
95
+
96
+ int WheelInfo::index() const
97
+ {
98
+ return index_;
99
+ }
100
+
101
+ btWheelInfo& WheelInfo::get()
102
+ {
103
+ if (index_ < 0 || index_ >= vehicle_->getNumWheels()) {
104
+ throw std::out_of_range("wheel index is out of range");
105
+ }
106
+ return vehicle_->getWheelInfo(index_);
107
+ }
108
+
109
+ const btWheelInfo& WheelInfo::get() const
110
+ {
111
+ if (index_ < 0 || index_ >= vehicle_->getNumWheels()) {
112
+ throw std::out_of_range("wheel index is out of range");
113
+ }
114
+ return vehicle_->getWheelInfo(index_);
115
+ }
116
+
117
+ bool WheelInfo::front_wheel() const
118
+ {
119
+ return get().m_bIsFrontWheel;
120
+ }
121
+
122
+ Transform WheelInfo::world_transform() const
123
+ {
124
+ return Transform(get().m_worldTransform);
125
+ }
126
+
127
+ btVector3 WheelInfo::chassis_connection_point() const
128
+ {
129
+ return get().m_chassisConnectionPointCS;
130
+ }
131
+
132
+ btVector3 WheelInfo::wheel_direction() const
133
+ {
134
+ return get().m_wheelDirectionCS;
135
+ }
136
+
137
+ btVector3 WheelInfo::wheel_axle() const
138
+ {
139
+ return get().m_wheelAxleCS;
140
+ }
141
+
142
+ btScalar WheelInfo::suspension_rest_length() const
143
+ {
144
+ return get().getSuspensionRestLength();
145
+ }
146
+
147
+ btScalar WheelInfo::radius() const
148
+ {
149
+ return get().m_wheelsRadius;
150
+ }
151
+
152
+ btScalar WheelInfo::suspension_stiffness() const
153
+ {
154
+ return get().m_suspensionStiffness;
155
+ }
156
+
157
+ btScalar WheelInfo::set_suspension_stiffness(btScalar value)
158
+ {
159
+ get().m_suspensionStiffness = value;
160
+ return value;
161
+ }
162
+
163
+ btScalar WheelInfo::damping_compression() const
164
+ {
165
+ return get().m_wheelsDampingCompression;
166
+ }
167
+
168
+ btScalar WheelInfo::set_damping_compression(btScalar value)
169
+ {
170
+ get().m_wheelsDampingCompression = value;
171
+ return value;
172
+ }
173
+
174
+ btScalar WheelInfo::damping_relaxation() const
175
+ {
176
+ return get().m_wheelsDampingRelaxation;
177
+ }
178
+
179
+ btScalar WheelInfo::set_damping_relaxation(btScalar value)
180
+ {
181
+ get().m_wheelsDampingRelaxation = value;
182
+ return value;
183
+ }
184
+
185
+ btScalar WheelInfo::friction_slip() const
186
+ {
187
+ return get().m_frictionSlip;
188
+ }
189
+
190
+ btScalar WheelInfo::set_friction_slip(btScalar value)
191
+ {
192
+ get().m_frictionSlip = value;
193
+ return value;
194
+ }
195
+
196
+ btScalar WheelInfo::steering() const
197
+ {
198
+ return get().m_steering;
199
+ }
200
+
201
+ btScalar WheelInfo::rotation() const
202
+ {
203
+ return get().m_rotation;
204
+ }
205
+
206
+ btScalar WheelInfo::delta_rotation() const
207
+ {
208
+ return get().m_deltaRotation;
209
+ }
210
+
211
+ btScalar WheelInfo::roll_influence() const
212
+ {
213
+ return get().m_rollInfluence;
214
+ }
215
+
216
+ btScalar WheelInfo::set_roll_influence(btScalar value)
217
+ {
218
+ get().m_rollInfluence = value;
219
+ return value;
220
+ }
221
+
222
+ btScalar WheelInfo::engine_force() const
223
+ {
224
+ return get().m_engineForce;
225
+ }
226
+
227
+ btScalar WheelInfo::brake() const
228
+ {
229
+ return get().m_brake;
230
+ }
231
+
232
+ btScalar WheelInfo::suspension_force() const
233
+ {
234
+ return get().m_wheelsSuspensionForce;
235
+ }
236
+
237
+ btScalar WheelInfo::skid_info() const
238
+ {
239
+ return get().m_skidInfo;
240
+ }
241
+
242
+ bool WheelInfo::contact() const
243
+ {
244
+ return get().m_raycastInfo.m_isInContact;
245
+ }
246
+
247
+ btVector3 WheelInfo::contact_point() const
248
+ {
249
+ return get().m_raycastInfo.m_contactPointWS;
250
+ }
251
+
252
+ btVector3 WheelInfo::contact_normal() const
253
+ {
254
+ return get().m_raycastInfo.m_contactNormalWS;
255
+ }
256
+
257
+ RaycastVehicle::RaycastVehicle(VehicleTuning& tuning, DiscreteDynamicsWorld& world, RigidBody& chassis)
258
+ : tuning_(tuning.get()),
259
+ raycaster_(std::make_unique<btDefaultVehicleRaycaster>(world.get())),
260
+ vehicle_(std::make_unique<btRaycastVehicle>(tuning_, chassis.get(), raycaster_.get()))
261
+ {
262
+ }
263
+
264
+ btRaycastVehicle* RaycastVehicle::get()
265
+ {
266
+ return vehicle_.get();
267
+ }
268
+
269
+ const btRaycastVehicle* RaycastVehicle::get() const
270
+ {
271
+ return vehicle_.get();
272
+ }
273
+
274
+ int RaycastVehicle::validate_wheel_index(int index) const
275
+ {
276
+ if (index < 0 || index >= vehicle_->getNumWheels()) {
277
+ throw std::out_of_range("wheel index is out of range");
278
+ }
279
+ return index;
280
+ }
281
+
282
+ WheelInfo RaycastVehicle::add_wheel(Rice::Object connection_point,
283
+ Rice::Object wheel_direction,
284
+ Rice::Object wheel_axle,
285
+ btScalar suspension_rest_length,
286
+ btScalar wheel_radius,
287
+ VehicleTuning& tuning,
288
+ bool front_wheel)
289
+ {
290
+ vehicle_->addWheel(
291
+ coerce_vector(connection_point),
292
+ coerce_vector(wheel_direction),
293
+ coerce_vector(wheel_axle),
294
+ suspension_rest_length,
295
+ wheel_radius,
296
+ tuning.get(),
297
+ front_wheel);
298
+ return WheelInfo(vehicle_.get(), vehicle_->getNumWheels() - 1);
299
+ }
300
+
301
+ int RaycastVehicle::num_wheels() const
302
+ {
303
+ return vehicle_->getNumWheels();
304
+ }
305
+
306
+ WheelInfo RaycastVehicle::wheel_info(int index)
307
+ {
308
+ return WheelInfo(vehicle_.get(), validate_wheel_index(index));
309
+ }
310
+
311
+ Transform RaycastVehicle::wheel_transform(int index) const
312
+ {
313
+ return Transform(vehicle_->getWheelTransformWS(validate_wheel_index(index)));
314
+ }
315
+
316
+ void RaycastVehicle::update_wheel_transform(int index, bool interpolated_transform)
317
+ {
318
+ vehicle_->updateWheelTransform(validate_wheel_index(index), interpolated_transform);
319
+ }
320
+
321
+ Transform RaycastVehicle::chassis_world_transform() const
322
+ {
323
+ return Transform(vehicle_->getChassisWorldTransform());
324
+ }
325
+
326
+ btScalar RaycastVehicle::steering_value(int wheel) const
327
+ {
328
+ return vehicle_->getSteeringValue(validate_wheel_index(wheel));
329
+ }
330
+
331
+ void RaycastVehicle::set_steering_value(btScalar steering, int wheel)
332
+ {
333
+ vehicle_->setSteeringValue(steering, validate_wheel_index(wheel));
334
+ }
335
+
336
+ void RaycastVehicle::apply_engine_force(btScalar force, int wheel)
337
+ {
338
+ vehicle_->applyEngineForce(force, validate_wheel_index(wheel));
339
+ }
340
+
341
+ void RaycastVehicle::set_brake(btScalar brake, int wheel)
342
+ {
343
+ vehicle_->setBrake(brake, validate_wheel_index(wheel));
344
+ }
345
+
346
+ void RaycastVehicle::reset_suspension()
347
+ {
348
+ vehicle_->resetSuspension();
349
+ }
350
+
351
+ btScalar RaycastVehicle::current_speed_km_hour() const
352
+ {
353
+ return vehicle_->getCurrentSpeedKmHour();
354
+ }
355
+
356
+ btVector3 RaycastVehicle::forward_vector() const
357
+ {
358
+ return vehicle_->getForwardVector();
359
+ }
360
+
361
+ void RaycastVehicle::set_pitch_control(btScalar pitch)
362
+ {
363
+ vehicle_->setPitchControl(pitch);
364
+ }
365
+
366
+ void RaycastVehicle::set_coordinate_system(int right_index, int up_index, int forward_index)
367
+ {
368
+ vehicle_->setCoordinateSystem(right_index, up_index, forward_index);
369
+ }
370
+
371
+ Rice::Array RaycastVehicle::coordinate_system() const
372
+ {
373
+ Rice::Array array;
374
+ array.push(vehicle_->getRightAxis());
375
+ array.push(vehicle_->getUpAxis());
376
+ array.push(vehicle_->getForwardAxis());
377
+ return array;
378
+ }
379
+
380
+ void RaycastVehicle::update_vehicle(btScalar step)
381
+ {
382
+ vehicle_->updateVehicle(step);
383
+ }
384
+ } // namespace bullet3
385
+
386
+ void Init_Vehicle(Rice::Module rb_mBullet)
387
+ {
388
+ Rice::define_class_under<bullet3::VehicleTuning>(rb_mBullet, "VehicleTuning")
389
+ .define_constructor(Rice::Constructor<bullet3::VehicleTuning>())
390
+ .define_method("suspension_stiffness", &bullet3::VehicleTuning::suspension_stiffness)
391
+ .define_method("suspension_stiffness=", &bullet3::VehicleTuning::set_suspension_stiffness)
392
+ .define_method("suspension_compression", &bullet3::VehicleTuning::suspension_compression)
393
+ .define_method("suspension_compression=", &bullet3::VehicleTuning::set_suspension_compression)
394
+ .define_method("suspension_damping", &bullet3::VehicleTuning::suspension_damping)
395
+ .define_method("suspension_damping=", &bullet3::VehicleTuning::set_suspension_damping)
396
+ .define_method("max_suspension_travel_cm", &bullet3::VehicleTuning::max_suspension_travel_cm)
397
+ .define_method("max_suspension_travel_cm=", &bullet3::VehicleTuning::set_max_suspension_travel_cm)
398
+ .define_method("friction_slip", &bullet3::VehicleTuning::friction_slip)
399
+ .define_method("friction_slip=", &bullet3::VehicleTuning::set_friction_slip)
400
+ .define_method("max_suspension_force", &bullet3::VehicleTuning::max_suspension_force)
401
+ .define_method("max_suspension_force=", &bullet3::VehicleTuning::set_max_suspension_force);
402
+
403
+ Rice::define_class_under<bullet3::WheelInfo>(rb_mBullet, "WheelInfo")
404
+ .define_method("index", &bullet3::WheelInfo::index)
405
+ .define_method("front_wheel?", &bullet3::WheelInfo::front_wheel)
406
+ .define_method("world_transform", &bullet3::WheelInfo::world_transform)
407
+ .define_method("chassis_connection_point", &bullet3::WheelInfo::chassis_connection_point)
408
+ .define_method("wheel_direction", &bullet3::WheelInfo::wheel_direction)
409
+ .define_method("wheel_axle", &bullet3::WheelInfo::wheel_axle)
410
+ .define_method("suspension_rest_length", &bullet3::WheelInfo::suspension_rest_length)
411
+ .define_method("radius", &bullet3::WheelInfo::radius)
412
+ .define_method("suspension_stiffness", &bullet3::WheelInfo::suspension_stiffness)
413
+ .define_method("suspension_stiffness=", &bullet3::WheelInfo::set_suspension_stiffness)
414
+ .define_method("damping_compression", &bullet3::WheelInfo::damping_compression)
415
+ .define_method("damping_compression=", &bullet3::WheelInfo::set_damping_compression)
416
+ .define_method("damping_relaxation", &bullet3::WheelInfo::damping_relaxation)
417
+ .define_method("damping_relaxation=", &bullet3::WheelInfo::set_damping_relaxation)
418
+ .define_method("friction_slip", &bullet3::WheelInfo::friction_slip)
419
+ .define_method("friction_slip=", &bullet3::WheelInfo::set_friction_slip)
420
+ .define_method("steering", &bullet3::WheelInfo::steering)
421
+ .define_method("rotation", &bullet3::WheelInfo::rotation)
422
+ .define_method("delta_rotation", &bullet3::WheelInfo::delta_rotation)
423
+ .define_method("roll_influence", &bullet3::WheelInfo::roll_influence)
424
+ .define_method("roll_influence=", &bullet3::WheelInfo::set_roll_influence)
425
+ .define_method("engine_force", &bullet3::WheelInfo::engine_force)
426
+ .define_method("brake", &bullet3::WheelInfo::brake)
427
+ .define_method("suspension_force", &bullet3::WheelInfo::suspension_force)
428
+ .define_method("skid_info", &bullet3::WheelInfo::skid_info)
429
+ .define_method("contact?", &bullet3::WheelInfo::contact)
430
+ .define_method("contact_point", &bullet3::WheelInfo::contact_point)
431
+ .define_method("contact_normal", &bullet3::WheelInfo::contact_normal);
432
+
433
+ Rice::define_class_under<bullet3::RaycastVehicle>(rb_mBullet, "RaycastVehicle")
434
+ .define_constructor(Rice::Constructor<bullet3::RaycastVehicle,
435
+ bullet3::VehicleTuning&,
436
+ bullet3::DiscreteDynamicsWorld&,
437
+ bullet3::RigidBody&>(),
438
+ Rice::Arg("tuning").keepAlive(),
439
+ Rice::Arg("world").keepAlive(),
440
+ Rice::Arg("chassis").keepAlive())
441
+ .define_method("add_wheel", &bullet3::RaycastVehicle::add_wheel,
442
+ Rice::Arg("connection_point").setValue(),
443
+ Rice::Arg("wheel_direction").setValue(),
444
+ Rice::Arg("wheel_axle").setValue(),
445
+ Rice::Arg("suspension_rest_length"),
446
+ Rice::Arg("wheel_radius"),
447
+ Rice::Arg("tuning").keepAlive(),
448
+ Rice::Arg("front_wheel"))
449
+ .define_method("num_wheels", &bullet3::RaycastVehicle::num_wheels)
450
+ .define_method("wheel_info", &bullet3::RaycastVehicle::wheel_info)
451
+ .define_method("wheel_transform", &bullet3::RaycastVehicle::wheel_transform)
452
+ .define_method("update_wheel_transform", &bullet3::RaycastVehicle::update_wheel_transform,
453
+ Rice::Arg("index"),
454
+ Rice::Arg("interpolated_transform") = true)
455
+ .define_method("chassis_world_transform", &bullet3::RaycastVehicle::chassis_world_transform)
456
+ .define_method("steering_value", &bullet3::RaycastVehicle::steering_value)
457
+ .define_method("set_steering_value", &bullet3::RaycastVehicle::set_steering_value)
458
+ .define_method("apply_engine_force", &bullet3::RaycastVehicle::apply_engine_force)
459
+ .define_method("set_brake", &bullet3::RaycastVehicle::set_brake)
460
+ .define_method("reset_suspension", &bullet3::RaycastVehicle::reset_suspension)
461
+ .define_method("current_speed_km_hour", &bullet3::RaycastVehicle::current_speed_km_hour)
462
+ .define_method("forward_vector", &bullet3::RaycastVehicle::forward_vector)
463
+ .define_method("pitch_control=", &bullet3::RaycastVehicle::set_pitch_control)
464
+ .define_method("set_coordinate_system", &bullet3::RaycastVehicle::set_coordinate_system)
465
+ .define_method("coordinate_system", &bullet3::RaycastVehicle::coordinate_system)
466
+ .define_method("update_vehicle", &bullet3::RaycastVehicle::update_vehicle);
467
+ }
@@ -0,0 +1,115 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+
5
+ #include <BulletDynamics/Vehicle/btRaycastVehicle.h>
6
+ #include <rice/rice.hpp>
7
+
8
+ #include "../dynamics/rb_dynamics.hpp"
9
+ #include "../linear_math/rb_transform.hpp"
10
+
11
+ namespace bullet3 {
12
+ class VehicleTuning {
13
+ public:
14
+ VehicleTuning();
15
+
16
+ btRaycastVehicle::btVehicleTuning& get();
17
+ const btRaycastVehicle::btVehicleTuning& get() const;
18
+ btScalar suspension_stiffness() const;
19
+ btScalar set_suspension_stiffness(btScalar value);
20
+ btScalar suspension_compression() const;
21
+ btScalar set_suspension_compression(btScalar value);
22
+ btScalar suspension_damping() const;
23
+ btScalar set_suspension_damping(btScalar value);
24
+ btScalar max_suspension_travel_cm() const;
25
+ btScalar set_max_suspension_travel_cm(btScalar value);
26
+ btScalar friction_slip() const;
27
+ btScalar set_friction_slip(btScalar value);
28
+ btScalar max_suspension_force() const;
29
+ btScalar set_max_suspension_force(btScalar value);
30
+
31
+ private:
32
+ btRaycastVehicle::btVehicleTuning tuning_;
33
+ };
34
+
35
+ class WheelInfo {
36
+ public:
37
+ WheelInfo(btRaycastVehicle* vehicle, int index);
38
+
39
+ int index() const;
40
+ bool front_wheel() const;
41
+ Transform world_transform() const;
42
+ btVector3 chassis_connection_point() const;
43
+ btVector3 wheel_direction() const;
44
+ btVector3 wheel_axle() const;
45
+ btScalar suspension_rest_length() const;
46
+ btScalar radius() const;
47
+ btScalar suspension_stiffness() const;
48
+ btScalar set_suspension_stiffness(btScalar value);
49
+ btScalar damping_compression() const;
50
+ btScalar set_damping_compression(btScalar value);
51
+ btScalar damping_relaxation() const;
52
+ btScalar set_damping_relaxation(btScalar value);
53
+ btScalar friction_slip() const;
54
+ btScalar set_friction_slip(btScalar value);
55
+ btScalar steering() const;
56
+ btScalar rotation() const;
57
+ btScalar delta_rotation() const;
58
+ btScalar roll_influence() const;
59
+ btScalar set_roll_influence(btScalar value);
60
+ btScalar engine_force() const;
61
+ btScalar brake() const;
62
+ btScalar suspension_force() const;
63
+ btScalar skid_info() const;
64
+ bool contact() const;
65
+ btVector3 contact_point() const;
66
+ btVector3 contact_normal() const;
67
+
68
+ private:
69
+ btWheelInfo& get();
70
+ const btWheelInfo& get() const;
71
+
72
+ btRaycastVehicle* vehicle_;
73
+ int index_;
74
+ };
75
+
76
+ class RaycastVehicle {
77
+ public:
78
+ RaycastVehicle(VehicleTuning& tuning, DiscreteDynamicsWorld& world, RigidBody& chassis);
79
+
80
+ btRaycastVehicle* get();
81
+ const btRaycastVehicle* get() const;
82
+ WheelInfo add_wheel(Rice::Object connection_point,
83
+ Rice::Object wheel_direction,
84
+ Rice::Object wheel_axle,
85
+ btScalar suspension_rest_length,
86
+ btScalar wheel_radius,
87
+ VehicleTuning& tuning,
88
+ bool front_wheel);
89
+ int num_wheels() const;
90
+ WheelInfo wheel_info(int index);
91
+ Transform wheel_transform(int index) const;
92
+ void update_wheel_transform(int index, bool interpolated_transform);
93
+ Transform chassis_world_transform() const;
94
+ btScalar steering_value(int wheel) const;
95
+ void set_steering_value(btScalar steering, int wheel);
96
+ void apply_engine_force(btScalar force, int wheel);
97
+ void set_brake(btScalar brake, int wheel);
98
+ void reset_suspension();
99
+ btScalar current_speed_km_hour() const;
100
+ btVector3 forward_vector() const;
101
+ void set_pitch_control(btScalar pitch);
102
+ void set_coordinate_system(int right_index, int up_index, int forward_index);
103
+ Rice::Array coordinate_system() const;
104
+ void update_vehicle(btScalar step);
105
+
106
+ private:
107
+ int validate_wheel_index(int index) const;
108
+
109
+ btRaycastVehicle::btVehicleTuning tuning_;
110
+ std::unique_ptr<btDefaultVehicleRaycaster> raycaster_;
111
+ std::unique_ptr<btRaycastVehicle> vehicle_;
112
+ };
113
+ } // namespace bullet3
114
+
115
+ void Init_Vehicle(Rice::Module rb_mBullet);
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet3
4
+ module Shapes
5
+ end unless const_defined?(:Shapes, false)
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet3
4
+ module Constraints
5
+ end unless const_defined?(:Constraints, false)
6
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet3
4
+ module Data
5
+ DEFAULT_PATH = File.expand_path("../../data", __dir__)
6
+
7
+ class << self
8
+ def search_paths
9
+ @search_paths ||= [DEFAULT_PATH]
10
+ end
11
+
12
+ def add_search_path(path)
13
+ expanded = File.expand_path(path)
14
+ search_paths << expanded unless search_paths.include?(expanded)
15
+ expanded
16
+ end
17
+
18
+ def remove_search_path(path)
19
+ search_paths.delete(File.expand_path(path))
20
+ end
21
+
22
+ def path(*parts)
23
+ File.join(DEFAULT_PATH, *parts)
24
+ end
25
+
26
+ def find(filename)
27
+ expanded = File.expand_path(filename)
28
+ return expanded if File.exist?(expanded)
29
+
30
+ search_paths.each do |search_path|
31
+ candidate = File.expand_path(filename, search_path)
32
+ return candidate if File.exist?(candidate)
33
+ end
34
+
35
+ raise Errno::ENOENT, filename
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bullet3
4
+ class DebugDraw
5
+ NO_DEBUG = 0 unless const_defined?(:NO_DEBUG, false)
6
+ DRAW_WIREFRAME = 1 unless const_defined?(:DRAW_WIREFRAME, false)
7
+ DRAW_AABB = 2 unless const_defined?(:DRAW_AABB, false)
8
+ DRAW_CONTACT_POINTS = 8 unless const_defined?(:DRAW_CONTACT_POINTS, false)
9
+ DRAW_CONSTRAINTS = 1 << 11 unless const_defined?(:DRAW_CONSTRAINTS, false)
10
+ DRAW_CONSTRAINT_LIMITS = 1 << 12 unless const_defined?(:DRAW_CONSTRAINT_LIMITS, false)
11
+ DRAW_FRAMES = 1 << 15 unless const_defined?(:DRAW_FRAMES, false)
12
+
13
+ attr_accessor :debug_mode
14
+ attr_reader :lines, :contact_points, :warnings, :texts
15
+
16
+ def initialize(target = nil)
17
+ @target = target
18
+ @debug_mode = DRAW_WIREFRAME | DRAW_AABB | DRAW_CONSTRAINTS | DRAW_CONSTRAINT_LIMITS
19
+ clear
20
+ end
21
+
22
+ def clear
23
+ @lines = []
24
+ @contact_points = []
25
+ @warnings = []
26
+ @texts = []
27
+ nil
28
+ end
29
+
30
+ def draw_line(from, to, color)
31
+ entry = { from: vector_array(from), to: vector_array(to), color: vector_array(color) }
32
+ lines << entry
33
+ @target.draw_line(entry[:from], entry[:to], entry[:color]) if @target&.respond_to?(:draw_line)
34
+ nil
35
+ end
36
+
37
+ def draw_contact_point(point, normal, distance = nil, life_time = nil, color = nil, **options)
38
+ distance = options.fetch(:distance, distance)
39
+ life_time = options.fetch(:life_time, life_time)
40
+ color = options.fetch(:color, color)
41
+ entry = {
42
+ point: vector_array(point),
43
+ normal: vector_array(normal),
44
+ distance: Float(distance),
45
+ life_time: Integer(life_time),
46
+ color: vector_array(color)
47
+ }
48
+ contact_points << entry
49
+ @target.draw_contact_point(entry) if @target&.respond_to?(:draw_contact_point)
50
+ nil
51
+ end
52
+
53
+ def report_error_warning(message)
54
+ warning = message.to_s
55
+ warnings << warning
56
+ @target.report_error_warning(warning) if @target&.respond_to?(:report_error_warning)
57
+ nil
58
+ end
59
+
60
+ def draw_3d_text(location, text)
61
+ entry = { location: vector_array(location), text: text.to_s }
62
+ texts << entry
63
+ @target.draw_3d_text(entry[:location], entry[:text]) if @target&.respond_to?(:draw_3d_text)
64
+ nil
65
+ end
66
+
67
+ private
68
+
69
+ def vector_array(value)
70
+ Vector3.coerce(value).to_a
71
+ end
72
+ end unless const_defined?(:DebugDraw, false)
73
+ end