summaryrefslogtreecommitdiff
path: root/modules/bullet
diff options
context:
space:
mode:
Diffstat (limited to 'modules/bullet')
-rw-r--r--modules/bullet/SCsub2
-rw-r--r--modules/bullet/area_bullet.cpp10
-rw-r--r--modules/bullet/area_bullet.h1
-rw-r--r--modules/bullet/btRayShape.cpp2
-rw-r--r--modules/bullet/bullet_physics_server.cpp2
-rw-r--r--modules/bullet/bullet_physics_server.h4
-rw-r--r--modules/bullet/bullet_utilities.h2
-rw-r--r--modules/bullet/collision_object_bullet.cpp57
-rw-r--r--modules/bullet/collision_object_bullet.h19
-rw-r--r--modules/bullet/godot_collision_dispatcher.h2
-rw-r--r--modules/bullet/godot_result_callbacks.cpp8
-rw-r--r--modules/bullet/godot_result_callbacks.h8
-rw-r--r--modules/bullet/register_types.cpp4
-rw-r--r--modules/bullet/rigid_body_bullet.cpp36
-rw-r--r--modules/bullet/rigid_body_bullet.h1
-rw-r--r--modules/bullet/shape_bullet.cpp7
-rw-r--r--modules/bullet/shape_bullet.h2
-rw-r--r--modules/bullet/space_bullet.cpp66
-rw-r--r--modules/bullet/space_bullet.h2
19 files changed, 168 insertions, 67 deletions
diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub
index d8d0b930a5..2557e8cb1d 100644
--- a/modules/bullet/SCsub
+++ b/modules/bullet/SCsub
@@ -68,11 +68,13 @@ if env['builtin_bullet']:
, "BulletCollision/CollisionShapes/btEmptyShape.cpp"
, "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp"
, "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp"
+ , "BulletCollision/CollisionShapes/btMiniSDF.cpp"
, "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp"
, "BulletCollision/CollisionShapes/btMultiSphereShape.cpp"
, "BulletCollision/CollisionShapes/btOptimizedBvh.cpp"
, "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp"
, "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp"
+ , "BulletCollision/CollisionShapes/btSdfCollisionShape.cpp"
, "BulletCollision/CollisionShapes/btShapeHull.cpp"
, "BulletCollision/CollisionShapes/btSphereShape.cpp"
, "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp"
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index 3668088590..3200b4a214 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -30,6 +30,7 @@
#include "area_bullet.h"
+#include "bullet_physics_server.h"
#include "bullet_types_converter.h"
#include "bullet_utilities.h"
#include "collision_object_bullet.h"
@@ -57,7 +58,7 @@ AreaBullet::AreaBullet() :
spOv_priority(0) {
btGhost = bulletnew(btGhostObject);
- btGhost->setCollisionShape(compoundShape);
+ btGhost->setCollisionShape(BulletPhysicsServer::get_empty_shape());
setupBulletCollisionObject(btGhost);
/// Collision objects with a callback still have collision response with dynamic rigid bodies.
/// In order to use collision objects as trigger, you have to disable the collision response.
@@ -162,6 +163,13 @@ bool AreaBullet::is_monitoring() const {
return get_godot_object_flags() & GOF_IS_MONITORING_AREA;
}
+void AreaBullet::main_shape_resetted() {
+ if (get_main_shape())
+ btGhost->setCollisionShape(get_main_shape());
+ else
+ btGhost->setCollisionShape(BulletPhysicsServer::get_empty_shape());
+}
+
void AreaBullet::reload_body() {
if (space) {
space->remove_area(this);
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index b2046c684e..a6bf73906c 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -142,6 +142,7 @@ public:
_FORCE_INLINE_ void set_spOv_priority(int p_priority) { spOv_priority = p_priority; }
_FORCE_INLINE_ int get_spOv_priority() { return spOv_priority; }
+ virtual void main_shape_resetted();
virtual void reload_body();
virtual void set_space(SpaceBullet *p_space);
diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp
index 8707096038..6cc63d79ce 100644
--- a/modules/bullet/btRayShape.cpp
+++ b/modules/bullet/btRayShape.cpp
@@ -30,7 +30,7 @@
#include "btRayShape.h"
-#include "math/math_funcs.h"
+#include "core/math/math_funcs.h"
#include <LinearMath/btAabbUtil2.h>
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index dbd27a3564..53a38967c3 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -31,8 +31,8 @@
#include "bullet_physics_server.h"
#include "bullet_utilities.h"
-#include "class_db.h"
#include "cone_twist_joint_bullet.h"
+#include "core/class_db.h"
#include "core/error_macros.h"
#include "core/ustring.h"
#include "generic_6dof_joint_bullet.h"
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index e9c568d605..4c52cace67 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -32,8 +32,8 @@
#define BULLET_PHYSICS_SERVER_H
#include "area_bullet.h"
+#include "core/rid.h"
#include "joint_bullet.h"
-#include "rid.h"
#include "rigid_body_bullet.h"
#include "servers/physics_server.h"
#include "shape_bullet.h"
@@ -61,7 +61,7 @@ class BulletPhysicsServer : public PhysicsServer {
mutable RID_Owner<JointBullet> joint_owner;
private:
- /// This is used when a collision shape is not active, so the bullet compound shapes index are always sync with godot index
+ /// This is used as replacement of collision shape inside a compound or main shape
static btEmptyShape *emptyShape;
public:
diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h
index 2841dfbe69..029eb6691a 100644
--- a/modules/bullet/bullet_utilities.h
+++ b/modules/bullet/bullet_utilities.h
@@ -35,8 +35,6 @@
@author AndreaCatania
*/
-#pragma once
-
#define bulletnew(cl) \
new cl
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index 271cdb0223..df67f8d7ab 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -53,10 +53,17 @@ void CollisionObjectBullet::ShapeWrapper::set_transform(const Transform &p_trans
G_TO_B(p_transform, transform);
UNSCALE_BT_BASIS(transform);
}
+
void CollisionObjectBullet::ShapeWrapper::set_transform(const btTransform &p_transform) {
transform = p_transform;
}
+void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_scale) {
+ if (!bt_shape) {
+ bt_shape = shape->create_bt_shape(scale * body_scale);
+ }
+}
+
CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
RIDBullet(),
space(NULL),
@@ -107,6 +114,7 @@ void CollisionObjectBullet::setupBulletCollisionObject(btCollisionObject *p_coll
bt_collision_object->setUserIndex(type);
// Force the enabling of collision and avoid problems
set_collision_enabled(collisionsEnabled);
+ p_collisionObject->setCollisionFlags(p_collisionObject->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
}
void CollisionObjectBullet::add_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) {
@@ -186,13 +194,14 @@ const btTransform &CollisionObjectBullet::get_transform__bullet() const {
RigidCollisionObjectBullet::RigidCollisionObjectBullet(Type p_type) :
CollisionObjectBullet(p_type),
- compoundShape(bulletnew(btCompoundShape(enableDynamicAabbTree, initialChildCapacity))) {
+ mainShape(NULL) {
}
RigidCollisionObjectBullet::~RigidCollisionObjectBullet() {
remove_all_shapes(true);
- bt_collision_object->setCollisionShape(NULL);
- bulletdelete(compoundShape);
+ if (mainShape && mainShape->isCompound()) {
+ bulletdelete(mainShape);
+ }
}
/* Not used
@@ -277,6 +286,10 @@ btCollisionShape *RigidCollisionObjectBullet::get_bt_shape(int p_index) const {
return shapes[p_index].bt_shape;
}
+const btTransform &RigidCollisionObjectBullet::get_bt_shape_transform(int p_index) const {
+ return shapes[p_index].transform;
+}
+
Transform RigidCollisionObjectBullet::get_shape_transform(int p_index) const {
Transform trs;
B_TO_G(shapes[p_index].transform, trs);
@@ -294,33 +307,47 @@ void RigidCollisionObjectBullet::on_shape_changed(const ShapeBullet *const p_sha
}
void RigidCollisionObjectBullet::on_shapes_changed() {
- int i;
- // Remove all shapes, reverse order for performance reason (Array resize)
- for (i = compoundShape->getNumChildShapes() - 1; 0 <= i; --i) {
- compoundShape->removeChildShapeByIndex(i);
+ if (mainShape && mainShape->isCompound()) {
+ bulletdelete(mainShape);
}
+ mainShape = NULL;
ShapeWrapper *shpWrapper;
- const int shapes_size = shapes.size();
+ const int shape_count = shapes.size();
// Reset shape if required
if (force_shape_reset) {
- for (i = 0; i < shapes_size; ++i) {
+ for (int i(0); i < shape_count; ++i) {
shpWrapper = &shapes.write[i];
bulletdelete(shpWrapper->bt_shape);
}
force_shape_reset = false;
}
- // Insert all shapes
btVector3 body_scale(get_bt_body_scale());
- for (i = 0; i < shapes_size; ++i) {
+
+ if (!shape_count)
+ return;
+
+ // Try to optimize by not using compound
+ if (1 == shape_count) {
+ shpWrapper = &shapes.write[0];
+ if (shpWrapper->active && shpWrapper->transform.getOrigin().isZero() && shpWrapper->transform.getBasis() == shpWrapper->transform.getBasis().getIdentity()) {
+ shpWrapper->claim_bt_shape(body_scale);
+ mainShape = shpWrapper->bt_shape;
+ main_shape_resetted();
+ return;
+ }
+ }
+
+ btCompoundShape *compoundShape = bulletnew(btCompoundShape(enableDynamicAabbTree, initialChildCapacity));
+
+ // Insert all shapes into compound
+ for (int i(0); i < shape_count; ++i) {
shpWrapper = &shapes.write[i];
if (shpWrapper->active) {
- if (!shpWrapper->bt_shape) {
- shpWrapper->bt_shape = shpWrapper->shape->create_bt_shape(shpWrapper->scale * body_scale);
- }
+ shpWrapper->claim_bt_shape(body_scale);
btTransform scaled_shape_transform(shpWrapper->transform);
scaled_shape_transform.getOrigin() *= body_scale;
@@ -331,6 +358,8 @@ void RigidCollisionObjectBullet::on_shapes_changed() {
}
compoundShape->recalculateLocalAabb();
+ mainShape = compoundShape;
+ main_shape_resetted();
}
void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) {
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
index 506976eabf..ea06cecb17 100644
--- a/modules/bullet/collision_object_bullet.h
+++ b/modules/bullet/collision_object_bullet.h
@@ -31,11 +31,11 @@
#ifndef COLLISION_OBJECT_BULLET_H
#define COLLISION_OBJECT_BULLET_H
+#include "core/math/transform.h"
+#include "core/math/vector3.h"
+#include "core/object.h"
#include "core/vset.h"
-#include "object.h"
#include "shape_owner_bullet.h"
-#include "transform.h"
-#include "vector3.h"
#include <LinearMath/btTransform.h>
@@ -109,6 +109,8 @@ public:
void set_transform(const Transform &p_transform);
void set_transform(const btTransform &p_transform);
+
+ void claim_bt_shape(const btVector3 &body_scale);
};
protected:
@@ -207,10 +209,8 @@ public:
class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet {
protected:
- /// This is required to combine some shapes together.
- /// Since Godot allow to have multiple shapes for each body with custom relative location,
- /// each body will attach the shapes using this class even if there is only one shape.
- btCompoundShape *compoundShape;
+ /// This could be a compound shape in case multi please collision are found
+ btCollisionShape *mainShape;
Vector<ShapeWrapper> shapes;
public:
@@ -231,15 +231,18 @@ public:
virtual void on_shape_changed(const ShapeBullet *const p_shape);
virtual void on_shapes_changed();
- _FORCE_INLINE_ btCompoundShape *get_compound_shape() const { return compoundShape; }
+ _FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; }
+
int get_shape_count() const;
ShapeBullet *get_shape(int p_index) const;
btCollisionShape *get_bt_shape(int p_index) const;
+ const btTransform &get_bt_shape_transform(int p_index) const;
Transform get_shape_transform(int p_index) const;
void set_shape_disabled(int p_index, bool p_disabled);
bool is_shape_disabled(int p_index);
+ virtual void main_shape_resetted() = 0;
virtual void on_body_scale_changed();
private:
diff --git a/modules/bullet/godot_collision_dispatcher.h b/modules/bullet/godot_collision_dispatcher.h
index 2e5a6c2732..1faaa68626 100644
--- a/modules/bullet/godot_collision_dispatcher.h
+++ b/modules/bullet/godot_collision_dispatcher.h
@@ -31,7 +31,7 @@
#ifndef GODOT_COLLISION_DISPATCHER_H
#define GODOT_COLLISION_DISPATCHER_H
-#include "int_types.h"
+#include "core/int_types.h"
#include <btBulletDynamicsCommon.h>
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 534034d707..08d8b8c6f6 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -34,11 +34,19 @@
#include "bullet_types_converter.h"
#include "collision_object_bullet.h"
#include "rigid_body_bullet.h"
+#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
/**
@author AndreaCatania
*/
+bool godotContactAddedCallback(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {
+ if (!colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound()) {
+ btAdjustInternalEdgeContacts(cp, colObj1Wrap, colObj0Wrap, partId1, index1);
+ }
+ return true;
+}
+
bool GodotFilterCallback::test_collision_filters(uint32_t body0_collision_layer, uint32_t body0_collision_mask, uint32_t body1_collision_layer, uint32_t body1_collision_mask) {
return body0_collision_layer & body1_collision_mask || body1_collision_layer & body0_collision_mask;
}
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 3948f43c00..8e70b72841 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -42,6 +42,9 @@
class RigidBodyBullet;
+/// This callback is injected inside bullet server and allow me to smooth contacts against trimesh
+bool godotContactAddedCallback(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1);
+
/// This class is required to implement custom collision behaviour in the broadphase
struct GodotFilterCallback : public btOverlapFilterCallback {
static bool test_collision_filters(uint32_t body0_collision_layer, uint32_t body0_collision_mask, uint32_t body1_collision_layer, uint32_t body1_collision_mask);
@@ -71,7 +74,10 @@ public:
virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) {
- m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ if (rayResult.m_localShapeInfo)
+ m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ else
+ m_shapeId = 0;
return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
}
};
diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp
index a76b0438b4..31e5f6784e 100644
--- a/modules/bullet/register_types.cpp
+++ b/modules/bullet/register_types.cpp
@@ -31,8 +31,8 @@
#include "register_types.h"
#include "bullet_physics_server.h"
-#include "class_db.h"
-#include "project_settings.h"
+#include "core/class_db.h"
+#include "core/project_settings.h"
/**
@author AndreaCatania
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 9c0e802be5..2d0e74eb6f 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -279,7 +279,7 @@ RigidBodyBullet::RigidBodyBullet() :
// 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);
}
}
@@ -711,15 +720,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 +741,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) {
@@ -783,9 +796,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();
@@ -986,7 +1001,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) {
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index f03009bce9..cd2f215906 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -231,6 +231,7 @@ public:
_FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; }
+ virtual void main_shape_resetted();
virtual void reload_body();
virtual void set_space(SpaceBullet *p_space);
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index cc7d106496..4a2263407c 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -36,6 +36,7 @@
#include "bullet_utilities.h"
#include "shape_owner_bullet.h"
+#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
#include <BulletCollision/CollisionShapes/btConvexPointCloudShape.h>
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
#include <btBulletCollisionCommon.h>
@@ -358,7 +359,8 @@ ConcavePolygonShapeBullet::ConcavePolygonShapeBullet() :
ConcavePolygonShapeBullet::~ConcavePolygonShapeBullet() {
if (meshShape) {
delete meshShape->getMeshInterface();
- delete meshShape;
+ delete meshShape->getTriangleInfoMap();
+ bulletdelete(meshShape);
}
faces = PoolVector<Vector3>();
}
@@ -380,6 +382,7 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
if (meshShape) {
/// Clear previous created shape
delete meshShape->getMeshInterface();
+ delete meshShape->getTriangleInfoMap();
bulletdelete(meshShape);
}
int src_face_count = faces.size();
@@ -407,6 +410,8 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
const bool useQuantizedAabbCompression = true;
meshShape = bulletnew(btBvhTriangleMeshShape(shapeInterface, useQuantizedAabbCompression));
+ btTriangleInfoMap *triangleInfoMap = new btTriangleInfoMap();
+ btGenerateInternalEdgeInfo(meshShape, triangleInfoMap);
} else {
meshShape = NULL;
ERR_PRINT("The faces count are 0, the mesh shape cannot be created");
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
index 638e044e6a..9a1c8f5bfa 100644
--- a/modules/bullet/shape_bullet.h
+++ b/modules/bullet/shape_bullet.h
@@ -31,8 +31,8 @@
#ifndef SHAPE_BULLET_H
#define SHAPE_BULLET_H
+#include "core/math/geometry.h"
#include "core/variant.h"
-#include "geometry.h"
#include "rid_bullet.h"
#include "servers/physics_server.h"
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index b12925b073..5b220e1039 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -34,13 +34,13 @@
#include "bullet_types_converter.h"
#include "bullet_utilities.h"
#include "constraint_bullet.h"
+#include "core/project_settings.h"
+#include "core/ustring.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"
-#include "ustring.h"
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
@@ -295,11 +295,10 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_
bool shapes_found = false;
- btCompoundShape *compound = rigid_object->get_compound_shape();
- for (int i = compound->getNumChildShapes() - 1; 0 <= i; --i) {
- shape = compound->getChildShape(i);
+ for (int i = rigid_object->get_shape_count() - 1; 0 <= i; --i) {
+ shape = rigid_object->get_bt_shape(i);
if (shape->isConvex()) {
- child_transform = compound->getChildTransform(i);
+ child_transform = rigid_object->get_bt_shape_transform(i);
convex_shape = static_cast<btConvexShape *>(shape);
input.m_transformB = body_transform * child_transform;
@@ -598,6 +597,7 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
godotFilterCallback = bulletnew(GodotFilterCallback);
gCalculateCombinedRestitutionCallback = &calculateGodotCombinedRestitution;
gCalculateCombinedFrictionCallback = &calculateGodotCombinedFriction;
+ gContactAddedCallback = &godotContactAddedCallback;
dynamicsWorld->setWorldUserInfo(this);
@@ -642,7 +642,7 @@ void SpaceBullet::destroy_world() {
void SpaceBullet::check_ghost_overlaps() {
/// Algorithm support variables
- btConvexShape *other_body_shape;
+ btCollisionShape *other_body_shape;
btConvexShape *area_shape;
btGjkPairDetector::ClosestPointInput gjk_input;
AreaBullet *area;
@@ -684,30 +684,52 @@ void SpaceBullet::check_ghost_overlaps() {
bool hasOverlap = false;
// For each area shape
- for (y = area->get_compound_shape()->getNumChildShapes() - 1; 0 <= y; --y) {
- if (!area->get_compound_shape()->getChildShape(y)->isConvex())
+ for (y = area->get_shape_count() - 1; 0 <= y; --y) {
+ if (!area->get_bt_shape(y)->isConvex())
continue;
- gjk_input.m_transformA = area->get_transform__bullet() * area->get_compound_shape()->getChildTransform(y);
- area_shape = static_cast<btConvexShape *>(area->get_compound_shape()->getChildShape(y));
+ gjk_input.m_transformA = area->get_transform__bullet() * area->get_bt_shape_transform(y);
+ area_shape = static_cast<btConvexShape *>(area->get_bt_shape(y));
// For each other object shape
- for (z = otherObject->get_compound_shape()->getNumChildShapes() - 1; 0 <= z; --z) {
+ for (z = otherObject->get_shape_count() - 1; 0 <= z; --z) {
- if (!otherObject->get_compound_shape()->getChildShape(z)->isConvex())
- continue;
+ other_body_shape = static_cast<btCollisionShape *>(otherObject->get_bt_shape(z));
+ gjk_input.m_transformB = otherObject->get_transform__bullet() * otherObject->get_bt_shape_transform(z);
- other_body_shape = static_cast<btConvexShape *>(otherObject->get_compound_shape()->getChildShape(z));
- gjk_input.m_transformB = otherObject->get_transform__bullet() * otherObject->get_compound_shape()->getChildTransform(z);
+ if (other_body_shape->isConvex()) {
- btPointCollector result;
- btGjkPairDetector gjk_pair_detector(area_shape, other_body_shape, gjk_simplex_solver, gjk_epa_pen_solver);
- gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
+ btPointCollector result;
+ btGjkPairDetector gjk_pair_detector(area_shape, static_cast<btConvexShape *>(other_body_shape), gjk_simplex_solver, gjk_epa_pen_solver);
+ gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
- if (0 >= result.m_distance) {
- hasOverlap = true;
- goto collision_found;
+ if (0 >= result.m_distance) {
+ hasOverlap = true;
+ goto collision_found;
+ }
+
+ } else {
+
+ btCollisionObjectWrapper obA(NULL, area_shape, area->get_bt_ghost(), gjk_input.m_transformA, -1, y);
+ btCollisionObjectWrapper obB(NULL, other_body_shape, otherObject->get_bt_collision_object(), gjk_input.m_transformB, -1, z);
+
+ btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CONTACT_POINT_ALGORITHMS);
+
+ if (!algorithm)
+ continue;
+
+ GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB);
+ algorithm->processCollision(&obA, &obB, dynamicsWorld->getDispatchInfo(), &contactPointResult);
+
+ algorithm->~btCollisionAlgorithm();
+ dispatcher->freeCollisionAlgorithm(algorithm);
+
+ if (contactPointResult.hasHit()) {
+ hasOverlap = true;
+ goto collision_found;
+ }
}
+
} // ~For each other object shape
} // ~For each area shape
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index 517ec67ffa..0649e1f7e3 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -65,6 +65,8 @@ class SpaceBullet;
class SoftBodyBullet;
class btGjkEpaPenetrationDepthSolver;
+extern ContactAddedCallback gContactAddedCallback;
+
class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState {
GDCLASS(BulletPhysicsDirectSpaceState, PhysicsDirectSpaceState)
private: