Fix joints collision exceptions
Fix 3D joint handling of collision exceptions, so that they lose effect when the joint is not valid in every case; also some redundant code removed.
Also avoid trying to create the joint when not neither body A nor body B are set.
Make 2D joints be handled like their 3D counterparts, which adds the fixes to them while also removing duplicated code.
(adapted from commit 4a98a59aa6
)
This commit is contained in:
parent
06d7e36898
commit
d8584682f0
3 changed files with 59 additions and 92 deletions
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue