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

One-directional layer check for Area vs. RigidBody/SoftBody/Area
This commit is contained in:
Camille Mohr-Daurat 2021-08-26 07:59:06 -07:00 committed by GitHub
commit f89adbf112
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 65 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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),

View file

@ -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;