summaryrefslogtreecommitdiff
path: root/modules/bullet/rigid_body_bullet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/bullet/rigid_body_bullet.cpp')
-rw-r--r--modules/bullet/rigid_body_bullet.cpp67
1 files changed, 42 insertions, 25 deletions
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 9c0e802be5..d9a77885b3 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -259,27 +259,27 @@ RigidBodyBullet::RigidBodyBullet() :
RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY),
kinematic_utilities(NULL),
locked_axis(0),
- gravity_scale(1),
mass(1),
+ gravity_scale(1),
linearDamp(0),
angularDamp(0),
can_sleep(true),
omit_forces_integration(false),
- force_integration_callback(NULL),
- isTransformChanged(false),
- previousActiveState(true),
maxCollisionsDetection(0),
collisionsCount(0),
maxAreasWhereIam(10),
areaWhereIamCount(0),
countGravityPointSpaces(0),
- isScratchedSpaceOverrideModificator(false) {
+ isScratchedSpaceOverrideModificator(false),
+ isTransformChanged(false),
+ previousActiveState(true),
+ force_integration_callback(NULL) {
godotMotionState = bulletnew(GodotMotionState(this));
// Initial properties
const btVector3 localInertia(0, 0, 0);
- btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, compoundShape, localInertia);
+ btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, BulletPhysicsServer::get_empty_shape(), localInertia);
btBody = bulletnew(btRigidBody(cInfo));
setupBulletCollisionObject(btBody);
@@ -314,10 +314,19 @@ void RigidBodyBullet::destroy_kinematic_utilities() {
}
}
+void RigidBodyBullet::main_shape_resetted() {
+ if (get_main_shape())
+ btBody->setCollisionShape(get_main_shape());
+ else
+ btBody->setCollisionShape(BulletPhysicsServer::get_empty_shape());
+ set_continuous_collision_detection(is_continuous_collision_detection_enabled()); // Reset
+}
+
void RigidBodyBullet::reload_body() {
if (space) {
space->remove_rigid_body(this);
- space->add_rigid_body(this);
+ if (get_main_shape())
+ space->add_rigid_body(this);
}
}
@@ -342,7 +351,7 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) {
void RigidBodyBullet::dispatch_callbacks() {
/// The check isTransformChanged is necessary in order to call integrated forces only when the first transform is sent
- if ((btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && isTransformChanged) {
+ if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && isTransformChanged) {
if (omit_forces_integration)
btBody->clearForces();
@@ -526,20 +535,18 @@ void RigidBodyBullet::set_mode(PhysicsServer::BodyMode p_mode) {
reload_axis_lock();
_internal_set_mass(0);
break;
- case PhysicsServer::BODY_MODE_RIGID: {
+ case PhysicsServer::BODY_MODE_RIGID:
mode = PhysicsServer::BODY_MODE_RIGID;
reload_axis_lock();
_internal_set_mass(0 == mass ? 1 : mass);
scratch_space_override_modificator();
break;
- }
- case PhysicsServer::BODY_MODE_CHARACTER: {
+ case PhysicsServer::BODY_MODE_CHARACTER:
mode = PhysicsServer::BODY_MODE_CHARACTER;
reload_axis_lock();
_internal_set_mass(0 == mass ? 1 : mass);
scratch_space_override_modificator();
break;
- }
}
btBody->setAngularVelocity(btVector3(0, 0, 0));
@@ -711,15 +718,19 @@ void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) {
if (p_enable) {
// This threshold enable CCD if the object moves more than
// 1 meter in one simulation frame
- btBody->setCcdMotionThreshold(1);
+ btBody->setCcdMotionThreshold(0.1);
/// Calculate using the rule writte below the CCD swept sphere radius
/// CCD works on an embedded sphere of radius, make sure this radius
/// is embedded inside the convex objects, preferably smaller:
/// for an object of dimensions 1 meter, try 0.2
- btVector3 center;
btScalar radius;
- btBody->getCollisionShape()->getBoundingSphere(center, radius);
+ if (btBody->getCollisionShape()) {
+ btVector3 center;
+ btBody->getCollisionShape()->getBoundingSphere(center, radius);
+ } else {
+ radius = 0;
+ }
btBody->setCcdSweptSphereRadius(radius * 0.2);
} else {
btBody->setCcdMotionThreshold(0.);
@@ -728,7 +739,7 @@ void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) {
}
bool RigidBodyBullet::is_continuous_collision_detection_enabled() const {
- return 0. != btBody->getCcdMotionThreshold();
+ return 0. < btBody->getCcdMotionThreshold();
}
void RigidBodyBullet::set_linear_velocity(const Vector3 &p_velocity) {
@@ -761,10 +772,13 @@ Vector3 RigidBodyBullet::get_angular_velocity() const {
void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transform) {
if (mode == PhysicsServer::BODY_MODE_KINEMATIC) {
+ if (space)
+ btBody->setLinearVelocity((p_global_transform.getOrigin() - btBody->getWorldTransform().getOrigin()) / space->get_delta_time());
// The kinematic use MotionState class
godotMotionState->moveBody(p_global_transform);
}
btBody->setWorldTransform(p_global_transform);
+ scratch();
}
const btTransform &RigidBodyBullet::get_transform__bullet() const {
@@ -783,9 +797,11 @@ void RigidBodyBullet::on_shapes_changed() {
const btScalar invMass = btBody->getInvMass();
const btScalar mass = invMass == 0 ? 0 : 1 / invMass;
- btVector3 inertia;
- btBody->getCollisionShape()->calculateLocalInertia(mass, inertia);
- btBody->setMassProps(mass, inertia);
+ if (mainShape) {
+ btVector3 inertia;
+ mainShape->calculateLocalInertia(mass, inertia);
+ btBody->setMassProps(mass, inertia);
+ }
btBody->updateInertiaTensor();
reload_kinematic_shapes();
@@ -834,7 +850,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
bool wasTheAreaFound = false;
for (int i = 0; i < areaWhereIamCount; ++i) {
if (p_area == areasWhereIam[i]) {
- // The area was fount, just shift down all elements
+ // The area was found, just shift down all elements
for (int j = i; j < areaWhereIamCount; ++j) {
areasWhereIam.write[j] = areasWhereIam[j + 1];
}
@@ -909,10 +925,10 @@ void RigidBodyBullet::reload_space_override_modificator() {
}
switch (currentArea->get_spOv_mode()) {
- ///case PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED:
- /// This area does not affect gravity/damp. These are generally areas
- /// that exist only to detect collisions, and objects entering or exiting them.
- /// break;
+ case PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED:
+ /// This area does not affect gravity/damp. These are generally areas
+ /// that exist only to detect collisions, and objects entering or exiting them.
+ break;
case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE:
/// This area adds its gravity/damp values to whatever has been
/// calculated so far. This way, many overlapping areas can combine
@@ -986,7 +1002,8 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
return;
m_isStatic = false;
- compoundShape->calculateLocalInertia(p_mass, localInertia);
+ if (mainShape)
+ mainShape->calculateLocalInertia(p_mass, localInertia);
if (PhysicsServer::BODY_MODE_RIGID == mode) {