summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2017-06-23 23:30:43 -0300
committerJuan Linietsky <reduzio@gmail.com>2017-06-23 23:39:52 -0300
commit6ba1e4677ba15992c750bddffcb9f1eacd1558a1 (patch)
tree78e6c53f5279a76fc589544ad3c241c2648af66b /servers
parent683f50bef476fbe630f893876e709ad03348b2c3 (diff)
-Trigger shapes removed in 2D, they became obsolete long ago when areas could detect their own overlap
-Added ability to disable individual collisionshape/polygon -Moved One Way Collision to shape, allowing more flexibility -Changed internals of CollisionObject, shapes are generated from child nodes on the fly, not stored inside any longer. -Modifying a CollisionPolygon2D on the fly now works, it can even be animated. Will port this to 3D once well tested. Have fun!
Diffstat (limited to 'servers')
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp15
-rw-r--r--servers/physics_2d/body_2d_sw.cpp2
-rw-r--r--servers/physics_2d/body_2d_sw.h15
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp15
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp3
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h15
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp52
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h12
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h11
-rw-r--r--servers/physics_2d/space_2d_sw.cpp106
-rw-r--r--servers/physics_2d_server.cpp11
-rw-r--r--servers/physics_2d_server.h12
12 files changed, 90 insertions, 179 deletions
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index c98375fc44..184db944da 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -32,7 +32,13 @@
bool AreaPair2DSW::setup(real_t p_step) {
- bool result = area->test_collision_mask(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(), NULL, this);
+ bool result = false;
+
+ if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
+ result = false;
+ } else if (area->test_collision_mask(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(), NULL, this)) {
+ result = true;
+ }
if (result != colliding) {
@@ -90,7 +96,12 @@ AreaPair2DSW::~AreaPair2DSW() {
bool Area2Pair2DSW::setup(real_t p_step) {
- bool result = area_a->test_collision_mask(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(), NULL, this);
+ bool result = false;
+ if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
+ result = false;
+ } else if (area_a->test_collision_mask(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(), NULL, this)) {
+ result = true;
+ }
if (result != colliding) {
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index 03ad66d4e9..538ea10211 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -676,8 +676,6 @@ Body2DSW::Body2DSW()
area_linear_damp = 0;
contact_count = 0;
gravity_scale = 1.0;
- using_one_way_cache = false;
- one_way_collision_max_depth = 0.1;
first_integration = false;
still_time = 0;
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 23adebbad6..9e5deef3f2 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -67,9 +67,6 @@ class Body2DSW : public CollisionObject2DSW {
Vector2 applied_force;
real_t applied_torque;
- Vector2 one_way_collision_direction;
- real_t one_way_collision_max_depth;
-
SelfList<Body2DSW> active_list;
SelfList<Body2DSW> inertia_update_list;
SelfList<Body2DSW> direct_state_query_list;
@@ -81,7 +78,6 @@ class Body2DSW : public CollisionObject2DSW {
bool can_sleep;
bool first_time_kinematic;
bool first_integration;
- bool using_one_way_cache;
void _update_inertia();
virtual void _shapes_changed();
Transform2D new_transform;
@@ -246,17 +242,6 @@ public:
_FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode = p_mode; }
_FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; }
- void set_one_way_collision_direction(const Vector2 &p_dir) {
- one_way_collision_direction = p_dir;
- using_one_way_cache = one_way_collision_direction != Vector2();
- }
- Vector2 get_one_way_collision_direction() const { return one_way_collision_direction; }
-
- void set_one_way_collision_max_depth(real_t p_depth) { one_way_collision_max_depth = p_depth; }
- real_t get_one_way_collision_max_depth() const { return one_way_collision_max_depth; }
-
- _FORCE_INLINE_ bool is_using_one_way_collision() const { return using_one_way_cache; }
-
void set_space(Space2DSW *p_space);
void update_inertias();
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index 47e9afbde6..484d4503d0 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -225,6 +225,11 @@ bool BodyPair2DSW::setup(real_t p_step) {
return false;
}
+ if (A->is_shape_set_as_disabled(shape_A) || B->is_shape_set_as_disabled(shape_B)) {
+ collided = false;
+ return false;
+ }
+
//use local A coordinates to avoid numerical issues on collision detection
offset_B = B->get_transform().get_origin() - A->get_transform().get_origin();
@@ -280,8 +285,8 @@ bool BodyPair2DSW::setup(real_t p_step) {
//if (!prev_collided) {
{
- if (A->is_using_one_way_collision()) {
- Vector2 direction = A->get_one_way_collision_direction();
+ if (A->is_shape_set_as_one_way_collision(shape_A)) {
+ Vector2 direction = xform_A.get_axis(1).normalized();
bool valid = false;
if (B->get_linear_velocity().dot(direction) >= 0) {
for (int i = 0; i < contact_count; i++) {
@@ -303,8 +308,8 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
}
- if (B->is_using_one_way_collision()) {
- Vector2 direction = B->get_one_way_collision_direction();
+ if (B->is_shape_set_as_one_way_collision(shape_B)) {
+ Vector2 direction = xform_B.get_axis(1).normalized();
bool valid = false;
if (A->get_linear_velocity().dot(direction) >= 0) {
for (int i = 0; i < contact_count; i++) {
@@ -390,7 +395,7 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
}
- if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC)) {
+ if ((A->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC)) {
c.active = false;
collided = false;
continue;
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 0163a18850..8f13f1130a 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -37,7 +37,8 @@ void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_tra
s.xform = p_transform;
s.xform_inv = s.xform.affine_inverse();
s.bpid = 0; //needs update
- s.trigger = false;
+ s.disabled = false;
+ s.one_way_collision = false;
shapes.push_back(s);
p_shape->add_owner(this);
_update_shapes();
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index f2059e8618..5e29132e8d 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -58,8 +58,12 @@ private:
Rect2 aabb_cache; //for rayqueries
Shape2DSW *shape;
Variant metadata;
- bool trigger;
- Shape() { trigger = false; }
+ bool disabled;
+ bool one_way_collision;
+ Shape() {
+ disabled = false;
+ one_way_collision = false;
+ }
};
Vector<Shape> shapes;
@@ -116,8 +120,11 @@ public:
_FORCE_INLINE_ Transform2D get_inv_transform() const { return inv_transform; }
_FORCE_INLINE_ Space2DSW *get_space() const { return space; }
- _FORCE_INLINE_ void set_shape_as_trigger(int p_idx, bool p_enable) { shapes[p_idx].trigger = p_enable; }
- _FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; }
+ _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_disabled) { shapes[p_idx].disabled = p_disabled; }
+ _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const { return shapes[p_idx].disabled; }
+
+ _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision) { shapes[p_idx].one_way_collision = p_one_way_collision; }
+ _FORCE_INLINE_ bool is_shape_set_as_one_way_collision(int p_idx) const { return shapes[p_idx].one_way_collision; }
void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; }
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; }
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 9a31fa49b0..1d88710f1a 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -352,6 +352,15 @@ void Physics2DServerSW::area_set_shape_transform(RID p_area, int p_shape_idx, co
area->set_shape_transform(p_shape_idx, p_transform);
}
+void Physics2DServerSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) {
+
+ Area2DSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ ERR_FAIL_INDEX(p_shape, area->get_shape_count());
+ area->set_shape_as_disabled(p_shape, p_disabled);
+}
+
int Physics2DServerSW::area_get_shape_count(RID p_area) const {
Area2DSW *area = area_owner.get(p_area);
@@ -640,24 +649,23 @@ void Physics2DServerSW::body_clear_shapes(RID p_body) {
body->remove_shape(0);
}
-void Physics2DServerSW::body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) {
+void Physics2DServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
- body->set_shape_as_trigger(p_shape_idx, p_enable);
+ body->set_shape_as_disabled(p_shape_idx, p_disabled);
}
+void Physics2DServerSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable) {
-bool Physics2DServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const {
-
- const Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, false);
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
- ERR_FAIL_INDEX_V(p_shape_idx, body->get_shape_count(), false);
+ ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
- return body->is_shape_set_as_trigger(p_shape_idx);
+ body->set_shape_as_one_way_collision(p_shape_idx, p_enable);
}
void Physics2DServerSW::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) {
@@ -887,34 +895,6 @@ int Physics2DServerSW::body_get_max_contacts_reported(RID p_body) const {
return body->get_max_contacts_reported();
}
-void Physics2DServerSW::body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction) {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
- body->set_one_way_collision_direction(p_direction);
-}
-
-Vector2 Physics2DServerSW::body_get_one_way_collision_direction(RID p_body) const {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, Vector2());
- return body->get_one_way_collision_direction();
-}
-
-void Physics2DServerSW::body_set_one_way_collision_max_depth(RID p_body, real_t p_max_depth) {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
- body->set_one_way_collision_max_depth(p_max_depth);
-}
-
-real_t Physics2DServerSW::body_get_one_way_collision_max_depth(RID p_body) const {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, 0);
- return body->get_one_way_collision_max_depth();
-}
-
void Physics2DServerSW::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
Body2DSW *body = body_owner.get(p_body);
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index be67e3157d..9cbdfc598f 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -123,6 +123,8 @@ public:
virtual RID area_get_shape(RID p_area, int p_shape_idx) const;
virtual Transform2D area_get_shape_transform(RID p_area, int p_shape_idx) const;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled);
+
virtual void area_remove_shape(RID p_area, int p_shape_idx);
virtual void area_clear_shapes(RID p_area);
@@ -167,8 +169,8 @@ public:
virtual void body_remove_shape(RID p_body, int p_shape_idx);
virtual void body_clear_shapes(RID p_body);
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable);
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled);
+ virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled);
virtual void body_attach_object_instance_ID(RID p_body, uint32_t p_ID);
virtual uint32_t body_get_object_instance_ID(RID p_body) const;
@@ -212,12 +214,6 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts);
virtual int body_get_max_contacts_reported(RID p_body) const;
- virtual void body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction);
- virtual Vector2 body_get_one_way_collision_direction(RID p_body) const;
-
- virtual void body_set_one_way_collision_max_depth(RID p_body, real_t p_max_depth);
- virtual real_t body_get_one_way_collision_max_depth(RID p_body) const;
-
virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant());
virtual bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count);
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index 1026d84fd9..9fcfebef6b 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -145,6 +145,7 @@ public:
FUNC3(area_add_shape, RID, RID, const Transform2D &);
FUNC3(area_set_shape, RID, int, RID);
FUNC3(area_set_shape_transform, RID, int, const Transform2D &);
+ FUNC3(area_set_shape_disabled, RID, int, bool);
FUNC1RC(int, area_get_shape_count, RID);
FUNC2RC(RID, area_get_shape, RID, int);
@@ -191,8 +192,8 @@ public:
FUNC2RC(Variant, body_get_shape_metadata, RID, int);
FUNC2RC(RID, body_get_shape, RID, int);
- FUNC3(body_set_shape_as_trigger, RID, int, bool);
- FUNC2RC(bool, body_is_shape_set_as_trigger, RID, int);
+ FUNC3(body_set_shape_disabled, RID, int, bool);
+ FUNC3(body_set_shape_as_one_way_collision, RID, int, bool);
FUNC2(body_remove_shape, RID, int);
FUNC1(body_clear_shapes, RID);
@@ -232,12 +233,6 @@ public:
FUNC2(body_set_max_contacts_reported, RID, int);
FUNC1RC(int, body_get_max_contacts_reported, RID);
- FUNC2(body_set_one_way_collision_direction, RID, const Vector2 &);
- FUNC1RC(Vector2, body_get_one_way_collision_direction, RID);
-
- FUNC2(body_set_one_way_collision_max_depth, RID, real_t);
- FUNC1RC(real_t, body_get_one_way_collision_max_depth, RID);
-
FUNC2(body_set_contacts_reported_depth_treshold, RID, real_t);
FUNC1RC(real_t, body_get_contacts_reported_depth_treshold, RID);
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index fd94fc01cd..b197ba5905 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -265,14 +265,6 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
//test initial overlap
if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, p_margin)) {
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- //if one way collision direction ignore initial overlap
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
- continue;
- }
- }
-
return false;
}
@@ -297,27 +289,6 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
}
}
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
-
- Vector2 cd[2];
- Physics2DServerSW::CollCbkData cbk;
- cbk.max = 1;
- cbk.amount = 0;
- cbk.ptr = cd;
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
-
- Vector2 sep = mnormal; //important optimization for this to work fast enough
- bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * (hi + space->contact_max_allowed_penetration), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, p_margin);
- if (!collided || cbk.amount == 0) {
- continue;
- }
- }
- }
-
if (low < best_safe) {
best_safe = low;
best_unsafe = hi;
@@ -369,15 +340,9 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
if (p_exclude.has(col_obj->get_self()))
continue;
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
- } else {
- cbk.valid_dir = Vector2();
- cbk.valid_depth = 0;
- }
+ cbk.valid_dir = Vector2();
+ cbk.valid_depth = 0;
if (CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
collided = p_result_max == 0 || cbk.amount > 0;
@@ -407,13 +372,10 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
_RestCallbackData2D *rd = (_RestCallbackData2D *)p_userdata;
if (rd->valid_dir != Vector2()) {
-
- if (rd->valid_dir != Vector2()) {
- if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth)
- return;
- if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25)
- return;
- }
+ if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth)
+ return;
+ if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25)
+ return;
}
Vector2 contact_rel = p_point_B - p_point_A;
@@ -455,16 +417,8 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
if (p_exclude.has(col_obj->get_self()))
continue;
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- rcd.valid_dir = body->get_one_way_collision_direction();
- rcd.valid_depth = body->get_one_way_collision_max_depth();
- } else {
- rcd.valid_dir = Vector2();
- rcd.valid_depth = 0;
- }
-
+ rcd.valid_dir = Vector2();
+ rcd.valid_depth = 0;
rcd.object = col_obj;
rcd.shape = shape_idx;
bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
@@ -517,7 +471,7 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
keep = false;
else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self()))
keep = false;
- else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_trigger(intersection_query_subindex_results[i]))
+ else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i]))
keep = false;
if (!keep) {
@@ -589,7 +543,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_trigger(j))
+ if (p_body->is_shape_set_as_disabled(j))
continue;
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
@@ -599,18 +553,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
-
- Vector2 cdir = body->get_one_way_collision_direction();
- /*
- if (cdir!=Vector2() && p_motion.dot(cdir)<0)
- continue;
- */
+ if (col_obj->is_shape_set_as_one_way_collision(j)) {
- cbk.valid_dir = cdir;
- cbk.valid_depth = body->get_one_way_collision_max_depth();
+ cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ cbk.valid_depth = p_margin; //only valid depth is the collision margin
} else {
cbk.valid_dir = Vector2();
cbk.valid_depth = 0;
@@ -678,7 +624,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_trigger(j))
+ if (p_body->is_shape_set_as_disabled(j))
continue;
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
@@ -703,12 +649,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
//test initial overlap
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- //if one way collision direction ignore initial overlap
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
- continue;
- }
+ if (col_obj->is_shape_set_as_one_way_collision(j)) {
+ continue;
}
stuck = true;
@@ -720,7 +662,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
real_t hi = 1;
Vector2 mnormal = p_motion.normalized();
- for (int i = 0; i < 8; i++) { //steps should be customizable..
+ for (int k = 0; k < 8; k++) { //steps should be customizable..
real_t ofs = (low + hi) * 0.5;
@@ -739,15 +681,16 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
+ if (col_obj->is_shape_set_as_one_way_collision(j)) {
Vector2 cd[2];
Physics2DServerSW::CollCbkData cbk;
cbk.max = 1;
cbk.amount = 0;
cbk.ptr = cd;
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
+ cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ ;
+ cbk.valid_depth = 10e20;
Vector2 sep = mnormal; //important optimization for this to work fast enough
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, 0);
@@ -816,11 +759,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
+ if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- rcd.valid_dir = body->get_one_way_collision_direction();
- rcd.valid_depth = body->get_one_way_collision_max_depth();
+ rcd.valid_dir = body_shape_xform.get_axis(1).normalized();
+ rcd.valid_depth = 10e20;
} else {
rcd.valid_dir = Vector2();
rcd.valid_depth = 0;
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index 8ffa82214c..55ea2b41e7 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -496,6 +496,7 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform"), &Physics2DServer::area_add_shape, DEFVAL(Transform2D()));
ClassDB::bind_method(D_METHOD("area_set_shape", "area", "shape_idx", "shape"), &Physics2DServer::area_set_shape);
ClassDB::bind_method(D_METHOD("area_set_shape_transform", "area", "shape_idx", "transform"), &Physics2DServer::area_set_shape_transform);
+ ClassDB::bind_method(D_METHOD("area_set_shape_disabled", "area", "shape_idx", "disable"), &Physics2DServer::area_set_shape_disabled);
ClassDB::bind_method(D_METHOD("area_get_shape_count", "area"), &Physics2DServer::area_get_shape_count);
ClassDB::bind_method(D_METHOD("area_get_shape", "area", "shape_idx"), &Physics2DServer::area_get_shape);
@@ -539,8 +540,8 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_remove_shape", "body", "shape_idx"), &Physics2DServer::body_remove_shape);
ClassDB::bind_method(D_METHOD("body_clear_shapes", "body"), &Physics2DServer::body_clear_shapes);
- ClassDB::bind_method(D_METHOD("body_set_shape_as_trigger", "body", "shape_idx", "enable"), &Physics2DServer::body_set_shape_as_trigger);
- ClassDB::bind_method(D_METHOD("body_is_shape_set_as_trigger", "body", "shape_idx"), &Physics2DServer::body_is_shape_set_as_trigger);
+ ClassDB::bind_method(D_METHOD("body_set_shape_disabled", "body", "shape_idx", "disable"), &Physics2DServer::body_set_shape_disabled);
+ ClassDB::bind_method(D_METHOD("body_set_shape_as_one_way_collision", "body", "shape_idx", "enable"), &Physics2DServer::body_set_shape_as_one_way_collision);
ClassDB::bind_method(D_METHOD("body_attach_object_instance_ID", "body", "id"), &Physics2DServer::body_attach_object_instance_ID);
ClassDB::bind_method(D_METHOD("body_get_object_instance_ID", "body"), &Physics2DServer::body_get_object_instance_ID);
@@ -571,12 +572,6 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_max_contacts_reported", "body", "amount"), &Physics2DServer::body_set_max_contacts_reported);
ClassDB::bind_method(D_METHOD("body_get_max_contacts_reported", "body"), &Physics2DServer::body_get_max_contacts_reported);
- ClassDB::bind_method(D_METHOD("body_set_one_way_collision_direction", "body", "normal"), &Physics2DServer::body_set_one_way_collision_direction);
- ClassDB::bind_method(D_METHOD("body_get_one_way_collision_direction", "body"), &Physics2DServer::body_get_one_way_collision_direction);
-
- ClassDB::bind_method(D_METHOD("body_set_one_way_collision_max_depth", "body", "depth"), &Physics2DServer::body_set_one_way_collision_max_depth);
- ClassDB::bind_method(D_METHOD("body_get_one_way_collision_max_depth", "body"), &Physics2DServer::body_get_one_way_collision_max_depth);
-
ClassDB::bind_method(D_METHOD("body_set_omit_force_integration", "body", "enable"), &Physics2DServer::body_set_omit_force_integration);
ClassDB::bind_method(D_METHOD("body_is_omitting_force_integration", "body"), &Physics2DServer::body_is_omitting_force_integration);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 80113dd7d6..f25f05bafc 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -332,6 +332,8 @@ public:
virtual void area_remove_shape(RID p_area, int p_shape_idx) = 0;
virtual void area_clear_shapes(RID p_area) = 0;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) = 0;
+
virtual void area_attach_object_instance_ID(RID p_area, ObjectID p_ID) = 0;
virtual ObjectID area_get_object_instance_ID(RID p_area) const = 0;
@@ -380,8 +382,8 @@ public:
virtual Transform2D body_get_shape_transform(RID p_body, int p_shape_idx) const = 0;
virtual Variant body_get_shape_metadata(RID p_body, int p_shape_idx) const = 0;
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) = 0;
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const = 0;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled) = 0;
+ virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled) = 0;
virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0;
virtual void body_clear_shapes(RID p_body) = 0;
@@ -451,12 +453,6 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) = 0;
virtual int body_get_max_contacts_reported(RID p_body) const = 0;
- virtual void body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction) = 0;
- virtual Vector2 body_get_one_way_collision_direction(RID p_body) const = 0;
-
- virtual void body_set_one_way_collision_max_depth(RID p_body, float p_max_depth) = 0;
- virtual float body_get_one_way_collision_max_depth(RID p_body) const = 0;
-
//missing remove
virtual void body_set_contacts_reported_depth_treshold(RID p_body, float p_treshold) = 0;
virtual float body_get_contacts_reported_depth_treshold(RID p_body) const = 0;