summaryrefslogtreecommitdiff
path: root/modules/bullet/space_bullet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/bullet/space_bullet.cpp')
-rw-r--r--modules/bullet/space_bullet.cpp47
1 files changed, 44 insertions, 3 deletions
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 971fd39509..132c3739d6 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -36,6 +36,7 @@
#include "constraint_bullet.h"
#include "godot_collision_configuration.h"
#include "godot_collision_dispatcher.h"
+#include "project_settings.h"
#include "rigid_body_bullet.h"
#include "servers/physics_server.h"
#include "soft_body_bullet.h"
@@ -325,7 +326,7 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_
}
}
-SpaceBullet::SpaceBullet(bool p_create_soft_world) :
+SpaceBullet::SpaceBullet() :
broadphase(NULL),
dispatcher(NULL),
solver(NULL),
@@ -338,7 +339,7 @@ SpaceBullet::SpaceBullet(bool p_create_soft_world) :
gravityMagnitude(10),
contactDebugCount(0) {
- create_empty_world(p_create_soft_world);
+ create_empty_world(GLOBAL_DEF("physics/3d/active_soft_world", true));
direct_access = memnew(BulletPhysicsDirectSpaceState(this));
}
@@ -355,6 +356,7 @@ void SpaceBullet::flush_queries() {
}
void SpaceBullet::step(real_t p_delta_time) {
+ delta_time = p_delta_time;
dynamicsWorld->stepSimulation(p_delta_time, 0, 0);
}
@@ -483,6 +485,7 @@ void SpaceBullet::reload_collision_filters(RigidBodyBullet *p_body) {
void SpaceBullet::add_soft_body(SoftBodyBullet *p_body) {
if (is_using_soft_world()) {
if (p_body->get_bt_soft_body()) {
+ p_body->get_bt_soft_body()->m_worldInfo = get_soft_body_world_info();
static_cast<btSoftRigidDynamicsWorld *>(dynamicsWorld)->addSoftBody(p_body->get_bt_soft_body(), p_body->get_collision_layer(), p_body->get_collision_mask());
}
} else {
@@ -494,6 +497,7 @@ void SpaceBullet::remove_soft_body(SoftBodyBullet *p_body) {
if (is_using_soft_world()) {
if (p_body->get_bt_soft_body()) {
static_cast<btSoftRigidDynamicsWorld *>(dynamicsWorld)->removeSoftBody(p_body->get_bt_soft_body());
+ p_body->get_bt_soft_body()->m_worldInfo = NULL;
}
}
}
@@ -549,7 +553,43 @@ BulletPhysicsDirectSpaceState *SpaceBullet::get_direct_state() {
}
btScalar calculateGodotCombinedRestitution(const btCollisionObject *body0, const btCollisionObject *body1) {
- return MAX(body0->getRestitution(), body1->getRestitution());
+
+ const PhysicsServer::CombineMode cm = static_cast<RigidBodyBullet *>(body0->getUserPointer())->get_restitution_combine_mode();
+
+ switch (cm) {
+ case PhysicsServer::COMBINE_MODE_INHERIT:
+ if (static_cast<RigidBodyBullet *>(body1->getUserPointer())->get_restitution_combine_mode() != PhysicsServer::COMBINE_MODE_INHERIT)
+ return calculateGodotCombinedRestitution(body1, body0);
+ // else use MAX [This is used when the two bodies doesn't use physical material]
+ case PhysicsServer::COMBINE_MODE_MAX:
+ return MAX(body0->getRestitution(), body1->getRestitution());
+ case PhysicsServer::COMBINE_MODE_MIN:
+ return MIN(body0->getRestitution(), body1->getRestitution());
+ case PhysicsServer::COMBINE_MODE_MULTIPLY:
+ return body0->getRestitution() * body1->getRestitution();
+ default: // Is always PhysicsServer::COMBINE_MODE_AVERAGE:
+ return (body0->getRestitution() + body1->getRestitution()) / 2;
+ }
+}
+
+btScalar calculateGodotCombinedFriction(const btCollisionObject *body0, const btCollisionObject *body1) {
+
+ const PhysicsServer::CombineMode cm = static_cast<RigidBodyBullet *>(body0->getUserPointer())->get_friction_combine_mode();
+
+ switch (cm) {
+ case PhysicsServer::COMBINE_MODE_INHERIT:
+ if (static_cast<RigidBodyBullet *>(body1->getUserPointer())->get_friction_combine_mode() != PhysicsServer::COMBINE_MODE_INHERIT)
+ return calculateGodotCombinedFriction(body1, body0);
+ // else use MULTIPLY [This is used when the two bodies doesn't use physical material]
+ case PhysicsServer::COMBINE_MODE_MULTIPLY:
+ return body0->getFriction() * body1->getFriction();
+ case PhysicsServer::COMBINE_MODE_MAX:
+ return MAX(body0->getFriction(), body1->getFriction());
+ case PhysicsServer::COMBINE_MODE_MIN:
+ return MIN(body0->getFriction(), body1->getFriction());
+ default: // Is always PhysicsServer::COMBINE_MODE_AVERAGE:
+ return (body0->getFriction() * body1->getFriction()) / 2;
+ }
}
void SpaceBullet::create_empty_world(bool p_create_soft_world) {
@@ -585,6 +625,7 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
ghostPairCallback = bulletnew(btGhostPairCallback);
godotFilterCallback = bulletnew(GodotFilterCallback);
gCalculateCombinedRestitutionCallback = &calculateGodotCombinedRestitution;
+ gCalculateCombinedFrictionCallback = &calculateGodotCombinedFriction;
dynamicsWorld->setWorldUserInfo(this);