diff options
Diffstat (limited to 'scene/2d/navigation_polygon.cpp')
-rw-r--r-- | scene/2d/navigation_polygon.cpp | 135 |
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); } |