summaryrefslogtreecommitdiff
path: root/scene/2d/navigation_polygon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d/navigation_polygon.cpp')
-rw-r--r--scene/2d/navigation_polygon.cpp135
1 files changed, 85 insertions, 50 deletions
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index 883fb37668..6754c1c9a6 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -32,7 +32,9 @@
#include "core/core_string_names.h"
#include "core/engine.h"
+#include "core/os/mutex.h"
#include "navigation_2d.h"
+#include "servers/navigation_2d_server.h"
#include "thirdparty/misc/triangulator.h"
@@ -44,11 +46,11 @@ Rect2 NavigationPolygon::_edit_get_rect() const {
bool first = true;
for (int i = 0; i < outlines.size(); i++) {
- const PoolVector<Vector2> &outline = outlines[i];
+ const Vector<Vector2> &outline = outlines[i];
const int outline_size = outline.size();
if (outline_size < 3)
continue;
- PoolVector<Vector2>::Read p = outline.read();
+ const Vector2 *p = outline.ptr();
for (int j = 0; j < outline_size; j++) {
if (first) {
item_rect = Rect2(p[j], Vector2(0, 0));
@@ -67,7 +69,7 @@ Rect2 NavigationPolygon::_edit_get_rect() const {
bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
for (int i = 0; i < outlines.size(); i++) {
- const PoolVector<Vector2> &outline = outlines[i];
+ const Vector<Vector2> &outline = outlines[i];
const int outline_size = outline.size();
if (outline_size < 3)
continue;
@@ -78,19 +80,25 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double
}
#endif
-void NavigationPolygon::set_vertices(const PoolVector<Vector2> &p_vertices) {
+void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) {
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
vertices = p_vertices;
rect_cache_dirty = true;
}
-PoolVector<Vector2> NavigationPolygon::get_vertices() const {
+Vector<Vector2> NavigationPolygon::get_vertices() const {
return vertices;
}
void NavigationPolygon::_set_polygons(const Array &p_array) {
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
polygons.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
polygons.write[i].indices = p_array[i];
@@ -133,9 +141,12 @@ void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) {
Polygon polygon;
polygon.indices = p_polygon;
polygons.push_back(polygon);
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
}
-void NavigationPolygon::add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index) {
+void NavigationPolygon::add_outline_at_index(const Vector<Vector2> &p_outline, int p_index) {
outlines.insert(p_index, p_outline);
rect_cache_dirty = true;
@@ -153,9 +164,37 @@ Vector<int> NavigationPolygon::get_polygon(int p_idx) {
void NavigationPolygon::clear_polygons() {
polygons.clear();
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
}
-void NavigationPolygon::add_outline(const PoolVector<Vector2> &p_outline) {
+Ref<NavigationMesh> NavigationPolygon::get_mesh() {
+ navmesh_generation->lock();
+ if (navmesh.is_null()) {
+ navmesh.instance();
+ Vector<Vector3> verts;
+ {
+ verts.resize(get_vertices().size());
+ Vector3 *w = verts.ptrw();
+
+ const Vector2 *r = get_vertices().ptr();
+
+ for (int i(0); i < get_vertices().size(); i++) {
+ w[i] = Vector3(r[i].x, 0.0, r[i].y);
+ }
+ }
+ navmesh->set_vertices(verts);
+
+ for (int i(0); i < get_polygon_count(); i++) {
+ navmesh->add_polygon(get_polygon(i));
+ }
+ }
+ navmesh_generation->unlock();
+ return navmesh;
+}
+
+void NavigationPolygon::add_outline(const Vector<Vector2> &p_outline) {
outlines.push_back(p_outline);
rect_cache_dirty = true;
@@ -166,7 +205,7 @@ int NavigationPolygon::get_outline_count() const {
return outlines.size();
}
-void NavigationPolygon::set_outline(int p_idx, const PoolVector<Vector2> &p_outline) {
+void NavigationPolygon::set_outline(int p_idx, const Vector<Vector2> &p_outline) {
ERR_FAIL_INDEX(p_idx, outlines.size());
outlines.write[p_idx] = p_outline;
rect_cache_dirty = true;
@@ -179,8 +218,8 @@ void NavigationPolygon::remove_outline(int p_idx) {
rect_cache_dirty = true;
}
-PoolVector<Vector2> NavigationPolygon::get_outline(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, outlines.size(), PoolVector<Vector2>());
+Vector<Vector2> NavigationPolygon::get_outline(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, outlines.size(), Vector<Vector2>());
return outlines[p_idx];
}
@@ -191,17 +230,20 @@ void NavigationPolygon::clear_outlines() {
}
void NavigationPolygon::make_polygons_from_outlines() {
+ navmesh_generation->lock();
+ navmesh.unref();
+ navmesh_generation->unlock();
List<TriangulatorPoly> in_poly, out_poly;
Vector2 outside_point(-1e10, -1e10);
for (int i = 0; i < outlines.size(); i++) {
- PoolVector<Vector2> ol = outlines[i];
+ Vector<Vector2> ol = outlines[i];
int olsize = ol.size();
if (olsize < 3)
continue;
- PoolVector<Vector2>::Read r = ol.read();
+ const Vector2 *r = ol.ptr();
for (int j = 0; j < olsize; j++) {
outside_point.x = MAX(r[j].x, outside_point.x);
outside_point.y = MAX(r[j].y, outside_point.y);
@@ -212,11 +254,11 @@ void NavigationPolygon::make_polygons_from_outlines() {
for (int i = 0; i < outlines.size(); i++) {
- PoolVector<Vector2> ol = outlines[i];
+ Vector<Vector2> ol = outlines[i];
int olsize = ol.size();
if (olsize < 3)
continue;
- PoolVector<Vector2>::Read r = ol.read();
+ const Vector2 *r = ol.ptr();
int interscount = 0;
//test if this is an outer outline
@@ -225,11 +267,11 @@ void NavigationPolygon::make_polygons_from_outlines() {
if (i == k)
continue; //no self intersect
- PoolVector<Vector2> ol2 = outlines[k];
+ Vector<Vector2> ol2 = outlines[k];
int olsize2 = ol2.size();
if (olsize2 < 3)
continue;
- PoolVector<Vector2>::Read r2 = ol2.read();
+ const Vector2 *r2 = ol2.ptr();
for (int l = 0; l < olsize2; l++) {
@@ -314,13 +356,18 @@ void NavigationPolygon::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_outlines", "outlines"), &NavigationPolygon::_set_outlines);
ClassDB::bind_method(D_METHOD("_get_outlines"), &NavigationPolygon::_get_outlines);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines");
}
NavigationPolygon::NavigationPolygon() :
- rect_cache_dirty(true) {
+ rect_cache_dirty(true),
+ navmesh_generation(Mutex::create()) {
+}
+
+NavigationPolygon::~NavigationPolygon() {
+ memdelete(navmesh_generation);
}
void NavigationPolygonInstance::set_enabled(bool p_enabled) {
@@ -334,18 +381,12 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) {
if (!enabled) {
- if (nav_id != -1) {
- navigation->navpoly_remove(nav_id);
- nav_id = -1;
- }
+ Navigation2DServer::get_singleton()->region_set_map(region, RID());
} else {
if (navigation) {
- if (navpoly.is_valid()) {
-
- nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this);
- }
+ Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid());
}
}
@@ -382,9 +423,9 @@ void NavigationPolygonInstance::_notification(int p_what) {
navigation = Object::cast_to<Navigation2D>(c);
if (navigation) {
- if (enabled && navpoly.is_valid()) {
+ if (enabled) {
- nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this);
+ Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid());
}
break;
}
@@ -395,19 +436,14 @@ void NavigationPolygonInstance::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
- if (navigation && nav_id != -1) {
- navigation->navpoly_set_transform(nav_id, get_relative_transform_to_parent(navigation));
- }
+ Navigation2DServer::get_singleton()->region_set_transform(region, get_global_transform());
} break;
case NOTIFICATION_EXIT_TREE: {
if (navigation) {
- if (nav_id != -1) {
- navigation->navpoly_remove(nav_id);
- nav_id = -1;
- }
+ Navigation2DServer::get_singleton()->region_set_map(region, RID());
}
navigation = NULL;
} break;
@@ -415,7 +451,7 @@ void NavigationPolygonInstance::_notification(int p_what) {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) {
- PoolVector<Vector2> verts = navpoly->get_vertices();
+ Vector<Vector2> verts = navpoly->get_vertices();
int vsize = verts.size();
if (vsize < 3)
return;
@@ -431,7 +467,7 @@ void NavigationPolygonInstance::_notification(int p_what) {
vertices.resize(vsize);
colors.resize(vsize);
{
- PoolVector<Vector2>::Read vr = verts.read();
+ const Vector2 *vr = verts.ptr();
for (int i = 0; i < vsize; i++) {
vertices.write[i] = vr[i];
colors.write[i] = color;
@@ -466,24 +502,18 @@ void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolyg
return;
}
- if (navigation && nav_id != -1) {
- navigation->navpoly_remove(nav_id);
- nav_id = -1;
- }
-
if (navpoly.is_valid()) {
- navpoly->disconnect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed");
+ navpoly->disconnect_compat(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed");
}
+
navpoly = p_navpoly;
+ Navigation2DServer::get_singleton()->region_set_navpoly(region, p_navpoly);
+
if (navpoly.is_valid()) {
- navpoly->connect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed");
+ navpoly->connect_compat(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed");
}
_navpoly_changed();
- if (navigation && navpoly.is_valid() && enabled) {
- nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this);
- }
-
_change_notify("navpoly");
update_configuration_warning();
}
@@ -536,8 +566,13 @@ void NavigationPolygonInstance::_bind_methods() {
NavigationPolygonInstance::NavigationPolygonInstance() {
- navigation = NULL;
- nav_id = -1;
enabled = true;
set_notify_transform(true);
+ region = Navigation2DServer::get_singleton()->region_create();
+
+ navigation = NULL;
+}
+
+NavigationPolygonInstance::~NavigationPolygonInstance() {
+ Navigation2DServer::get_singleton()->free(region);
}