diff options
Diffstat (limited to 'modules/bullet')
-rw-r--r-- | modules/bullet/btRayShape.cpp | 5 | ||||
-rw-r--r-- | modules/bullet/btRayShape.h | 4 | ||||
-rw-r--r-- | modules/bullet/bullet_physics_server.cpp | 29 | ||||
-rw-r--r-- | modules/bullet/bullet_physics_server.h | 4 | ||||
-rw-r--r-- | modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml | 2 | ||||
-rw-r--r-- | modules/bullet/doc_classes/BulletPhysicsServer.xml | 2 | ||||
-rw-r--r-- | modules/bullet/godot_motion_state.h | 2 | ||||
-rw-r--r-- | modules/bullet/godot_ray_world_algorithm.cpp | 8 | ||||
-rw-r--r-- | modules/bullet/godot_result_callbacks.cpp | 30 | ||||
-rw-r--r-- | modules/bullet/godot_result_callbacks.h | 13 | ||||
-rw-r--r-- | modules/bullet/rigid_body_bullet.cpp | 16 | ||||
-rw-r--r-- | modules/bullet/rigid_body_bullet.h | 6 | ||||
-rw-r--r-- | modules/bullet/shape_bullet.cpp | 24 | ||||
-rw-r--r-- | modules/bullet/shape_bullet.h | 5 | ||||
-rw-r--r-- | modules/bullet/space_bullet.cpp | 49 | ||||
-rw-r--r-- | modules/bullet/space_bullet.h | 4 |
16 files changed, 113 insertions, 90 deletions
diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp index 4164450cd2..8707096038 100644 --- a/modules/bullet/btRayShape.cpp +++ b/modules/bullet/btRayShape.cpp @@ -54,6 +54,11 @@ void btRayShape::setLength(btScalar p_length) { reload_cache(); } +void btRayShape::setSlipsOnSlope(bool p_slipsOnSlope) { + + slipsOnSlope = p_slipsOnSlope; +} + btVector3 btRayShape::localGetSupportingVertex(const btVector3 &vec) const { return localGetSupportingVertexWithoutMargin(vec) + (m_shapeAxis * m_collisionMargin); } diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h index 99a9412dbe..a44c30db4b 100644 --- a/modules/bullet/btRayShape.h +++ b/modules/bullet/btRayShape.h @@ -44,6 +44,7 @@ ATTRIBUTE_ALIGNED16(class) btRayShape : public btConvexInternalShape { btScalar m_length; + bool slipsOnSlope; /// The default axis is the z btVector3 m_shapeAxis; @@ -59,6 +60,9 @@ public: void setLength(btScalar p_length); btScalar getLength() const { return m_length; } + void setSlipsOnSlope(bool p_slipOnSlope); + bool getSlipsOnSlope() const { return slipsOnSlope; } + const btTransform &getSupportPoint() const { return m_cacheSupportPoint; } const btScalar &getScaledLength() const { return m_cacheScaledLength; } diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index b646fc164d..4a0c7499b4 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -619,11 +619,11 @@ uint32_t BulletPhysicsServer::body_get_collision_mask(RID p_body) const { } void BulletPhysicsServer::body_set_user_flags(RID p_body, uint32_t p_flags) { - WARN_PRINT("This function si not currently supported by bullet and Godot"); + // This function si not currently supported } uint32_t BulletPhysicsServer::body_get_user_flags(RID p_body) const { - WARN_PRINT("This function si not currently supported by bullet and Godot"); + // This function si not currently supported return 0; } @@ -783,22 +783,27 @@ int BulletPhysicsServer::body_get_max_contacts_reported(RID p_body) const { return body->get_max_collisions_detection(); } -void BulletPhysicsServer::body_set_contacts_reported_depth_threshold(RID p_body, float p_treshold) { - WARN_PRINT("Not supported by bullet and even Godot"); +void BulletPhysicsServer::body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) { + // Not supported by bullet and even Godot } float BulletPhysicsServer::body_get_contacts_reported_depth_threshold(RID p_body) const { - WARN_PRINT("Not supported by bullet and even Godot"); + // Not supported by bullet and even Godot return 0.; } void BulletPhysicsServer::body_set_omit_force_integration(RID p_body, bool p_omit) { - WARN_PRINT("Not supported by bullet"); + RigidBodyBullet *body = rigid_body_owner.get(p_body); + ERR_FAIL_COND(!body); + + body->set_omit_forces_integration(p_omit); } bool BulletPhysicsServer::body_is_omitting_force_integration(RID p_body) const { - WARN_PRINT("Not supported by bullet"); - return false; + RigidBodyBullet *body = rigid_body_owner.get(p_body); + ERR_FAIL_COND_V(!body, false); + + return body->get_omit_forces_integration(); } void BulletPhysicsServer::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) { @@ -825,12 +830,12 @@ PhysicsDirectBodyState *BulletPhysicsServer::body_get_direct_state(RID p_body) { return BulletPhysicsDirectBodyState::get_singleton(body); } -bool BulletPhysicsServer::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result) { +bool BulletPhysicsServer::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result) { RigidBodyBullet *body = rigid_body_owner.get(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); - return body->get_space()->test_body_motion(body, p_from, p_motion, r_result); + return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, r_result); } RID BulletPhysicsServer::soft_body_create(bool p_init_sleeping) { @@ -979,11 +984,11 @@ PhysicsServer::JointType BulletPhysicsServer::joint_get_type(RID p_joint) const } void BulletPhysicsServer::joint_set_solver_priority(RID p_joint, int p_priority) { - //WARN_PRINTS("Joint priority not supported by bullet"); + // Joint priority not supported by bullet } int BulletPhysicsServer::joint_get_solver_priority(RID p_joint) const { - //WARN_PRINTS("Joint priority not supported by bullet"); + // Joint priority not supported by bullet return 0; } diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 764ec2387c..e931915bba 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -239,7 +239,7 @@ public: virtual void body_set_max_contacts_reported(RID p_body, int p_contacts); virtual int body_get_max_contacts_reported(RID p_body) const; - virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_treshold); + virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold); virtual float body_get_contacts_reported_depth_threshold(RID p_body) const; virtual void body_set_omit_force_integration(RID p_body, bool p_omit); @@ -253,7 +253,7 @@ public: // this function only works on physics process, errors and returns null otherwise virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body); - virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result = NULL); + virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL); /* SOFT BODY API */ diff --git a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml index c7909c7d72..a4dc61d0bc 100644 --- a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml +++ b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BulletPhysicsDirectBodyState" inherits="PhysicsDirectBodyState" category="Core" version="3.0-stable"> +<class name="BulletPhysicsDirectBodyState" inherits="PhysicsDirectBodyState" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/bullet/doc_classes/BulletPhysicsServer.xml b/modules/bullet/doc_classes/BulletPhysicsServer.xml index a59abb0ebb..1486936cf4 100644 --- a/modules/bullet/doc_classes/BulletPhysicsServer.xml +++ b/modules/bullet/doc_classes/BulletPhysicsServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BulletPhysicsServer" inherits="PhysicsServer" category="Core" version="3.0-stable"> +<class name="BulletPhysicsServer" inherits="PhysicsServer" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h index fe5d8418b7..fa58e86589 100644 --- a/modules/bullet/godot_motion_state.h +++ b/modules/bullet/godot_motion_state.h @@ -87,7 +87,7 @@ public: public: /// Use this function to move kinematic body - /// -- or set initial transfom before body creation. + /// -- or set initial transform before body creation. void moveBody(const btTransform &newWorldTransform) { bodyKinematicWorldTransf = newWorldTransform; } diff --git a/modules/bullet/godot_ray_world_algorithm.cpp b/modules/bullet/godot_ray_world_algorithm.cpp index 4a511b39a7..53d0ab7e3c 100644 --- a/modules/bullet/godot_ray_world_algorithm.cpp +++ b/modules/bullet/godot_ray_world_algorithm.cpp @@ -100,14 +100,16 @@ void GodotRayWorldAlgorithm::processCollision(const btCollisionObjectWrapper *bo if (btResult.hasHit()) { - btVector3 ray_normal(ray_transform.getOrigin() - to.getOrigin()); - ray_normal.normalize(); btScalar depth(ray_shape->getScaledLength() * (btResult.m_closestHitFraction - 1)); if (depth >= -RAY_STABILITY_MARGIN) depth = 0; - resultOut->addContactPoint(ray_normal, btResult.m_hitPointWorld, depth); + if (ray_shape->getSlipsOnSlope()) + resultOut->addContactPoint(btResult.m_hitNormalWorld, btResult.m_hitPointWorld, depth); + else { + resultOut->addContactPoint((ray_transform.getOrigin() - to.getOrigin()).normalize(), btResult.m_hitPointWorld, depth); + } } } diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index 8d4ca6d6a7..72c982bb0b 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -98,11 +98,16 @@ bool GodotKinClosestConvexResultCallback::needsCollision(btBroadphaseProxy *prox if (gObj == m_self_object) { return false; } else { - if (m_ignore_areas && gObj->getType() == CollisionObjectBullet::TYPE_AREA) { + + // A kinematic body can't be stopped by a rigid body since the mass of kinematic body is infinite + if (m_infinite_inertia && !btObj->isStaticOrKinematicObject()) return false; - } else if (m_self_object->has_collision_exception(gObj)) { + + if (gObj->getType() == CollisionObjectBullet::TYPE_AREA) + return false; + + if (m_self_object->has_collision_exception(gObj)) return false; - } } return true; } else { @@ -252,18 +257,15 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth) { - if (depth < 0) { - // Has penetration - if (m_most_penetrated_distance > depth) { + // Has penetration + if (m_penetration_distance < ABS(depth)) { - bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); + bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); - m_most_penetrated_distance = depth; - m_pointCollisionObject = (isSwapped ? m_body0Wrap : m_body1Wrap)->getCollisionObject(); - m_other_compound_shape_index = isSwapped ? m_index1 : m_index0; - m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld; - m_pointWorld = isSwapped ? (pointInWorldOnB + normalOnBInWorld * depth) : pointInWorldOnB; - m_penetration_distance = depth; - } + m_penetration_distance = depth; + m_pointCollisionObject = (isSwapped ? m_body0Wrap : m_body1Wrap)->getCollisionObject(); + m_other_compound_shape_index = isSwapped ? m_index1 : m_index0; + m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld; + m_pointWorld = isSwapped ? (pointInWorldOnB + normalOnBInWorld * depth) : pointInWorldOnB; } } diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index e1b0b1b421..60493d4788 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -93,12 +93,12 @@ public: struct GodotKinClosestConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { public: const RigidBodyBullet *m_self_object; - const bool m_ignore_areas; + const bool m_infinite_inertia; - GodotKinClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const RigidBodyBullet *p_self_object, bool p_ignore_areas) : + GodotKinClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const RigidBodyBullet *p_self_object, bool p_infinite_inertia) : btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), m_self_object(p_self_object), - m_ignore_areas(p_ignore_areas) {} + m_infinite_inertia(p_infinite_inertia) {} virtual bool needsCollision(btBroadphaseProxy *proxy0) const; }; @@ -187,18 +187,15 @@ struct GodotDeepPenetrationContactResultCallback : public btManifoldResult { int m_other_compound_shape_index; const btCollisionObject *m_pointCollisionObject; - btScalar m_most_penetrated_distance; - GodotDeepPenetrationContactResultCallback(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap) : btManifoldResult(body0Wrap, body1Wrap), m_pointCollisionObject(NULL), m_penetration_distance(0), - m_other_compound_shape_index(0), - m_most_penetrated_distance(1e20) {} + m_other_compound_shape_index(0) {} void reset() { m_pointCollisionObject = NULL; - m_most_penetrated_distance = 1e20; + m_penetration_distance = 0; } bool hasHit() { diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index f96218ef46..2494063c22 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -114,10 +114,18 @@ Transform BulletPhysicsDirectBodyState::get_transform() const { return body->get_transform(); } +void BulletPhysicsDirectBodyState::add_central_force(const Vector3 &p_force) { + body->apply_central_force(p_force); +} + void BulletPhysicsDirectBodyState::add_force(const Vector3 &p_force, const Vector3 &p_pos) { body->apply_force(p_force, p_pos); } +void BulletPhysicsDirectBodyState::add_torque(const Vector3 &p_torque) { + body->apply_torque(p_torque); +} + void BulletPhysicsDirectBodyState::apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) { body->apply_impulse(p_pos, p_j); } @@ -247,6 +255,7 @@ RigidBodyBullet::RigidBodyBullet() : linearDamp(0), angularDamp(0), can_sleep(true), + omit_forces_integration(false), force_integration_callback(NULL), isTransformChanged(false), previousActiveState(true), @@ -326,6 +335,9 @@ 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 (omit_forces_integration) + btBody->clearForces(); + BulletPhysicsDirectBodyState *bodyDirect = BulletPhysicsDirectBodyState::get_singleton(this); Variant variantBodyDirect = bodyDirect; @@ -429,6 +441,10 @@ bool RigidBodyBullet::is_active() const { return btBody->isActive(); } +void RigidBodyBullet::set_omit_forces_integration(bool p_omit) { + omit_forces_integration = p_omit; +} + void RigidBodyBullet::set_param(PhysicsServer::BodyParameter p_param, real_t p_value) { switch (p_param) { case PhysicsServer::BODY_PARAM_BOUNCE: diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index c4a9676bdd..b9511243c7 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -110,7 +110,9 @@ public: virtual void set_transform(const Transform &p_transform); virtual Transform get_transform() const; + virtual void add_central_force(const Vector3 &p_force); virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos); + virtual void add_torque(const Vector3 &p_torque); virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j); virtual void apply_torque_impulse(const Vector3 &p_j); @@ -196,6 +198,7 @@ private: real_t linearDamp; real_t angularDamp; bool can_sleep; + bool omit_forces_integration; Vector<CollisionData> collisions; // these parameters are used to avoid vector resize @@ -252,6 +255,9 @@ public: void set_activation_state(bool p_active); bool is_active() const; + void set_omit_forces_integration(bool p_omit); + _FORCE_INLINE_ bool get_omit_forces_integration() const { return omit_forces_integration; } + void set_param(PhysicsServer::BodyParameter p_param, real_t); real_t get_param(PhysicsServer::BodyParameter p_param) const; diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index c6b9695d96..5d8d391bd9 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -135,8 +135,10 @@ btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(PoolVector<rea return bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, -fieldHeight, fieldHeight, YAxis, PHY_FLOAT, flipQuadEdges)); } -btRayShape *ShapeBullet::create_shape_ray(real_t p_length) { - return bulletnew(btRayShape(p_length)); +btRayShape *ShapeBullet::create_shape_ray(real_t p_length, bool p_slips_on_slope) { + btRayShape *r(bulletnew(btRayShape(p_length))); + r->setSlipsOnSlope(p_slips_on_slope); + return r; } /* PLANE */ @@ -435,25 +437,33 @@ btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_impli /* Ray shape */ RayShapeBullet::RayShapeBullet() : ShapeBullet(), - length(1) {} + length(1), + slips_on_slope(false) {} void RayShapeBullet::set_data(const Variant &p_data) { - setup(p_data); + + Dictionary d = p_data; + setup(d["length"], d["slips_on_slope"]); } Variant RayShapeBullet::get_data() const { - return length; + + Dictionary d; + d["length"] = length; + d["slips_on_slope"] = slips_on_slope; + return d; } PhysicsServer::ShapeType RayShapeBullet::get_type() const { return PhysicsServer::SHAPE_RAY; } -void RayShapeBullet::setup(real_t p_length) { +void RayShapeBullet::setup(real_t p_length, bool p_slips_on_slope) { length = p_length; + slips_on_slope = p_slips_on_slope; notifyShapeChanged(); } btCollisionShape *RayShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { - return prepare(ShapeBullet::create_shape_ray(length * p_implicit_scale[1] + p_margin)); + return prepare(ShapeBullet::create_shape_ray(length * p_implicit_scale[1] + p_margin, slips_on_slope)); } diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index e04a3c808a..2acba90e36 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -86,7 +86,7 @@ public: static class btConvexPointCloudShape *create_shape_convex(btAlignedObjectArray<btVector3> &p_vertices, const btVector3 &p_local_scaling = btVector3(1, 1, 1)); static class btScaledBvhTriangleMeshShape *create_shape_concave(btBvhTriangleMeshShape *p_mesh_shape, const btVector3 &p_local_scaling = btVector3(1, 1, 1)); static class btHeightfieldTerrainShape *create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size); - static class btRayShape *create_shape_ray(real_t p_length); + static class btRayShape *create_shape_ray(real_t p_length, bool p_slips_on_slope); }; class PlaneShapeBullet : public ShapeBullet { @@ -216,6 +216,7 @@ class RayShapeBullet : public ShapeBullet { public: real_t length; + bool slips_on_slope; RayShapeBullet(); @@ -225,6 +226,6 @@ public: virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0); private: - void setup(real_t p_length); + void setup(real_t p_length, bool p_slips_on_slope); }; #endif diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 88d9c20eba..8c15758e0f 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -628,7 +628,7 @@ void SpaceBullet::destroy_world() { void SpaceBullet::check_ghost_overlaps() { - /// Algorith support variables + /// Algorithm support variables btConvexShape *other_body_shape; btConvexShape *area_shape; btGjkPairDetector::ClosestPointInput gjk_input; @@ -790,7 +790,7 @@ void SpaceBullet::update_gravity() { /// I'm leaving this here just for future tests. /// Debug motion and normal vector drawing #define debug_test_motion 0 -#define PERFORM_INITIAL_UNSTACK 0 + #define RECOVERING_MOVEMENT_SCALE 0.4 #define RECOVERING_MOVEMENT_CYCLES 4 @@ -804,8 +804,7 @@ static Ref<SpatialMaterial> red_mat; static Ref<SpatialMaterial> blue_mat; #endif -#define IGNORE_AREAS_TRUE true -bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, PhysicsServer::MotionResult *r_result) { +bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer::MotionResult *r_result) { #if debug_test_motion /// Yes I know this is not good, but I've used it as fast debugging hack. @@ -839,25 +838,14 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f } #endif - ///// Release all generated manifolds - //{ - // if(p_body->get_kinematic_utilities()){ - // for(int i= p_body->get_kinematic_utilities()->m_generatedManifold.size()-1; 0<=i; --i){ - // dispatcher->releaseManifold( p_body->get_kinematic_utilities()->m_generatedManifold[i] ); - // } - // p_body->get_kinematic_utilities()->m_generatedManifold.clear(); - // } - //} - btTransform body_safe_position; G_TO_B(p_from, body_safe_position); UNSCALE_BT_BASIS(body_safe_position); -#if PERFORM_INITIAL_UNSTACK btVector3 recover_initial_position(0, 0, 0); { /// Phase one - multi shapes depenetration using margin for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { - if (!recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, recover_initial_position)) { + if (!recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, recover_initial_position)) { break; } } @@ -865,7 +853,6 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f // Add recover movement in order to make it safe body_safe_position.getOrigin() += recover_initial_position; } -#endif btVector3 motion; G_TO_B(p_motion, motion); @@ -900,11 +887,11 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f btTransform shape_world_to(shape_world_from); shape_world_to.getOrigin() += motion; - GodotKinClosestConvexResultCallback btResult(shape_world_from.getOrigin(), shape_world_to.getOrigin(), p_body, IGNORE_AREAS_TRUE); + GodotKinClosestConvexResultCallback btResult(shape_world_from.getOrigin(), shape_world_to.getOrigin(), p_body, p_infinite_inertia); btResult.m_collisionFilterGroup = p_body->get_collision_layer(); btResult.m_collisionFilterMask = p_body->get_collision_mask(); - dynamicsWorld->convexSweepTest(convex_shape_test, shape_world_from, shape_world_to, btResult, 0.002); + dynamicsWorld->convexSweepTest(convex_shape_test, shape_world_from, shape_world_to, btResult, dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration); if (btResult.hasHit()) { /// Since for each sweep test I fix the motion of new shapes in base the recover result, @@ -926,14 +913,11 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f real_t l_penetration_distance = 1e20; for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { - l_has_penetration = recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, delta_recover_movement, &r_recover_result); + l_has_penetration = recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, delta_recover_movement, &r_recover_result); if (r_result) { -#if PERFORM_INITIAL_UNSTACK B_TO_G(motion + delta_recover_movement + recover_initial_position, r_result->motion); -#else - B_TO_G(motion + delta_recover_movement, r_result->motion); -#endif + if (l_has_penetration) { has_penetration = true; if (l_penetration_distance <= r_recover_result.penetration_distance) { @@ -955,15 +939,6 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f r_result->collider_shape = r_recover_result.other_compound_shape_index; r_result->collision_local_shape = r_recover_result.local_shape_most_recovered; - //{ /// Add manifold point to manage collisions - // btPersistentManifold* manifold = dynamicsWorld->getDispatcher()->getNewManifold(p_body->getBtBody(), btRigid); - // btManifoldPoint manifoldPoint(result_callabck.m_pointWorld, result_callabck.m_pointWorld, result_callabck.m_pointNormalWorld, result_callabck.m_penetration_distance); - // manifoldPoint.m_index0 = r_result->collision_local_shape; - // manifoldPoint.m_index1 = r_result->collider_shape; - // manifold->addManifoldPoint(manifoldPoint); - // p_body->get_kinematic_utilities()->m_generatedManifold.push_back(manifold); - //} - #if debug_test_motion Vector3 sup_line2; B_TO_G(motion, sup_line2); @@ -1022,7 +997,7 @@ public: } }; -bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) { +bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) { RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), p_body->get_collision_mask()); @@ -1053,7 +1028,7 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran for (int i = recover_broad_result.result_collision_objects.size() - 1; 0 <= i; --i) { btCollisionObject *otherObject = recover_broad_result.result_collision_objects[i]; - if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object())) + if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object()) || (p_infinite_inertia && !otherObject->isStaticOrKinematicObject())) continue; if (otherObject->getCollisionShape()->isCompound()) { @@ -1132,7 +1107,7 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC btCollisionObjectWrapper obA(NULL, p_shapeA, p_objectA, tA, -1, p_shapeId_A); btCollisionObjectWrapper obB(NULL, p_shapeB, p_objectB, p_transformB, -1, p_shapeId_B); - btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CLOSEST_POINT_ALGORITHMS); + btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CONTACT_POINT_ALGORITHMS); if (algorithm) { GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB); //discrete collision detection query @@ -1142,7 +1117,7 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC dispatcher->freeCollisionAlgorithm(algorithm); if (contactPointResult.hasHit()) { - r_delta_recover_movement += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * -1 * p_recover_movement_scale); + r_delta_recover_movement += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * p_recover_movement_scale); if (r_recover_result) { if (contactPointResult.m_penetration_distance < r_recover_result->penetration_distance) { diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 2b97f0b274..a6c2786878 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -172,7 +172,7 @@ public: void update_gravity(); - bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, PhysicsServer::MotionResult *r_result); + bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer::MotionResult *r_result); private: void create_empty_world(bool p_create_soft_world); @@ -199,7 +199,7 @@ private: local_shape_most_recovered(0) {} }; - bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL); + bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL); /// This is an API that recover a kinematic object from penetration /// This allow only Convex Convex test and it always use GJK algorithm, With this API we don't benefit of Bullet special accelerated functions bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL); |