diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp index f4bb9acbd7b..919c3152d70 100644 --- a/modules/bullet/godot_collision_configuration.cpp +++ b/modules/bullet/godot_collision_configuration.cpp @@ -94,3 +94,59 @@ btCollisionAlgorithmCreateFunc *GodotCollisionConfiguration::getClosestPointsAlg return btDefaultCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(proxyType0, proxyType1); } } + +GodotSoftCollisionConfiguration::GodotSoftCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) : + btSoftBodyRigidBodyCollisionConfiguration(constructionInfo) { + + void *mem = NULL; + + mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::CreateFunc), 16); + m_rayWorldCF = new (mem) GodotRayWorldAlgorithm::CreateFunc(world); + + mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::SwappedCreateFunc), 16); + m_swappedRayWorldCF = new (mem) GodotRayWorldAlgorithm::SwappedCreateFunc(world); +} + +GodotSoftCollisionConfiguration::~GodotSoftCollisionConfiguration() { + m_rayWorldCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree(m_rayWorldCF); + + m_swappedRayWorldCF->~btCollisionAlgorithmCreateFunc(); + btAlignedFree(m_swappedRayWorldCF); +} + +btCollisionAlgorithmCreateFunc *GodotSoftCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) { + + if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { + + // This collision is not supported + return m_emptyCreateFunc; + } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) { + + return m_rayWorldCF; + } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { + + return m_swappedRayWorldCF; + } else { + + return btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0, proxyType1); + } +} + +btCollisionAlgorithmCreateFunc *GodotSoftCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) { + + if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { + + // This collision is not supported + return m_emptyCreateFunc; + } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) { + + return m_rayWorldCF; + } else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) { + + return m_swappedRayWorldCF; + } else { + + return btSoftBodyRigidBodyCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(proxyType0, proxyType1); + } +} diff --git a/modules/bullet/godot_collision_configuration.h b/modules/bullet/godot_collision_configuration.h index 9b30ad0c621..11012c5f6db 100644 --- a/modules/bullet/godot_collision_configuration.h +++ b/modules/bullet/godot_collision_configuration.h @@ -32,6 +32,7 @@ #define GODOT_COLLISION_CONFIGURATION_H #include +#include /** @author AndreaCatania @@ -50,4 +51,16 @@ public: virtual btCollisionAlgorithmCreateFunc *getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1); virtual btCollisionAlgorithmCreateFunc *getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1); }; + +class GodotSoftCollisionConfiguration : public btSoftBodyRigidBodyCollisionConfiguration { + btCollisionAlgorithmCreateFunc *m_rayWorldCF; + btCollisionAlgorithmCreateFunc *m_swappedRayWorldCF; + +public: + GodotSoftCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo = btDefaultCollisionConstructionInfo()); + virtual ~GodotSoftCollisionConfiguration(); + + virtual btCollisionAlgorithmCreateFunc *getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1); + virtual btCollisionAlgorithmCreateFunc *getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1); +}; #endif diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 404cb8e37b4..a4aec25124f 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -577,7 +577,7 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) { } if (p_create_soft_world) { - collisionConfiguration = bulletnew(btSoftBodyRigidBodyCollisionConfiguration); + collisionConfiguration = bulletnew(GodotSoftCollisionConfiguration(static_cast(world_mem))); } else { collisionConfiguration = bulletnew(GodotCollisionConfiguration(static_cast(world_mem))); }