-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!
This commit is contained in:
@@ -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) {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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 {
|
||||
Body2DSW *body = body_owner.get(p_body);
|
||||
ERR_FAIL_COND(!body);
|
||||
|
||||
const Body2DSW *body = body_owner.get(p_body);
|
||||
ERR_FAIL_COND_V(!body, false);
|
||||
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
|
||||
|
||||
ERR_FAIL_INDEX_V(p_shape_idx, body->get_shape_count(), false);
|
||||
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
if (col_obj->is_shape_set_as_one_way_collision(j)) {
|
||||
|
||||
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;
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user