Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One-directional layer check for Area vs. RigidBody/SoftBody/Area #51801

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 37 additions & 30 deletions servers/physics_2d/area_pair_2d_sw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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.
Expand All @@ -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);
}
6 changes: 4 additions & 2 deletions servers/physics_2d/area_pair_2d_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
69 changes: 38 additions & 31 deletions servers/physics_3d/area_pair_3d_sw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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.
Expand All @@ -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);
}
Expand All @@ -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),
Expand Down
6 changes: 4 additions & 2 deletions servers/physics_3d/area_pair_3d_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down