Skip to content

Commit

Permalink
Added physics API in order to enable/disable collisions between rigid…
Browse files Browse the repository at this point in the history
…body attached to a joint with bullet physics bullet

Fixes godotengine#16424
  • Loading branch information
AndreaCatania committed Feb 5, 2018
1 parent ea99b90 commit a42765d
Show file tree
Hide file tree
Showing 15 changed files with 121 additions and 13 deletions.
30 changes: 22 additions & 8 deletions modules/bullet/bullet_physics_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@
return RID(); \
}

#define AddJointToSpace(body, joint, disableCollisionsBetweenLinkedBodies) \
body->get_space()->add_constraint(joint, disableCollisionsBetweenLinkedBodies);
#define AddJointToSpace(body, joint) \
body->get_space()->add_constraint(joint, joint->is_disabled_collisions_between_bodies());
// <--------------- Joint creation asserts

btEmptyShape *BulletPhysicsServer::emptyShape(ShapeBullet::create_shape_empty());
Expand Down Expand Up @@ -987,6 +987,20 @@ int BulletPhysicsServer::joint_get_solver_priority(RID p_joint) const {
return 0;
}

void BulletPhysicsServer::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) {
JointBullet *joint = joint_owner.get(p_joint);
ERR_FAIL_COND(!joint);

joint->disable_collisions_between_bodies(p_disable);
}

bool BulletPhysicsServer::joint_is_disabled_collisions_between_bodies(RID p_joint) const {
JointBullet *joint(joint_owner.get(p_joint));
ERR_FAIL_COND_V(!joint, false);

return joint->is_disabled_collisions_between_bodies();
}

RID BulletPhysicsServer::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
Expand All @@ -1003,7 +1017,7 @@ RID BulletPhysicsServer::joint_create_pin(RID p_body_A, const Vector3 &p_local_A
ERR_FAIL_COND_V(body_A == body_B, RID());

JointBullet *joint = bulletnew(PinJointBullet(body_A, p_local_A, body_B, p_local_B));
AddJointToSpace(body_A, joint, true);
AddJointToSpace(body_A, joint);

CreateThenReturnRID(joint_owner, joint);
}
Expand Down Expand Up @@ -1071,7 +1085,7 @@ RID BulletPhysicsServer::joint_create_hinge(RID p_body_A, const Transform &p_hin
ERR_FAIL_COND_V(body_A == body_B, RID());

JointBullet *joint = bulletnew(HingeJointBullet(body_A, body_B, p_hinge_A, p_hinge_B));
AddJointToSpace(body_A, joint, true);
AddJointToSpace(body_A, joint);

CreateThenReturnRID(joint_owner, joint);
}
Expand All @@ -1091,7 +1105,7 @@ RID BulletPhysicsServer::joint_create_hinge_simple(RID p_body_A, const Vector3 &
ERR_FAIL_COND_V(body_A == body_B, RID());

JointBullet *joint = bulletnew(HingeJointBullet(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B));
AddJointToSpace(body_A, joint, true);
AddJointToSpace(body_A, joint);

CreateThenReturnRID(joint_owner, joint);
}
Expand Down Expand Up @@ -1143,7 +1157,7 @@ RID BulletPhysicsServer::joint_create_slider(RID p_body_A, const Transform &p_lo
ERR_FAIL_COND_V(body_A == body_B, RID());

JointBullet *joint = bulletnew(SliderJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B));
AddJointToSpace(body_A, joint, true);
AddJointToSpace(body_A, joint);

CreateThenReturnRID(joint_owner, joint);
}
Expand Down Expand Up @@ -1177,7 +1191,7 @@ RID BulletPhysicsServer::joint_create_cone_twist(RID p_body_A, const Transform &
}

JointBullet *joint = bulletnew(ConeTwistJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B));
AddJointToSpace(body_A, joint, true);
AddJointToSpace(body_A, joint);

CreateThenReturnRID(joint_owner, joint);
}
Expand Down Expand Up @@ -1213,7 +1227,7 @@ RID BulletPhysicsServer::joint_create_generic_6dof(RID p_body_A, const Transform
ERR_FAIL_COND_V(body_A == body_B, RID());

JointBullet *joint = bulletnew(Generic6DOFJointBullet(body_A, body_B, p_local_frame_A, p_local_frame_B, true));
AddJointToSpace(body_A, joint, true);
AddJointToSpace(body_A, joint);

CreateThenReturnRID(joint_owner, joint);
}
Expand Down
3 changes: 3 additions & 0 deletions modules/bullet/bullet_physics_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ class BulletPhysicsServer : public PhysicsServer {
virtual void joint_set_solver_priority(RID p_joint, int p_priority);
virtual int joint_get_solver_priority(RID p_joint) const;

virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable);
virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const;

virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B);

virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value);
Expand Down
12 changes: 11 additions & 1 deletion modules/bullet/constraint_bullet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@

ConstraintBullet::ConstraintBullet() :
space(NULL),
constraint(NULL) {}
constraint(NULL),
disabled_collisions_between_bodies(true) {}

void ConstraintBullet::setup(btTypedConstraint *p_constraint) {
constraint = p_constraint;
Expand All @@ -53,3 +54,12 @@ void ConstraintBullet::set_space(SpaceBullet *p_space) {
void ConstraintBullet::destroy_internal_constraint() {
space->remove_constraint(this);
}

void ConstraintBullet::disable_collisions_between_bodies(const bool p_disabled) {
disabled_collisions_between_bodies = p_disabled;

if (space) {
space->remove_constraint(this);
space->add_constraint(this, disabled_collisions_between_bodies);
}
}
4 changes: 4 additions & 0 deletions modules/bullet/constraint_bullet.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class ConstraintBullet : public RIDBullet {
protected:
SpaceBullet *space;
btTypedConstraint *constraint;
bool disabled_collisions_between_bodies;

public:
ConstraintBullet();
Expand All @@ -57,6 +58,9 @@ class ConstraintBullet : public RIDBullet {
virtual void set_space(SpaceBullet *p_space);
virtual void destroy_internal_constraint();

void disable_collisions_between_bodies(const bool p_disabled);
_FORCE_INLINE_ bool is_disabled_collisions_between_bodies() const { return disabled_collisions_between_bodies; }

public:
virtual ~ConstraintBullet() {
bulletdelete(constraint);
Expand Down
3 changes: 1 addition & 2 deletions scene/2d/joints_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ void Joint2D::_update_joint(bool p_only_free) {
ba = body_a->get_rid();
bb = body_b->get_rid();

if (exclude_from_collision)
Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
Physics2DServer::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
}

void Joint2D::set_node_a(const NodePath &p_node_a) {
Expand Down
3 changes: 1 addition & 2 deletions scene/3d/physics_joint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ void Joint::_update_joint(bool p_only_free) {
ba = body_a->get_rid();
bb = body_b->get_rid();

if (exclude_from_collision)
PhysicsServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
PhysicsServer::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
}

void Joint::set_node_a(const NodePath &p_node_a) {
Expand Down
5 changes: 5 additions & 0 deletions servers/physics/constraint_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class ConstraintSW : public RID_Data {
ConstraintSW *island_next;
ConstraintSW *island_list_next;
int priority;
bool disabled_collisions_between_bodies;

RID self;

Expand All @@ -50,6 +51,7 @@ class ConstraintSW : public RID_Data {
_body_count = p_body_count;
island_step = 0;
priority = 1;
disabled_collisions_between_bodies = true;
}

public:
Expand All @@ -71,6 +73,9 @@ class ConstraintSW : public RID_Data {
_FORCE_INLINE_ void set_priority(int p_priority) { priority = p_priority; }
_FORCE_INLINE_ int get_priority() const { return priority; }

_FORCE_INLINE_ void disable_collisions_between_bodies(const bool p_disabled) { disabled_collisions_between_bodies = p_disabled; }
_FORCE_INLINE_ bool is_disabled_collisions_between_bodies() const { return disabled_collisions_between_bodies; }

virtual bool setup(real_t p_step) = 0;
virtual void solve(real_t p_step) = 0;

Expand Down
27 changes: 27 additions & 0 deletions servers/physics/physics_server_sw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,33 @@ int PhysicsServerSW::joint_get_solver_priority(RID p_joint) const {
return joint->get_priority();
}

void PhysicsServerSW::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) {
JointSW *joint = joint_owner.get(p_joint);
ERR_FAIL_COND(!joint);

joint->disable_collisions_between_bodies(p_disable);

if (2 == joint->get_body_count()) {
BodySW *body_a = *joint->get_body_ptr();
BodySW *body_b = *(joint->get_body_ptr() + 1);

if (p_disable) {
body_add_collision_exception(body_a->get_self(), body_b->get_self());
body_add_collision_exception(body_b->get_self(), body_a->get_self());
} else {
body_remove_collision_exception(body_a->get_self(), body_b->get_self());
body_remove_collision_exception(body_b->get_self(), body_a->get_self());
}
}
}

bool PhysicsServerSW::joint_is_disabled_collisions_between_bodies(RID p_joint) const {
JointSW *joint = joint_owner.get(p_joint);
ERR_FAIL_COND_V(!joint, true);

return joint->is_disabled_collisions_between_bodies();
}

PhysicsServerSW::JointType PhysicsServerSW::joint_get_type(RID p_joint) const {

JointSW *joint = joint_owner.get(p_joint);
Expand Down
3 changes: 3 additions & 0 deletions servers/physics/physics_server_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ class PhysicsServerSW : public PhysicsServer {
virtual void joint_set_solver_priority(RID p_joint, int p_priority);
virtual int joint_get_solver_priority(RID p_joint) const;

virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable);
virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const;

/* MISC */

virtual void free(RID p_rid);
Expand Down
5 changes: 5 additions & 0 deletions servers/physics_2d/constraint_2d_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Constraint2DSW : public RID_Data {
uint64_t island_step;
Constraint2DSW *island_next;
Constraint2DSW *island_list_next;
bool disabled_collisions_between_bodies;

RID self;

Expand All @@ -48,6 +49,7 @@ class Constraint2DSW : public RID_Data {
_body_ptr = p_body_ptr;
_body_count = p_body_count;
island_step = 0;
disabled_collisions_between_bodies = true;
}

public:
Expand All @@ -66,6 +68,9 @@ class Constraint2DSW : public RID_Data {
_FORCE_INLINE_ Body2DSW **get_body_ptr() const { return _body_ptr; }
_FORCE_INLINE_ int get_body_count() const { return _body_count; }

_FORCE_INLINE_ void disable_collisions_between_bodies(const bool p_disabled) { disabled_collisions_between_bodies = p_disabled; }
_FORCE_INLINE_ bool is_disabled_collisions_between_bodies() const { return disabled_collisions_between_bodies; }

virtual bool setup(real_t p_step) = 0;
virtual void solve(real_t p_step) = 0;

Expand Down
27 changes: 27 additions & 0 deletions servers/physics_2d/physics_2d_server_sw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,33 @@ real_t Physics2DServerSW::joint_get_param(RID p_joint, JointParam p_param) const
return 0;
}

void Physics2DServerSW::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) {
Joint2DSW *joint = joint_owner.get(p_joint);
ERR_FAIL_COND(!joint);

joint->disable_collisions_between_bodies(p_disable);

if (2 == joint->get_body_count()) {
Body2DSW *body_a = *joint->get_body_ptr();
Body2DSW *body_b = *(joint->get_body_ptr() + 1);

if (p_disable) {
body_add_collision_exception(body_a->get_self(), body_b->get_self());
body_add_collision_exception(body_b->get_self(), body_a->get_self());
} else {
body_remove_collision_exception(body_a->get_self(), body_b->get_self());
body_remove_collision_exception(body_b->get_self(), body_a->get_self());
}
}
}

bool Physics2DServerSW::joint_is_disabled_collisions_between_bodies(RID p_joint) const {
const Joint2DSW *joint = joint_owner.get(p_joint);
ERR_FAIL_COND_V(!joint, true);

return joint->is_disabled_collisions_between_bodies();
}

RID Physics2DServerSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b) {

Body2DSW *A = body_owner.get(p_body_a);
Expand Down
3 changes: 3 additions & 0 deletions servers/physics_2d/physics_2d_server_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ class Physics2DServerSW : public Physics2DServer {
virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value);
virtual real_t joint_get_param(RID p_joint, JointParam p_param) const;

virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disabled);
virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const;

virtual RID pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b = RID());
virtual RID groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b);
virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID());
Expand Down
3 changes: 3 additions & 0 deletions servers/physics_2d/physics_2d_server_wrap_mt.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ class Physics2DServerWrapMT : public Physics2DServer {
FUNC3(joint_set_param, RID, JointParam, real_t);
FUNC2RC(real_t, joint_get_param, RID, JointParam);

FUNC2(joint_disable_collisions_between_bodies, RID, const bool);
FUNC1RC(bool, joint_is_disabled_collisions_between_bodies, RID);

///FUNC3RID(pin_joint,const Vector2&,RID,RID);
///FUNC5RID(groove_joint,const Vector2&,const Vector2&,const Vector2&,RID,RID);
///FUNC4RID(damped_spring_joint,const Vector2&,const Vector2&,RID,RID);
Expand Down
3 changes: 3 additions & 0 deletions servers/physics_2d_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@ class Physics2DServer : public Object {
virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value) = 0;
virtual real_t joint_get_param(RID p_joint, JointParam p_param) const = 0;

virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0;
virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0;

virtual RID pin_joint_create(const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) = 0;
virtual RID groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) = 0;
virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) = 0;
Expand Down
3 changes: 3 additions & 0 deletions servers/physics_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,9 @@ class PhysicsServer : public Object {
virtual void joint_set_solver_priority(RID p_joint, int p_priority) = 0;
virtual int joint_get_solver_priority(RID p_joint) const = 0;

virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0;
virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0;

virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) = 0;

enum PinJointParam {
Expand Down

0 comments on commit a42765d

Please sign in to comment.