summaryrefslogtreecommitdiff
path: root/scene/2d/collision_polygon_2d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d/collision_polygon_2d.cpp')
-rw-r--r--scene/2d/collision_polygon_2d.cpp186
1 files changed, 83 insertions, 103 deletions
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 6b603c6473..bd669eb4c8 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -35,13 +35,9 @@
#include "thirdparty/misc/triangulator.h"
-void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
+void CollisionPolygon2D::_build_polygon() {
- if (unparenting || !can_update_body)
- return;
-
- CollisionObject2D *co = p_obj->cast_to<CollisionObject2D>();
- ERR_FAIL_COND(!co);
+ parent->shape_owner_clear_shapes(owner_id);
if (polygon.size() == 0)
return;
@@ -53,18 +49,10 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
//here comes the sun, lalalala
//decompose concave into multiple convex polygons and add them
Vector<Vector<Vector2> > decomp = _decompose_in_convex();
- shape_from = co->get_shape_count();
for (int i = 0; i < decomp.size(); i++) {
Ref<ConvexPolygonShape2D> convex = memnew(ConvexPolygonShape2D);
convex->set_points(decomp[i]);
- co->add_shape(convex, get_transform());
- if (trigger)
- co->set_shape_as_trigger(co->get_shape_count() - 1, true);
- }
- shape_to = co->get_shape_count() - 1;
- if (shape_to < shape_from) {
- shape_from = -1;
- shape_to = -1;
+ parent->shape_owner_add_shape(owner_id, convex);
}
} else {
@@ -83,28 +71,8 @@ void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) {
w = PoolVector<Vector2>::Write();
concave->set_segments(segments);
- co->add_shape(concave, get_transform());
- if (trigger)
- co->set_shape_as_trigger(co->get_shape_count() - 1, true);
-
- shape_from = co->get_shape_count() - 1;
- shape_to = co->get_shape_count() - 1;
+ parent->shape_owner_add_shape(owner_id, concave);
}
-
- //co->add_shape(shape,get_transform());
-}
-
-void CollisionPolygon2D::_update_parent() {
-
- if (!can_update_body)
- return;
- Node *parent = get_parent();
- if (!parent)
- return;
- CollisionObject2D *co = parent->cast_to<CollisionObject2D>();
- if (!co)
- return;
- co->_update_shapes_from_children();
}
Vector<Vector<Vector2> > CollisionPolygon2D::_decompose_in_convex() {
@@ -155,33 +123,38 @@ Vector<Vector<Vector2> > CollisionPolygon2D::_decompose_in_convex() {
void CollisionPolygon2D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- unparenting = false;
- can_update_body = get_tree()->is_editor_hint();
- if (!get_tree()->is_editor_hint()) {
+ case NOTIFICATION_PARENTED: {
+
+ parent = get_parent()->cast_to<CollisionObject2D>();
+ if (parent) {
+ owner_id = parent->create_shape_owner(this);
+ _build_polygon();
+ parent->shape_owner_set_transform(owner_id, get_transform());
+ parent->shape_owner_set_disabled(owner_id, disabled);
+ parent->shape_owner_set_one_way_collision(owner_id, one_way_collision);
+ }
+
+ /*if (get_tree()->is_editor_hint()) {
//display above all else
set_z_as_relative(false);
set_z(VS::CANVAS_ITEM_Z_MAX - 1);
- }
+ }*/
} break;
- case NOTIFICATION_EXIT_TREE: {
- can_update_body = false;
- } break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
- if (!is_inside_tree())
- break;
- if (can_update_body) {
- _update_parent();
- } else if (shape_from >= 0 && shape_to >= 0) {
- CollisionObject2D *co = get_parent()->cast_to<CollisionObject2D>();
- for (int i = shape_from; i <= shape_to; i++) {
- co->set_shape_transform(i, get_transform());
- }
+ if (parent) {
+ parent->shape_owner_set_transform(owner_id, get_transform());
}
} break;
+ case NOTIFICATION_UNPARENTED: {
+ if (parent) {
+ parent->remove_shape_owner(owner_id);
+ }
+ owner_id = 0;
+ parent = NULL;
+ } break;
case NOTIFICATION_DRAW: {
@@ -210,10 +183,22 @@ void CollisionPolygon2D::_notification(int p_what) {
draw_colored_polygon(polygon, get_tree()->get_debug_collisions_color());
#endif
- } break;
- case NOTIFICATION_UNPARENTED: {
- unparenting = true;
- _update_parent();
+ if (one_way_collision) {
+ Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
+ dcol.a = 1.0;
+ Vector2 line_to(0, 20);
+ draw_line(Vector2(), line_to, dcol, 3);
+ Vector<Vector2> pts;
+ float tsize = 8;
+ pts.push_back(line_to + (Vector2(0, tsize)));
+ pts.push_back(line_to + (Vector2(0.707 * tsize, 0)));
+ pts.push_back(line_to + (Vector2(-0.707 * tsize, 0)));
+ Vector<Color> cols;
+ for (int i = 0; i < 3; i++)
+ cols.push_back(dcol);
+
+ draw_primitive(pts, cols, Vector<Vector2>()); //small arrow
+ }
} break;
}
}
@@ -222,7 +207,7 @@ void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) {
polygon = p_polygon;
- if (can_update_body) {
+ {
for (int i = 0; i < polygon.size(); i++) {
if (i == 0)
aabb = Rect2(polygon[i], Size2());
@@ -236,7 +221,10 @@ void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) {
aabb.position -= aabb.size * 0.3;
aabb.size += aabb.size * 0.6;
}
- _update_parent();
+ }
+
+ if (parent) {
+ _build_polygon();
}
update();
update_configuration_warning();
@@ -251,7 +239,9 @@ void CollisionPolygon2D::set_build_mode(BuildMode p_mode) {
ERR_FAIL_INDEX(p_mode, 2);
build_mode = p_mode;
- _update_parent();
+ if (parent) {
+ _build_polygon();
+ }
}
CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const {
@@ -264,79 +254,69 @@ Rect2 CollisionPolygon2D::get_item_rect() const {
return aabb;
}
-void CollisionPolygon2D::set_trigger(bool p_trigger) {
+String CollisionPolygon2D::get_configuration_warning() const {
- trigger = p_trigger;
- _update_parent();
- if (!can_update_body && is_inside_tree() && shape_from >= 0 && shape_to >= 0) {
- CollisionObject2D *co = get_parent()->cast_to<CollisionObject2D>();
- for (int i = shape_from; i <= shape_to; i++) {
- co->set_shape_as_trigger(i, p_trigger);
- }
+ if (!get_parent()->cast_to<CollisionObject2D>()) {
+ return TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
}
-}
-bool CollisionPolygon2D::is_trigger() const {
+ if (polygon.empty()) {
+ return TTR("An empty CollisionPolygon2D has no effect on collision.");
+ }
- return trigger;
+ return String();
}
-void CollisionPolygon2D::_set_shape_range(const Vector2 &p_range) {
-
- shape_from = p_range.x;
- shape_to = p_range.y;
+void CollisionPolygon2D::set_disabled(bool p_disabled) {
+ disabled = p_disabled;
+ update();
+ if (parent) {
+ parent->shape_owner_set_disabled(owner_id, p_disabled);
+ }
}
-Vector2 CollisionPolygon2D::_get_shape_range() const {
-
- return Vector2(shape_from, shape_to);
+bool CollisionPolygon2D::is_disabled() const {
+ return disabled;
}
-String CollisionPolygon2D::get_configuration_warning() const {
-
- if (!get_parent()->cast_to<CollisionObject2D>()) {
- return TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
+void CollisionPolygon2D::set_one_way_collision(bool p_enable) {
+ one_way_collision = p_enable;
+ update();
+ if (parent) {
+ parent->shape_owner_set_one_way_collision(owner_id, p_enable);
}
+}
- if (polygon.empty()) {
- return TTR("An empty CollisionPolygon2D has no effect on collision.");
- }
+bool CollisionPolygon2D::is_one_way_collision_enabled() const {
- return String();
+ return one_way_collision;
}
void CollisionPolygon2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_add_to_collision_object"), &CollisionPolygon2D::_add_to_collision_object);
ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &CollisionPolygon2D::set_polygon);
ClassDB::bind_method(D_METHOD("get_polygon"), &CollisionPolygon2D::get_polygon);
ClassDB::bind_method(D_METHOD("set_build_mode", "build_mode"), &CollisionPolygon2D::set_build_mode);
ClassDB::bind_method(D_METHOD("get_build_mode"), &CollisionPolygon2D::get_build_mode);
-
- ClassDB::bind_method(D_METHOD("set_trigger", "trigger"), &CollisionPolygon2D::set_trigger);
- ClassDB::bind_method(D_METHOD("is_trigger"), &CollisionPolygon2D::is_trigger);
-
- ClassDB::bind_method(D_METHOD("_set_shape_range", "shape_range"), &CollisionPolygon2D::_set_shape_range);
- ClassDB::bind_method(D_METHOD("_get_shape_range"), &CollisionPolygon2D::_get_shape_range);
-
- ClassDB::bind_method(D_METHOD("get_collision_object_first_shape"), &CollisionPolygon2D::get_collision_object_first_shape);
- ClassDB::bind_method(D_METHOD("get_collision_object_last_shape"), &CollisionPolygon2D::get_collision_object_last_shape);
+ ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &CollisionPolygon2D::set_disabled);
+ ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionPolygon2D::is_disabled);
+ ClassDB::bind_method(D_METHOD("set_one_way_collision", "enabled"), &CollisionPolygon2D::set_one_way_collision);
+ ClassDB::bind_method(D_METHOD("is_one_way_collision_enabled"), &CollisionPolygon2D::is_one_way_collision_enabled);
ADD_PROPERTY(PropertyInfo(Variant::INT, "build_mode", PROPERTY_HINT_ENUM, "Solids,Segments"), "set_build_mode", "get_build_mode");
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shape_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_shape_range", "_get_shape_range");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trigger"), "set_trigger", "is_trigger");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled");
}
CollisionPolygon2D::CollisionPolygon2D() {
aabb = Rect2(-10, -10, 20, 20);
build_mode = BUILD_SOLIDS;
- trigger = false;
- unparenting = false;
- shape_from = -1;
- shape_to = -1;
- can_update_body = false;
set_notify_local_transform(true);
+ parent = NULL;
+ owner_id = 0;
+ disabled = false;
+ one_way_collision = false;
}