00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "bulletRigidBodyNode.h"
00016 #include "bulletShape.h"
00017
00018 TypeHandle BulletRigidBodyNode::_type_handle;
00019
00020
00021
00022
00023
00024
00025 BulletRigidBodyNode::
00026 BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
00027
00028
00029 _sync = TransformState::make_identity();
00030 _sync_disable = false;
00031
00032
00033 btScalar mass(0.0);
00034 btVector3 inertia(0, 0, 0);
00035
00036
00037 MotionState *motion = new MotionState(_sync);
00038 btRigidBody::btRigidBodyConstructionInfo ci(mass, motion, _shape, inertia);
00039
00040
00041 if (bullet_additional_damping) {
00042 ci.m_additionalDamping = true;
00043 ci.m_additionalDampingFactor = bullet_additional_damping_linear_factor;
00044 ci.m_additionalLinearDampingThresholdSqr = bullet_additional_damping_linear_threshold;
00045 ci.m_additionalAngularDampingFactor = bullet_additional_damping_angular_factor;
00046 ci.m_additionalAngularDampingThresholdSqr = bullet_additional_damping_angular_threshold;
00047 }
00048
00049
00050 _rigid = new btRigidBody(ci);
00051 _rigid->setUserPointer(this);
00052 }
00053
00054
00055
00056
00057
00058
00059 void BulletRigidBodyNode::
00060 output(ostream &out) const {
00061
00062 BulletBodyNode::output(out);
00063
00064 out << " mass=" << get_mass();
00065 }
00066
00067
00068
00069
00070
00071
00072 btCollisionObject *BulletRigidBodyNode::
00073 get_object() const {
00074
00075 return _rigid;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 void BulletRigidBodyNode::
00087 shape_changed() {
00088
00089 set_mass(get_mass());
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 void BulletRigidBodyNode::
00102 set_mass(PN_stdfloat mass) {
00103
00104 btScalar bt_mass = mass;
00105 btVector3 bt_inertia(0.0, 0.0, 0.0);
00106
00107 if (bt_mass > 0.0) {
00108 _rigid->getCollisionShape()->calculateLocalInertia(bt_mass, bt_inertia);
00109 }
00110
00111 _rigid->setMassProps(bt_mass, bt_inertia);
00112 _rigid->updateInertiaTensor();
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122 PN_stdfloat BulletRigidBodyNode::
00123 get_mass() const {
00124
00125 btScalar inv_mass = _rigid->getInvMass();
00126 btScalar mass = inv_mass == btScalar(0.0) ? btScalar(0.0) : btScalar(1.0) / inv_mass;
00127
00128 return mass;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 void BulletRigidBodyNode::
00148 set_inertia(const LVecBase3 &inertia) {
00149
00150 btVector3 inv_inertia(
00151 inertia.get_x() == 0.0 ? btScalar(0.0) : btScalar(1.0 / inertia.get_x()),
00152 inertia.get_y() == 0.0 ? btScalar(0.0) : btScalar(1.0 / inertia.get_y()),
00153 inertia.get_z() == 0.0 ? btScalar(0.0) : btScalar(1.0 / inertia.get_z())
00154 );
00155
00156 _rigid->setInvInertiaDiagLocal(inv_inertia);
00157 _rigid->updateInertiaTensor();
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 LVector3 BulletRigidBodyNode::
00169 get_inertia() const {
00170
00171 btVector3 inv_inertia = _rigid->getInvInertiaDiagLocal();
00172 LVector3 inertia(
00173 inv_inertia.x() == btScalar(0.0) ? 0.0 : 1.0 / inv_inertia.x(),
00174 inv_inertia.y() == btScalar(0.0) ? 0.0 : 1.0 / inv_inertia.y(),
00175 inv_inertia.z() == btScalar(0.0) ? 0.0 : 1.0 / inv_inertia.z()
00176 );
00177
00178 return inertia;
00179 }
00180
00181
00182
00183
00184
00185
00186 void BulletRigidBodyNode::
00187 apply_force(const LVector3 &force, const LPoint3 &pos) {
00188
00189 nassertv_always(!force.is_nan());
00190 nassertv_always(!pos.is_nan());
00191
00192 _rigid->applyForce(LVecBase3_to_btVector3(force),
00193 LVecBase3_to_btVector3(pos));
00194 }
00195
00196
00197
00198
00199
00200
00201 void BulletRigidBodyNode::
00202 apply_central_force(const LVector3 &force) {
00203
00204 nassertv_always(!force.is_nan());
00205
00206 _rigid->applyCentralForce(LVecBase3_to_btVector3(force));
00207 }
00208
00209
00210
00211
00212
00213
00214 void BulletRigidBodyNode::
00215 apply_torque(const LVector3 &torque) {
00216
00217 nassertv_always(!torque.is_nan());
00218
00219 _rigid->applyTorque(LVecBase3_to_btVector3(torque));
00220 }
00221
00222
00223
00224
00225
00226
00227 void BulletRigidBodyNode::
00228 apply_torque_impulse(const LVector3 &torque) {
00229
00230 nassertv_always(!torque.is_nan());
00231
00232 _rigid->applyTorqueImpulse(LVecBase3_to_btVector3(torque));
00233 }
00234
00235
00236
00237
00238
00239
00240 void BulletRigidBodyNode::
00241 apply_impulse(const LVector3 &impulse, const LPoint3 &pos) {
00242
00243 nassertv_always(!impulse.is_nan());
00244 nassertv_always(!pos.is_nan());
00245
00246 _rigid->applyImpulse(LVecBase3_to_btVector3(impulse),
00247 LVecBase3_to_btVector3(pos));
00248 }
00249
00250
00251
00252
00253
00254
00255 void BulletRigidBodyNode::
00256 apply_central_impulse(const LVector3 &impulse) {
00257
00258 nassertv_always(!impulse.is_nan());
00259
00260 _rigid->applyCentralImpulse(LVecBase3_to_btVector3(impulse));
00261 }
00262
00263
00264
00265
00266
00267
00268 void BulletRigidBodyNode::
00269 transform_changed() {
00270
00271 if (_sync_disable) return;
00272
00273 NodePath np = NodePath::any_path((PandaNode *)this);
00274 CPT(TransformState) ts = np.get_net_transform();
00275
00276 LMatrix4 m_sync = _sync->get_mat();
00277 LMatrix4 m_ts = ts->get_mat();
00278
00279 if (!m_sync.almost_equal(m_ts)) {
00280 _sync = ts;
00281
00282 btTransform trans = TransformState_to_btTrans(ts);
00283 _rigid->setCenterOfMassTransform(trans);
00284
00285 if (ts->has_scale()) {
00286 LVecBase3 scale = ts->get_scale();
00287 if (!scale.almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
00288 for (int i=0; i<get_num_shapes(); i++) {
00289 PT(BulletShape) shape = _shapes[i];
00290 shape->set_local_scale(scale);
00291 }
00292
00293 shape_changed();
00294 }
00295 }
00296
00297
00298 if (!_rigid->isActive()) {
00299 _rigid->activate(true);
00300 }
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309 void BulletRigidBodyNode::
00310 sync_p2b() {
00311
00312 transform_changed();
00313 }
00314
00315
00316
00317
00318
00319
00320 void BulletRigidBodyNode::
00321 sync_b2p() {
00322
00323 NodePath np = NodePath::any_path((PandaNode *)this);
00324 LVecBase3 scale = np.get_net_transform()->get_scale();
00325
00326 btTransform trans = _rigid->getWorldTransform();
00327 CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
00328
00329 LMatrix4 m_sync = _sync->get_mat();
00330 LMatrix4 m_ts = ts->get_mat();
00331
00332 if (!m_sync.almost_equal(m_ts)) {
00333 _sync = ts;
00334 _sync_disable = true;
00335 np.set_transform(NodePath(), ts);
00336 _sync_disable = false;
00337 }
00338 }
00339
00340
00341
00342
00343
00344
00345 LVector3 BulletRigidBodyNode::
00346 get_linear_velocity() const {
00347
00348 return btVector3_to_LVector3(_rigid->getLinearVelocity());
00349 }
00350
00351
00352
00353
00354
00355
00356 LVector3 BulletRigidBodyNode::
00357 get_angular_velocity() const {
00358
00359 return btVector3_to_LVector3(_rigid->getAngularVelocity());
00360 }
00361
00362
00363
00364
00365
00366
00367 void BulletRigidBodyNode::
00368 set_linear_velocity(const LVector3 &velocity) {
00369
00370 nassertv_always(!velocity.is_nan());
00371
00372 _rigid->setLinearVelocity(LVecBase3_to_btVector3(velocity));
00373 }
00374
00375
00376
00377
00378
00379
00380 void BulletRigidBodyNode::
00381 set_angular_velocity(const LVector3 &velocity) {
00382
00383 nassertv_always(!velocity.is_nan());
00384
00385 _rigid->setAngularVelocity(LVecBase3_to_btVector3(velocity));
00386 }
00387
00388
00389
00390
00391
00392
00393 void BulletRigidBodyNode::
00394 clear_forces() {
00395
00396 _rigid->clearForces();
00397 }
00398
00399
00400
00401
00402
00403
00404 PN_stdfloat BulletRigidBodyNode::
00405 get_linear_sleep_threshold() const {
00406
00407 return _rigid->getLinearSleepingThreshold();
00408 }
00409
00410
00411
00412
00413
00414
00415 PN_stdfloat BulletRigidBodyNode::
00416 get_angular_sleep_threshold() const {
00417
00418 return _rigid->getAngularSleepingThreshold();
00419 }
00420
00421
00422
00423
00424
00425
00426 void BulletRigidBodyNode::
00427 set_linear_sleep_threshold(PN_stdfloat threshold) {
00428
00429 _rigid->setSleepingThresholds(threshold, _rigid->getAngularSleepingThreshold());
00430 }
00431
00432
00433
00434
00435
00436
00437 void BulletRigidBodyNode::
00438 set_angular_sleep_threshold(PN_stdfloat threshold) {
00439
00440 _rigid->setSleepingThresholds(_rigid->getLinearSleepingThreshold(), threshold);
00441 }
00442
00443
00444
00445
00446
00447
00448 void BulletRigidBodyNode::
00449 set_gravity(const LVector3 &gravity) {
00450
00451 nassertv_always(!gravity.is_nan());
00452
00453 _rigid->setGravity(LVecBase3_to_btVector3(gravity));
00454 }
00455
00456
00457
00458
00459
00460
00461 LVector3 BulletRigidBodyNode::
00462 get_gravity() const {
00463
00464 return btVector3_to_LVector3(_rigid->getGravity());
00465 }
00466
00467
00468
00469
00470
00471
00472 void BulletRigidBodyNode::
00473 set_linear_factor(const LVector3 &factor) {
00474
00475 _rigid->setLinearFactor(LVecBase3_to_btVector3(factor));
00476 }
00477
00478
00479
00480
00481
00482
00483 void BulletRigidBodyNode::
00484 set_angular_factor(const LVector3 &factor) {
00485
00486 _rigid->setAngularFactor(LVecBase3_to_btVector3(factor));
00487 }
00488
00489
00490
00491
00492
00493
00494 void BulletRigidBodyNode::MotionState::
00495 getWorldTransform(btTransform &trans) const {
00496
00497 trans = TransformState_to_btTrans(_sync);
00498 }
00499
00500
00501
00502
00503
00504
00505 void BulletRigidBodyNode::MotionState::
00506 setWorldTransform(const btTransform &trans) {
00507
00508 }
00509