Merge pull request #10770 from RandomShaper/fix-joints

Fix joints collision exceptions, plus a bit more
This commit is contained in:
Rémi Verschelde 2017-10-31 23:02:37 +01:00 committed by GitHub
commit 24b3733f3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 120 deletions

View file

@ -33,19 +33,49 @@
#include "physics_body_2d.h"
#include "servers/physics_2d_server.h"
void Joint2D::_update_joint() {
if (!is_inside_tree())
return;
void Joint2D::_update_joint(bool p_only_free) {
if (joint.is_valid()) {
if (ba.is_valid() && bb.is_valid())
Physics2DServer::get_singleton()->body_remove_collision_exception(ba, bb);
Physics2DServer::get_singleton()->free(joint);
joint = RID();
ba = RID();
bb = RID();
}
joint = RID();
if (p_only_free || !is_inside_tree())
return;
Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
if (!node_a || !node_b)
return;
PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
if (!body_a || !body_b)
return;
if (!body_a) {
SWAP(body_a, body_b);
}
joint = _configure_joint(body_a, body_b);
if (!joint.is_valid())
return;
joint = _configure_joint();
Physics2DServer::get_singleton()->get_singleton()->joint_set_param(joint, Physics2DServer::JOINT_PARAM_BIAS, bias);
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());
}
void Joint2D::set_node_a(const NodePath &p_node_a) {
@ -83,9 +113,7 @@ void Joint2D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
if (joint.is_valid()) {
Physics2DServer::get_singleton()->free(joint);
joint = RID();
_update_joint(true);
}
} break;
}
@ -164,29 +192,8 @@ void PinJoint2D::_notification(int p_what) {
}
}
RID PinJoint2D::_configure_joint() {
RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
if (!node_a && !node_b)
return RID();
PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
if (!body_a && !body_b)
return RID();
if (!body_a) {
SWAP(body_a, body_b);
} else if (body_b) {
//add a collision exception between both
if (get_exclude_nodes_from_collision())
Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
else
Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());
}
RID pj = Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID());
Physics2DServer::get_singleton()->pin_joint_set_param(pj, Physics2DServer::PIN_JOINT_SOFTNESS, softness);
return pj;
@ -241,24 +248,7 @@ void GrooveJoint2D::_notification(int p_what) {
}
}
RID GrooveJoint2D::_configure_joint() {
Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
if (!node_a || !node_b)
return RID();
PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
if (!body_a || !body_b)
return RID();
if (get_exclude_nodes_from_collision())
Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
else
Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());
RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Transform2D gt = get_global_transform();
Vector2 groove_A1 = gt.get_origin();
@ -330,24 +320,7 @@ void DampedSpringJoint2D::_notification(int p_what) {
}
}
RID DampedSpringJoint2D::_configure_joint() {
Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
if (!node_a || !node_b)
return RID();
PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
if (!body_a || !body_b)
return RID();
if (get_exclude_nodes_from_collision())
Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
else
Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());
RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Transform2D gt = get_global_transform();
Vector2 anchor_A = gt.get_origin();

View file

@ -32,11 +32,14 @@
#include "node_2d.h"
class PhysicsBody2D;
class Joint2D : public Node2D {
GDCLASS(Joint2D, Node2D);
RID joint;
RID ba, bb;
NodePath a;
NodePath b;
@ -45,10 +48,10 @@ class Joint2D : public Node2D {
bool exclude_from_collision;
protected:
void _update_joint();
void _update_joint(bool p_only_free = false);
void _notification(int p_what);
virtual RID _configure_joint() = 0;
virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0;
static void _bind_methods();
@ -77,7 +80,7 @@ class PinJoint2D : public Joint2D {
protected:
void _notification(int p_what);
virtual RID _configure_joint();
virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b);
static void _bind_methods();
public:
@ -96,7 +99,7 @@ class GrooveJoint2D : public Joint2D {
protected:
void _notification(int p_what);
virtual RID _configure_joint();
virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b);
static void _bind_methods();
public:
@ -120,7 +123,7 @@ class DampedSpringJoint2D : public Joint2D {
protected:
void _notification(int p_what);
virtual RID _configure_joint();
virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b);
static void _bind_methods();
public:

View file

@ -32,13 +32,8 @@
void Joint::_update_joint(bool p_only_free) {
if (joint.is_valid()) {
if (ba.is_valid() && bb.is_valid()) {
if (exclude_from_collision)
PhysicsServer::get_singleton()->body_add_collision_exception(ba, bb);
else
PhysicsServer::get_singleton()->body_remove_collision_exception(ba, bb);
}
if (ba.is_valid() && bb.is_valid())
PhysicsServer::get_singleton()->body_remove_collision_exception(ba, bb);
PhysicsServer::get_singleton()->free(joint);
joint = RID();
@ -52,33 +47,31 @@ void Joint::_update_joint(bool p_only_free) {
Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
if (!node_a && !node_b)
if (!node_a || !node_b)
return;
PhysicsBody *body_a = Object::cast_to<PhysicsBody>(node_a);
PhysicsBody *body_b = Object::cast_to<PhysicsBody>(node_b);
if (!body_a && !body_b)
if (!body_a || !body_b)
return;
if (!body_a) {
SWAP(body_a, body_b);
} else if (body_b) {
//add a collision exception between both
PhysicsServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
}
joint = _configure_joint(body_a, body_b);
if (joint.is_valid())
PhysicsServer::get_singleton()->joint_set_solver_priority(joint, solver_priority);
if (!joint.is_valid())
return;
if (body_b && joint.is_valid()) {
PhysicsServer::get_singleton()->joint_set_solver_priority(joint, solver_priority);
ba = body_a->get_rid();
bb = body_b->get_rid();
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());
}
}
void Joint::set_node_a(const NodePath &p_node_a) {
@ -129,8 +122,6 @@ void Joint::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
if (joint.is_valid()) {
_update_joint(true);
//PhysicsServer::get_singleton()->free(joint);
joint = RID();
}
} break;
}

View file

@ -233,14 +233,7 @@ void PhysicsServerSW::area_set_space(RID p_area, RID p_space) {
if (area->get_space() == space)
return; //pointless
for (Set<ConstraintSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) {
RID self = E->get()->get_self();
if (!self.is_valid())
continue;
free(self);
}
area->clear_constraints();
area->set_space(space);
};
@ -494,14 +487,7 @@ void PhysicsServerSW::body_set_space(RID p_body, RID p_space) {
if (body->get_space() == space)
return; //pointless
for (Map<ConstraintSW *, int>::Element *E = body->get_constraint_map().front(); E; E = E->next()) {
RID self = E->key()->get_self();
if (!self.is_valid())
continue;
free(self);
}
body->clear_constraint_map();
body->set_space(space);
};

View file

@ -299,14 +299,7 @@ void Physics2DServerSW::area_set_space(RID p_area, RID p_space) {
if (area->get_space() == space)
return; //pointless
for (Set<Constraint2DSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) {
RID self = E->get()->get_self();
if (!self.is_valid())
continue;
free(self);
}
area->clear_constraints();
area->set_space(space);
};
@ -551,14 +544,7 @@ void Physics2DServerSW::body_set_space(RID p_body, RID p_space) {
if (body->get_space() == space)
return; //pointless
for (Map<Constraint2DSW *, int>::Element *E = body->get_constraint_map().front(); E; E = E->next()) {
RID self = E->key()->get_self();
if (!self.is_valid())
continue;
free(self);
}
body->clear_constraint_map();
body->set_space(space);
};