Merge pull request #16757 from AndreaCatania/kinpush
Improved kinematic body, Now can move rigid body
This commit is contained in:
commit
497a4e9e25
|
@ -825,12 +825,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) {
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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,16 +838,6 @@ 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);
|
||||
|
@ -857,7 +846,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -900,7 +889,7 @@ 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();
|
||||
|
||||
|
@ -926,7 +915,7 @@ 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
|
||||
|
@ -955,15 +944,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 +1002,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 +1033,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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "physics_body_2d.h"
|
||||
|
||||
#include "core/method_bind_ext.gen.inc"
|
||||
#include "engine.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
|
||||
|
@ -362,12 +363,12 @@ struct _RigidBody2DInOut {
|
|||
int local_shape;
|
||||
};
|
||||
|
||||
bool RigidBody2D::_test_motion(const Vector2 &p_motion, float p_margin, const Ref<Physics2DTestMotionResult> &p_result) {
|
||||
bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<Physics2DTestMotionResult> &p_result) {
|
||||
|
||||
Physics2DServer::MotionResult *r = NULL;
|
||||
if (p_result.is_valid())
|
||||
r = p_result->get_result_ptr();
|
||||
return Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_margin, r);
|
||||
return Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r);
|
||||
}
|
||||
|
||||
void RigidBody2D::_direct_state_changed(Object *p_state) {
|
||||
|
@ -970,11 +971,11 @@ RigidBody2D::~RigidBody2D() {
|
|||
|
||||
//////////////////////////
|
||||
|
||||
Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion) {
|
||||
Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia) {
|
||||
|
||||
Collision col;
|
||||
|
||||
if (move_and_collide(p_motion, col)) {
|
||||
if (move_and_collide(p_motion, p_infinite_inertia, col)) {
|
||||
if (motion_cache.is_null()) {
|
||||
motion_cache.instance();
|
||||
motion_cache->owner = this;
|
||||
|
@ -988,11 +989,11 @@ Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion) {
|
|||
return Ref<KinematicCollision2D>();
|
||||
}
|
||||
|
||||
bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, Collision &r_collision) {
|
||||
bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision) {
|
||||
|
||||
Transform2D gt = get_global_transform();
|
||||
Physics2DServer::MotionResult result;
|
||||
bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, margin, &result);
|
||||
bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result);
|
||||
|
||||
if (colliding) {
|
||||
r_collision.collider_metadata = result.collider_metadata;
|
||||
|
@ -1012,7 +1013,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, Collision &r_col
|
|||
return colliding;
|
||||
}
|
||||
|
||||
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
|
||||
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
|
||||
|
||||
Vector2 motion = (floor_velocity + p_linear_velocity) * get_physics_process_delta_time();
|
||||
Vector2 lv = p_linear_velocity;
|
||||
|
@ -1027,7 +1028,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
|
|||
|
||||
Collision collision;
|
||||
|
||||
bool collided = move_and_collide(motion, collision);
|
||||
bool collided = move_and_collide(motion, p_infinite_inertia, collision);
|
||||
|
||||
if (collided) {
|
||||
|
||||
|
@ -1094,11 +1095,11 @@ Vector2 KinematicBody2D::get_floor_velocity() const {
|
|||
return floor_velocity;
|
||||
}
|
||||
|
||||
bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion) {
|
||||
bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia) {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
return Physics2DServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, margin);
|
||||
return Physics2DServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin);
|
||||
}
|
||||
|
||||
void KinematicBody2D::set_safe_margin(float p_margin) {
|
||||
|
@ -1139,10 +1140,10 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) {
|
|||
|
||||
void KinematicBody2D::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec"), &KinematicBody2D::_move);
|
||||
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
|
||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia"), &KinematicBody2D::_move, DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody2D::test_move);
|
||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor);
|
||||
ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling);
|
||||
|
|
|
@ -185,7 +185,7 @@ private:
|
|||
void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape);
|
||||
void _direct_state_changed(Object *p_state);
|
||||
|
||||
bool _test_motion(const Vector2 &p_motion, float p_margin = 0.08, const Ref<Physics2DTestMotionResult> &p_result = Ref<Physics2DTestMotionResult>());
|
||||
bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, float p_margin = 0.08, const Ref<Physics2DTestMotionResult> &p_result = Ref<Physics2DTestMotionResult>());
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
@ -296,20 +296,20 @@ private:
|
|||
|
||||
_FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const;
|
||||
|
||||
Ref<KinematicCollision2D> _move(const Vector2 &p_motion);
|
||||
Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true);
|
||||
Ref<KinematicCollision2D> _get_slide_collision(int p_bounce);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
bool move_and_collide(const Vector2 &p_motion, Collision &r_collision);
|
||||
bool test_move(const Transform2D &p_from, const Vector2 &p_motion);
|
||||
bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision);
|
||||
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia);
|
||||
|
||||
void set_safe_margin(float p_margin);
|
||||
float get_safe_margin() const;
|
||||
|
||||
Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
|
||||
Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
|
||||
bool is_on_floor() const;
|
||||
bool is_on_wall() const;
|
||||
bool is_on_ceiling() const;
|
||||
|
|
|
@ -928,10 +928,10 @@ RigidBody::~RigidBody() {
|
|||
//////////////////////////////////////////////////////
|
||||
//////////////////////////
|
||||
|
||||
Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion) {
|
||||
Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_infinite_inertia) {
|
||||
|
||||
Collision col;
|
||||
if (move_and_collide(p_motion, col)) {
|
||||
if (move_and_collide(p_motion, p_infinite_inertia, col)) {
|
||||
if (motion_cache.is_null()) {
|
||||
motion_cache.instance();
|
||||
motion_cache->owner = this;
|
||||
|
@ -945,11 +945,11 @@ Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion) {
|
|||
return Ref<KinematicCollision>();
|
||||
}
|
||||
|
||||
bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_collision) {
|
||||
bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision) {
|
||||
|
||||
Transform gt = get_global_transform();
|
||||
PhysicsServer::MotionResult result;
|
||||
bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, &result);
|
||||
bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result);
|
||||
|
||||
if (colliding) {
|
||||
r_collision.collider_metadata = result.collider_metadata;
|
||||
|
@ -975,7 +975,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli
|
|||
return colliding;
|
||||
}
|
||||
|
||||
Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
|
||||
Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
|
||||
|
||||
Vector3 lv = p_linear_velocity;
|
||||
|
||||
|
@ -997,7 +997,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
|
|||
|
||||
Collision collision;
|
||||
|
||||
bool collided = move_and_collide(motion, collision);
|
||||
bool collided = move_and_collide(motion, p_infinite_inertia, collision);
|
||||
|
||||
if (collided) {
|
||||
|
||||
|
@ -1070,11 +1070,11 @@ Vector3 KinematicBody::get_floor_velocity() const {
|
|||
return floor_velocity;
|
||||
}
|
||||
|
||||
bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion) {
|
||||
bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion);
|
||||
return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia);
|
||||
}
|
||||
|
||||
void KinematicBody::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock) {
|
||||
|
@ -1123,10 +1123,10 @@ Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
|
|||
|
||||
void KinematicBody::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec"), &KinematicBody::_move);
|
||||
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_slides", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
|
||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia"), &KinematicBody::_move, DEFVAL(true));
|
||||
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_slides", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(true), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody::test_move);
|
||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody::test_move);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody::is_on_floor);
|
||||
ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody::is_on_ceiling);
|
||||
|
|
|
@ -286,15 +286,15 @@ private:
|
|||
|
||||
_FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
|
||||
|
||||
Ref<KinematicCollision> _move(const Vector3 &p_motion);
|
||||
Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true);
|
||||
Ref<KinematicCollision> _get_slide_collision(int p_bounce);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
bool move_and_collide(const Vector3 &p_motion, Collision &r_collision);
|
||||
bool test_move(const Transform &p_from, const Vector3 &p_motion);
|
||||
bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision);
|
||||
bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia);
|
||||
|
||||
void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock);
|
||||
bool get_axis_lock(PhysicsServer::BodyAxis p_axis) const;
|
||||
|
@ -302,7 +302,7 @@ public:
|
|||
void set_safe_margin(float p_margin);
|
||||
float get_safe_margin() const;
|
||||
|
||||
Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
|
||||
Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 0.05, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
|
||||
bool is_on_floor() const;
|
||||
bool is_on_wall() const;
|
||||
bool is_on_ceiling() const;
|
||||
|
|
|
@ -902,7 +902,7 @@ bool PhysicsServerSW::body_is_ray_pickable(RID p_body) const {
|
|||
return body->is_ray_pickable();
|
||||
}
|
||||
|
||||
bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result) {
|
||||
bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result) {
|
||||
|
||||
BodySW *body = body_owner.get(p_body);
|
||||
ERR_FAIL_COND_V(!body, false);
|
||||
|
@ -911,7 +911,7 @@ bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, cons
|
|||
|
||||
_update_shapes();
|
||||
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, body->get_kinematic_margin(), r_result);
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, body->get_kinematic_margin(), r_result);
|
||||
}
|
||||
|
||||
PhysicsDirectBodyState *PhysicsServerSW::body_get_direct_state(RID p_body) {
|
||||
|
|
|
@ -225,7 +225,7 @@ public:
|
|||
virtual void body_set_ray_pickable(RID p_body, bool p_enable);
|
||||
virtual bool body_is_ray_pickable(RID p_body) const;
|
||||
|
||||
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);
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body);
|
||||
|
|
|
@ -541,7 +541,7 @@ int SpaceSW::_cull_aabb_for_body(BodySW *p_body, const AABB &p_aabb) {
|
|||
return amount;
|
||||
}
|
||||
|
||||
bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer::MotionResult *r_result) {
|
||||
bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer::MotionResult *r_result) {
|
||||
|
||||
//give me back regular physics engine logic
|
||||
//this is madness
|
||||
|
|
|
@ -197,7 +197,7 @@ public:
|
|||
void set_elapsed_time(ElapsedTime p_time, uint64_t p_msec) { elapsed_time[p_time] = p_msec; }
|
||||
uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; }
|
||||
|
||||
bool test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer::MotionResult *r_result);
|
||||
bool test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer::MotionResult *r_result);
|
||||
|
||||
SpaceSW();
|
||||
~SpaceSW();
|
||||
|
|
|
@ -962,14 +962,14 @@ void Physics2DServerSW::body_set_pickable(RID p_body, bool p_pickable) {
|
|||
body->set_pickable(p_pickable);
|
||||
}
|
||||
|
||||
bool Physics2DServerSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, MotionResult *r_result) {
|
||||
bool Physics2DServerSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result) {
|
||||
|
||||
Body2DSW *body = body_owner.get(p_body);
|
||||
ERR_FAIL_COND_V(!body, false);
|
||||
ERR_FAIL_COND_V(!body->get_space(), false);
|
||||
ERR_FAIL_COND_V(body->get_space()->is_locked(), false);
|
||||
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result);
|
||||
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result);
|
||||
}
|
||||
|
||||
Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
|
||||
|
|
|
@ -232,7 +232,7 @@ public:
|
|||
|
||||
virtual void body_set_pickable(RID p_body, bool p_pickable);
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = NULL);
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL);
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
virtual Physics2DDirectBodyState *body_get_direct_state(RID p_body);
|
||||
|
|
|
@ -245,10 +245,10 @@ public:
|
|||
|
||||
FUNC2(body_set_pickable, RID, bool);
|
||||
|
||||
bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = NULL) {
|
||||
bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = NULL) {
|
||||
|
||||
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
|
||||
return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_margin, r_result);
|
||||
return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result);
|
||||
}
|
||||
|
||||
// this function only works on physics process, errors and returns null otherwise
|
||||
|
|
|
@ -483,7 +483,7 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
|
|||
return amount;
|
||||
}
|
||||
|
||||
bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, Physics2DServer::MotionResult *r_result) {
|
||||
bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result) {
|
||||
|
||||
//give me back regular physics engine logic
|
||||
//this is madness
|
||||
|
@ -550,6 +550,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
const CollisionObject2DSW *col_obj = intersection_query_results[i];
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
if (p_infinite_inertia && Physics2DServer::BODY_MODE_STATIC != b->get_mode() && Physics2DServer::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
|
||||
|
||||
cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
|
||||
|
@ -638,6 +645,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
int col_shape_idx = intersection_query_subindex_results[i];
|
||||
Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx);
|
||||
|
||||
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
if (p_infinite_inertia && Physics2DServer::BODY_MODE_STATIC != b->get_mode() && Physics2DServer::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bool excluded = false;
|
||||
|
||||
for (int k = 0; k < excluded_shape_pair_count; k++) {
|
||||
|
@ -768,6 +782,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
const CollisionObject2DSW *col_obj = intersection_query_results[i];
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
if (p_infinite_inertia && Physics2DServer::BODY_MODE_STATIC != b->get_mode() && Physics2DServer::BODY_MODE_KINEMATIC != b->get_mode()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
|
||||
|
||||
bool excluded = false;
|
||||
|
|
|
@ -182,7 +182,7 @@ public:
|
|||
|
||||
int get_collision_pairs() const { return collision_pairs; }
|
||||
|
||||
bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, Physics2DServer::MotionResult *r_result);
|
||||
bool test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, Physics2DServer::MotionResult *r_result);
|
||||
|
||||
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
|
||||
_FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); }
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
/*************************************************************************/
|
||||
|
||||
#include "physics_2d_server.h"
|
||||
#include "core/method_bind_ext.gen.inc"
|
||||
#include "core/project_settings.h"
|
||||
#include "print_string.h"
|
||||
|
||||
|
@ -476,12 +477,12 @@ Physics2DTestMotionResult::Physics2DTestMotionResult() {
|
|||
|
||||
///////////////////////////////////////
|
||||
|
||||
bool Physics2DServer::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, float p_margin, const Ref<Physics2DTestMotionResult> &p_result) {
|
||||
bool Physics2DServer::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<Physics2DTestMotionResult> &p_result) {
|
||||
|
||||
MotionResult *r = NULL;
|
||||
if (p_result.is_valid())
|
||||
r = p_result->get_result_ptr();
|
||||
return body_test_motion(p_body, p_from, p_motion, p_margin, r);
|
||||
return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r);
|
||||
}
|
||||
|
||||
void Physics2DServer::_bind_methods() {
|
||||
|
@ -598,7 +599,7 @@ void Physics2DServer::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("body_set_force_integration_callback", "body", "receiver", "method", "userdata"), &Physics2DServer::body_set_force_integration_callback, DEFVAL(Variant()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "margin", "result"), &Physics2DServer::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "infinite_inertia", "margin", "result"), &Physics2DServer::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &Physics2DServer::body_get_direct_state);
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ class Physics2DServer : public Object {
|
|||
|
||||
static Physics2DServer *singleton;
|
||||
|
||||
virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, float p_margin = 0.08, const Ref<Physics2DTestMotionResult> &p_result = Ref<Physics2DTestMotionResult>());
|
||||
virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.08, const Ref<Physics2DTestMotionResult> &p_result = Ref<Physics2DTestMotionResult>());
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -479,7 +479,7 @@ public:
|
|||
Variant collider_metadata;
|
||||
};
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL) = 0;
|
||||
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = NULL) = 0;
|
||||
|
||||
/* JOINT API */
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ public:
|
|||
Variant collider_metadata;
|
||||
};
|
||||
|
||||
virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, MotionResult *r_result = NULL) = 0;
|
||||
virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL) = 0;
|
||||
|
||||
/* JOINT API */
|
||||
|
||||
|
|
Loading…
Reference in New Issue