2
0
Эх сурвалжийг харах

Merge pull request #51801 from nekomatata/area-one-directional-layer-check

One-directional layer check for Area vs. RigidBody/SoftBody/Area
Camille Mohr-Daurat 4 жил өмнө
parent
commit
f89adbf112

+ 37 - 30
servers/physics_2d/area_pair_2d_sw.cpp

@@ -33,7 +33,7 @@
 
 bool AreaPair2DSW::setup(real_t p_step) {
 	bool result = false;
-	if (area->interacts_with(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), nullptr, this)) {
+	if (area->collides_with(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), nullptr, this)) {
 		result = true;
 	}
 
@@ -109,46 +109,51 @@ AreaPair2DSW::~AreaPair2DSW() {
 //////////////////////////////////
 
 bool Area2Pair2DSW::setup(real_t p_step) {
-	bool result = false;
-	if (area_a->interacts_with(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), nullptr, this)) {
-		result = true;
+	bool result_a = area_a->collides_with(area_b);
+	bool result_b = area_b->collides_with(area_a);
+	if ((result_a || result_b) && !CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), nullptr, this)) {
+		result_a = false;
+		result_b = false;
 	}
 
-	process_collision = false;
-	if (result != colliding) {
-		if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
-			process_collision = true;
-		} else if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
+	bool process_collision = false;
+
+	process_collision_a = false;
+	if (result_a != colliding_a) {
+		if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
+			process_collision_a = true;
 			process_collision = true;
 		}
+		colliding_a = result_a;
+	}
 
-		colliding = result;
+	process_collision_b = false;
+	if (result_b != colliding_b) {
+		if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
+			process_collision_b = true;
+			process_collision = true;
+		}
+		colliding_b = result_b;
 	}
 
 	return process_collision;
 }
 
 bool Area2Pair2DSW::pre_solve(real_t p_step) {
-	if (!process_collision) {
-		return false;
+	if (process_collision_a) {
+		if (colliding_a) {
+			area_a->add_area_to_query(area_b, shape_b, shape_a);
+		} else {
+			area_a->remove_area_from_query(area_b, shape_b, shape_a);
+		}
 	}
 
-	if (colliding) {
-		if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
+	if (process_collision_b) {
+		if (colliding_b) {
 			area_b->add_area_to_query(area_a, shape_a, shape_b);
-		}
-
-		if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
-			area_a->add_area_to_query(area_b, shape_b, shape_a);
-		}
-	} else {
-		if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
+		} else {
 			area_b->remove_area_from_query(area_a, shape_a, shape_b);
 		}
-
-		if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
-			area_a->remove_area_from_query(area_b, shape_b, shape_a);
-		}
 	}
 
 	return false; // Never do any post solving.
@@ -168,16 +173,18 @@ Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area
 }
 
 Area2Pair2DSW::~Area2Pair2DSW() {
-	if (colliding) {
-		if (area_b->has_area_monitor_callback()) {
-			area_b->remove_area_from_query(area_a, shape_a, shape_b);
-		}
-
+	if (colliding_a) {
 		if (area_a->has_area_monitor_callback()) {
 			area_a->remove_area_from_query(area_b, shape_b, shape_a);
 		}
 	}
 
+	if (colliding_b) {
+		if (area_b->has_area_monitor_callback()) {
+			area_b->remove_area_from_query(area_a, shape_a, shape_b);
+		}
+	}
+
 	area_a->remove_constraint(this);
 	area_b->remove_constraint(this);
 }

+ 4 - 2
servers/physics_2d/area_pair_2d_sw.h

@@ -57,8 +57,10 @@ class Area2Pair2DSW : public Constraint2DSW {
 	Area2DSW *area_b = nullptr;
 	int shape_a = 0;
 	int shape_b = 0;
-	bool colliding = false;
-	bool process_collision = false;
+	bool colliding_a = false;
+	bool colliding_b = false;
+	bool process_collision_a = false;
+	bool process_collision_b = false;
 
 public:
 	virtual bool setup(real_t p_step) override;

+ 38 - 31
servers/physics_3d/area_pair_3d_sw.cpp

@@ -33,7 +33,7 @@
 
 bool AreaPair3DSW::setup(real_t p_step) {
 	bool result = false;
-	if (area->interacts_with(body) && CollisionSolver3DSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), nullptr, this)) {
+	if (area->collides_with(body) && CollisionSolver3DSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), nullptr, this)) {
 		result = true;
 	}
 
@@ -109,46 +109,51 @@ AreaPair3DSW::~AreaPair3DSW() {
 ////////////////////////////////////////////////////
 
 bool Area2Pair3DSW::setup(real_t p_step) {
-	bool result = false;
-	if (area_a->interacts_with(area_b) && CollisionSolver3DSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), nullptr, this)) {
-		result = true;
+	bool result_a = area_a->collides_with(area_b);
+	bool result_b = area_b->collides_with(area_a);
+	if ((result_a || result_b) && !CollisionSolver3DSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), nullptr, this)) {
+		result_a = false;
+		result_b = false;
 	}
 
-	process_collision = false;
-	if (result != colliding) {
-		if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
-			process_collision = true;
-		} else if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
+	bool process_collision = false;
+
+	process_collision_a = false;
+	if (result_a != colliding_a) {
+		if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
+			process_collision_a = true;
 			process_collision = true;
 		}
+		colliding_a = result_a;
+	}
 
-		colliding = result;
+	process_collision_b = false;
+	if (result_b != colliding_b) {
+		if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
+			process_collision_b = true;
+			process_collision = true;
+		}
+		colliding_b = result_b;
 	}
 
 	return process_collision;
 }
 
 bool Area2Pair3DSW::pre_solve(real_t p_step) {
-	if (!process_collision) {
-		return false;
+	if (process_collision_a) {
+		if (colliding_a) {
+			area_a->add_area_to_query(area_b, shape_b, shape_a);
+		} else {
+			area_a->remove_area_from_query(area_b, shape_b, shape_a);
+		}
 	}
 
-	if (colliding) {
-		if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
+	if (process_collision_b) {
+		if (colliding_b) {
 			area_b->add_area_to_query(area_a, shape_a, shape_b);
-		}
-
-		if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
-			area_a->add_area_to_query(area_b, shape_b, shape_a);
-		}
-	} else {
-		if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
+		} else {
 			area_b->remove_area_from_query(area_a, shape_a, shape_b);
 		}
-
-		if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
-			area_a->remove_area_from_query(area_b, shape_b, shape_a);
-		}
 	}
 
 	return false; // Never do any post solving.
@@ -168,16 +173,18 @@ Area2Pair3DSW::Area2Pair3DSW(Area3DSW *p_area_a, int p_shape_a, Area3DSW *p_area
 }
 
 Area2Pair3DSW::~Area2Pair3DSW() {
-	if (colliding) {
-		if (area_b->has_area_monitor_callback()) {
-			area_b->remove_area_from_query(area_a, shape_a, shape_b);
-		}
-
+	if (colliding_a) {
 		if (area_a->has_area_monitor_callback()) {
 			area_a->remove_area_from_query(area_b, shape_b, shape_a);
 		}
 	}
 
+	if (colliding_b) {
+		if (area_b->has_area_monitor_callback()) {
+			area_b->remove_area_from_query(area_a, shape_a, shape_b);
+		}
+	}
+
 	area_a->remove_constraint(this);
 	area_b->remove_constraint(this);
 }
@@ -187,7 +194,7 @@ Area2Pair3DSW::~Area2Pair3DSW() {
 bool AreaSoftBodyPair3DSW::setup(real_t p_step) {
 	bool result = false;
 	if (
-			area->interacts_with(soft_body) &&
+			area->collides_with(soft_body) &&
 			CollisionSolver3DSW::solve_static(
 					soft_body->get_shape(soft_body_shape),
 					soft_body->get_transform() * soft_body->get_shape_transform(soft_body_shape),

+ 4 - 2
servers/physics_3d/area_pair_3d_sw.h

@@ -58,8 +58,10 @@ class Area2Pair3DSW : public Constraint3DSW {
 	Area3DSW *area_b;
 	int shape_a;
 	int shape_b;
-	bool colliding = false;
-	bool process_collision = false;
+	bool colliding_a = false;
+	bool colliding_b = false;
+	bool process_collision_a = false;
+	bool process_collision_b = false;
 
 public:
 	virtual bool setup(real_t p_step) override;