Merge pull request #44112 from winterpixelgames/PR-more-deterministic-and-reliable-2d-physics
make 2d constraint solving more deterministic by solving in push order
This commit is contained in:
commit
ddbdafbcf1
|
@ -89,7 +89,7 @@ AreaPair2DSW::~AreaPair2DSW() {
|
||||||
area->remove_body_from_query(body, body_shape, area_shape);
|
area->remove_body_from_query(body, body_shape, area_shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body->remove_constraint(this);
|
body->remove_constraint(this, 0);
|
||||||
area->remove_constraint(this);
|
area->remove_constraint(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -562,13 +562,13 @@ void Body2DSW::integrate_velocities(real_t p_step) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Body2DSW::wakeup_neighbours() {
|
void Body2DSW::wakeup_neighbours() {
|
||||||
for (Map<Constraint2DSW *, int>::Element *E = constraint_map.front(); E; E = E->next()) {
|
for (List<Pair<Constraint2DSW *, int>>::Element *E = constraint_list.front(); E; E = E->next()) {
|
||||||
const Constraint2DSW *c = E->key();
|
const Constraint2DSW *c = E->get().first;
|
||||||
Body2DSW **n = c->get_body_ptr();
|
Body2DSW **n = c->get_body_ptr();
|
||||||
int bc = c->get_body_count();
|
int bc = c->get_body_count();
|
||||||
|
|
||||||
for (int i = 0; i < bc; i++) {
|
for (int i = 0; i < bc; i++) {
|
||||||
if (i == E->get()) {
|
if (i == E->get().second) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Body2DSW *b = n[i];
|
Body2DSW *b = n[i];
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include "area_2d_sw.h"
|
#include "area_2d_sw.h"
|
||||||
#include "collision_object_2d_sw.h"
|
#include "collision_object_2d_sw.h"
|
||||||
|
#include "core/templates/list.h"
|
||||||
|
#include "core/templates/pair.h"
|
||||||
#include "core/templates/vset.h"
|
#include "core/templates/vset.h"
|
||||||
|
|
||||||
class Constraint2DSW;
|
class Constraint2DSW;
|
||||||
|
@ -83,7 +85,7 @@ class Body2DSW : public CollisionObject2DSW {
|
||||||
virtual void _shapes_changed();
|
virtual void _shapes_changed();
|
||||||
Transform2D new_transform;
|
Transform2D new_transform;
|
||||||
|
|
||||||
Map<Constraint2DSW *, int> constraint_map;
|
List<Pair<Constraint2DSW *, int>> constraint_list;
|
||||||
|
|
||||||
struct AreaCMP {
|
struct AreaCMP {
|
||||||
Area2DSW *area;
|
Area2DSW *area;
|
||||||
|
@ -179,10 +181,10 @@ public:
|
||||||
_FORCE_INLINE_ Body2DSW *get_island_list_next() const { return island_list_next; }
|
_FORCE_INLINE_ Body2DSW *get_island_list_next() const { return island_list_next; }
|
||||||
_FORCE_INLINE_ void set_island_list_next(Body2DSW *p_next) { island_list_next = p_next; }
|
_FORCE_INLINE_ void set_island_list_next(Body2DSW *p_next) { island_list_next = p_next; }
|
||||||
|
|
||||||
_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
|
_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_list.push_back({ p_constraint, p_pos }); }
|
||||||
_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraint_map.erase(p_constraint); }
|
_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_list.erase({ p_constraint, p_pos }); }
|
||||||
const Map<Constraint2DSW *, int> &get_constraint_map() const { return constraint_map; }
|
const List<Pair<Constraint2DSW *, int>> &get_constraint_list() const { return constraint_list; }
|
||||||
_FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); }
|
_FORCE_INLINE_ void clear_constraint_list() { constraint_list.clear(); }
|
||||||
|
|
||||||
_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
|
_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
|
||||||
_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
|
_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
|
||||||
|
|
|
@ -514,6 +514,6 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A, Body2DSW *p_B, int p_sh
|
||||||
}
|
}
|
||||||
|
|
||||||
BodyPair2DSW::~BodyPair2DSW() {
|
BodyPair2DSW::~BodyPair2DSW() {
|
||||||
A->remove_constraint(this);
|
A->remove_constraint(this, 0);
|
||||||
B->remove_constraint(this);
|
B->remove_constraint(this, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,10 +199,10 @@ PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p
|
||||||
|
|
||||||
PinJoint2DSW::~PinJoint2DSW() {
|
PinJoint2DSW::~PinJoint2DSW() {
|
||||||
if (A) {
|
if (A) {
|
||||||
A->remove_constraint(this);
|
A->remove_constraint(this, 0);
|
||||||
}
|
}
|
||||||
if (B) {
|
if (B) {
|
||||||
B->remove_constraint(this);
|
B->remove_constraint(this, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,8 +339,8 @@ GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_
|
||||||
}
|
}
|
||||||
|
|
||||||
GrooveJoint2DSW::~GrooveJoint2DSW() {
|
GrooveJoint2DSW::~GrooveJoint2DSW() {
|
||||||
A->remove_constraint(this);
|
A->remove_constraint(this, 0);
|
||||||
B->remove_constraint(this);
|
B->remove_constraint(this, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
@ -436,6 +436,6 @@ DampedSpringJoint2DSW::DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Ve
|
||||||
}
|
}
|
||||||
|
|
||||||
DampedSpringJoint2DSW::~DampedSpringJoint2DSW() {
|
DampedSpringJoint2DSW::~DampedSpringJoint2DSW() {
|
||||||
A->remove_constraint(this);
|
A->remove_constraint(this, 0);
|
||||||
B->remove_constraint(this);
|
B->remove_constraint(this, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,7 +554,7 @@ void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) {
|
||||||
return; //pointless
|
return; //pointless
|
||||||
}
|
}
|
||||||
|
|
||||||
body->clear_constraint_map();
|
body->clear_constraint_list();
|
||||||
body->set_space(space);
|
body->set_space(space);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ void Step2DSW::_populate_island(Body2DSW *p_body, Body2DSW **p_island, Constrain
|
||||||
p_body->set_island_next(*p_island);
|
p_body->set_island_next(*p_island);
|
||||||
*p_island = p_body;
|
*p_island = p_body;
|
||||||
|
|
||||||
for (Map<Constraint2DSW *, int>::Element *E = p_body->get_constraint_map().front(); E; E = E->next()) {
|
for (const List<Pair<Constraint2DSW *, int>>::Element *E = p_body->get_constraint_list().front(); E; E = E->next()) {
|
||||||
Constraint2DSW *c = (Constraint2DSW *)E->key();
|
Constraint2DSW *c = (Constraint2DSW *)E->get().first;
|
||||||
if (c->get_island_step() == _step) {
|
if (c->get_island_step() == _step) {
|
||||||
continue; //already processed
|
continue; //already processed
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ void Step2DSW::_populate_island(Body2DSW *p_body, Body2DSW **p_island, Constrain
|
||||||
*p_constraint_island = c;
|
*p_constraint_island = c;
|
||||||
|
|
||||||
for (int i = 0; i < c->get_body_count(); i++) {
|
for (int i = 0; i < c->get_body_count(); i++) {
|
||||||
if (i == E->get()) {
|
if (i == E->get().second) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Body2DSW *b = c->get_body_ptr()[i];
|
Body2DSW *b = c->get_body_ptr()[i];
|
||||||
|
|
Loading…
Reference in New Issue