Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NavigationPolygon: Implement get/set_polygon fast paths. #93171

Merged
merged 1 commit into from
Aug 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 51 additions & 15 deletions scene/resources/2d/navigation_polygon.cpp
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array
}
polygons.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
polygons.write[i].indices = p_array[i];
polygons.write[i] = p_array[i];
}
}

@@ -113,7 +113,7 @@ TypedArray<Vector<int32_t>> NavigationPolygon::_get_polygons() const {
TypedArray<Vector<int32_t>> ret;
ret.resize(polygons.size());
for (int i = 0; i < ret.size(); i++) {
ret[i] = polygons[i].indices;
ret[i] = polygons[i];
}

return ret;
@@ -141,9 +141,7 @@ TypedArray<Vector<Vector2>> NavigationPolygon::_get_outlines() const {

void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) {
RWLockWrite write_lock(rwlock);
Polygon polygon;
polygon.indices = p_polygon;
polygons.push_back(polygon);
polygons.push_back(p_polygon);
{
MutexLock lock(navigation_mesh_generation);
navigation_mesh.unref();
@@ -164,7 +162,7 @@ int NavigationPolygon::get_polygon_count() const {
Vector<int> NavigationPolygon::get_polygon(int p_idx) {
RWLockRead read_lock(rwlock);
ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
return polygons[p_idx].indices;
return polygons[p_idx];
}

void NavigationPolygon::clear_polygons() {
@@ -189,10 +187,19 @@ void NavigationPolygon::clear() {
void NavigationPolygon::set_data(const Vector<Vector2> &p_vertices, const Vector<Vector<int>> &p_polygons) {
RWLockWrite write_lock(rwlock);
vertices = p_vertices;
polygons.resize(p_polygons.size());
for (int i = 0; i < p_polygons.size(); i++) {
polygons.write[i].indices = p_polygons[i];
polygons = p_polygons;
{
MutexLock lock(navigation_mesh_generation);
navigation_mesh.unref();
}
}

void NavigationPolygon::set_data(const Vector<Vector2> &p_vertices, const Vector<Vector<int>> &p_polygons, const Vector<Vector<Vector2>> &p_outlines) {
RWLockWrite write_lock(rwlock);
vertices = p_vertices;
polygons = p_polygons;
outlines = p_outlines;
rect_cache_dirty = true;
{
MutexLock lock(navigation_mesh_generation);
navigation_mesh.unref();
@@ -202,10 +209,14 @@ void NavigationPolygon::set_data(const Vector<Vector2> &p_vertices, const Vector
void NavigationPolygon::get_data(Vector<Vector2> &r_vertices, Vector<Vector<int>> &r_polygons) {
RWLockRead read_lock(rwlock);
r_vertices = vertices;
r_polygons.resize(polygons.size());
for (int i = 0; i < polygons.size(); i++) {
r_polygons.write[i] = polygons[i].indices;
}
r_polygons = polygons;
}

void NavigationPolygon::get_data(Vector<Vector2> &r_vertices, Vector<Vector<int>> &r_polygons, Vector<Vector<Vector2>> &r_outlines) {
RWLockRead read_lock(rwlock);
r_vertices = vertices;
r_polygons = polygons;
r_outlines = outlines;
}

Ref<NavigationMesh> NavigationPolygon::get_navigation_mesh() {
@@ -237,6 +248,31 @@ Ref<NavigationMesh> NavigationPolygon::get_navigation_mesh() {
return navigation_mesh;
}

void NavigationPolygon::set_outlines(const Vector<Vector<Vector2>> &p_outlines) {
RWLockWrite write_lock(rwlock);
outlines = p_outlines;
rect_cache_dirty = true;
}

Vector<Vector<Vector2>> NavigationPolygon::get_outlines() const {
RWLockRead read_lock(rwlock);
return outlines;
}

void NavigationPolygon::set_polygons(const Vector<Vector<int>> &p_polygons) {
RWLockWrite write_lock(rwlock);
polygons = p_polygons;
{
MutexLock lock(navigation_mesh_generation);
navigation_mesh.unref();
}
}

Vector<Vector<int>> NavigationPolygon::get_polygons() const {
RWLockRead read_lock(rwlock);
return polygons;
}

void NavigationPolygon::add_outline(const Vector<Vector2> &p_outline) {
RWLockWrite write_lock(rwlock);
outlines.push_back(p_outline);
@@ -364,15 +400,15 @@ void NavigationPolygon::make_polygons_from_outlines() {
for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
TPPLPoly &tp = I->get();

struct Polygon p;
Vector<int> p;

for (int64_t i = 0; i < tp.GetNumPoints(); i++) {
HashMap<Vector2, int>::Iterator E = points.find(tp[i]);
if (!E) {
E = points.insert(tp[i], vertices.size());
vertices.push_back(tp[i]);
}
p.indices.push_back(E->value);
p.push_back(E->value);
}

polygons.push_back(p);
11 changes: 6 additions & 5 deletions scene/resources/2d/navigation_polygon.h
Original file line number Diff line number Diff line change
@@ -39,10 +39,7 @@ class NavigationPolygon : public Resource {
RWLock rwlock;

Vector<Vector2> vertices;
struct Polygon {
Vector<int> indices;
};
Vector<Polygon> polygons;
Vector<Vector<int>> polygons;
Vector<Vector<Vector2>> outlines;
Vector<Vector<Vector2>> baked_outlines;

@@ -109,14 +106,16 @@ class NavigationPolygon : public Resource {
Vector<Vector2> get_outline(int p_idx) const;
void remove_outline(int p_idx);
int get_outline_count() const;
void set_outlines(const Vector<Vector<Vector2>> &p_outlines);
Vector<Vector<Vector2>> get_outlines() const;

void clear_outlines();
#ifndef DISABLE_DEPRECATED
void make_polygons_from_outlines();
#endif // DISABLE_DEPRECATED

void set_polygons(const Vector<Vector<int>> &p_polygons);
const Vector<Vector<int>> &get_polygons() const;
Vector<Vector<int>> get_polygons() const;
Vector<int> get_polygon(int p_idx);
void clear_polygons();

@@ -155,7 +154,9 @@ class NavigationPolygon : public Resource {
void clear();

void set_data(const Vector<Vector2> &p_vertices, const Vector<Vector<int>> &p_polygons);
void set_data(const Vector<Vector2> &p_vertices, const Vector<Vector<int>> &p_polygons, const Vector<Vector<Vector2>> &p_outlines);
void get_data(Vector<Vector2> &r_vertices, Vector<Vector<int>> &r_polygons);
void get_data(Vector<Vector2> &r_vertices, Vector<Vector<int>> &r_polygons, Vector<Vector<Vector2>> &r_outlines);

NavigationPolygon() {}
~NavigationPolygon() {}
17 changes: 9 additions & 8 deletions scene/resources/2d/tile_set.cpp
Original file line number Diff line number Diff line change
@@ -6502,18 +6502,19 @@ Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_f
transformed_polygon.instantiate();

PackedVector2Array new_points = get_transformed_vertices(layer_tile_data.navigation_polygon->get_vertices(), p_flip_h, p_flip_v, p_transpose);
transformed_polygon->set_vertices(new_points);

int num_polygons = layer_tile_data.navigation_polygon->get_polygon_count();
for (int i = 0; i < num_polygons; ++i) {
transformed_polygon->add_polygon(layer_tile_data.navigation_polygon->get_polygon(i));
}
const Vector<Vector<Vector2>> outlines = layer_tile_data.navigation_polygon->get_outlines();
int outline_count = outlines.size();

Vector<Vector<Vector2>> new_outlines;
new_outlines.resize(outline_count);

for (int i = 0; i < layer_tile_data.navigation_polygon->get_outline_count(); i++) {
PackedVector2Array new_outline = get_transformed_vertices(layer_tile_data.navigation_polygon->get_outline(i), p_flip_h, p_flip_v, p_transpose);
transformed_polygon->add_outline(new_outline);
for (int i = 0; i < outline_count; i++) {
new_outlines.write[i] = get_transformed_vertices(outlines[i], p_flip_h, p_flip_v, p_transpose);
}

transformed_polygon->set_data(new_points, layer_tile_data.navigation_polygon->get_polygons(), new_outlines);

layer_tile_data.transformed_navigation_polygon[key] = transformed_polygon;
return transformed_polygon;
} else {
19 changes: 7 additions & 12 deletions scene/resources/3d/importer_mesh.cpp
Original file line number Diff line number Diff line change
@@ -1108,9 +1108,12 @@ Ref<NavigationMesh> ImporterMesh::create_navigation_mesh() {
}

HashMap<Vector3, int> unique_vertices;
LocalVector<int> face_indices;
Vector<Vector<int>> face_polygons;
face_polygons.resize(faces.size());

for (int i = 0; i < faces.size(); i++) {
Vector<int> face_indices;
face_indices.resize(3);
for (int j = 0; j < 3; j++) {
Vector3 v = faces[i].vertex[j];
int idx;
@@ -1120,8 +1123,9 @@ Ref<NavigationMesh> ImporterMesh::create_navigation_mesh() {
idx = unique_vertices.size();
unique_vertices[v] = idx;
}
face_indices.push_back(idx);
face_indices.write[j] = idx;
}
face_polygons.write[i] = face_indices;
}

Vector<Vector3> vertices;
@@ -1132,16 +1136,7 @@ Ref<NavigationMesh> ImporterMesh::create_navigation_mesh() {

Ref<NavigationMesh> nm;
nm.instantiate();
nm->set_vertices(vertices);

Vector<int> v3;
v3.resize(3);
for (uint32_t i = 0; i < face_indices.size(); i += 3) {
v3.write[0] = face_indices[i + 0];
v3.write[1] = face_indices[i + 1];
v3.write[2] = face_indices[i + 2];
nm->add_polygon(v3);
}
nm->set_data(vertices, face_polygons);

return nm;
}
41 changes: 22 additions & 19 deletions scene/resources/navigation_mesh.cpp
Original file line number Diff line number Diff line change
@@ -61,12 +61,12 @@ void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
int rlen = iarr.size();
const int *r = iarr.ptr();

Vector<int> polygon;
for (int j = 0; j < rlen; j += 3) {
Polygon polygon;
polygon.indices.resize(3);
polygon.indices.write[0] = r[j + 0] + from;
polygon.indices.write[1] = r[j + 1] + from;
polygon.indices.write[2] = r[j + 2] + from;
polygon.resize(3);
polygon.write[0] = r[j + 0] + from;
polygon.write[1] = r[j + 1] + from;
polygon.write[2] = r[j + 2] + from;
polygons.push_back(polygon);
}
}
@@ -318,7 +318,7 @@ void NavigationMesh::_set_polygons(const Array &p_array) {
RWLockWrite write_lock(rwlock);
polygons.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
polygons.write[i].indices = p_array[i];
polygons.write[i] = p_array[i];
}
notify_property_list_changed();
}
@@ -328,17 +328,26 @@ Array NavigationMesh::_get_polygons() const {
Array ret;
ret.resize(polygons.size());
for (int i = 0; i < ret.size(); i++) {
ret[i] = polygons[i].indices;
ret[i] = polygons[i];
}

return ret;
}

void NavigationMesh::set_polygons(const Vector<Vector<int>> &p_polygons) {
RWLockWrite write_lock(rwlock);
polygons = p_polygons;
notify_property_list_changed();
}

Vector<Vector<int>> NavigationMesh::get_polygons() const {
RWLockRead read_lock(rwlock);
return polygons;
}

void NavigationMesh::add_polygon(const Vector<int> &p_polygon) {
RWLockWrite write_lock(rwlock);
Polygon polygon;
polygon.indices = p_polygon;
polygons.push_back(polygon);
polygons.push_back(p_polygon);
notify_property_list_changed();
}

@@ -350,7 +359,7 @@ int NavigationMesh::get_polygon_count() const {
Vector<int> NavigationMesh::get_polygon(int p_idx) {
RWLockRead read_lock(rwlock);
ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
return polygons[p_idx].indices;
return polygons[p_idx];
}

void NavigationMesh::clear_polygons() {
@@ -367,19 +376,13 @@ void NavigationMesh::clear() {
void NavigationMesh::set_data(const Vector<Vector3> &p_vertices, const Vector<Vector<int>> &p_polygons) {
RWLockWrite write_lock(rwlock);
vertices = p_vertices;
polygons.resize(p_polygons.size());
for (int i = 0; i < p_polygons.size(); i++) {
polygons.write[i].indices = p_polygons[i];
}
polygons = p_polygons;
}

void NavigationMesh::get_data(Vector<Vector3> &r_vertices, Vector<Vector<int>> &r_polygons) {
RWLockRead read_lock(rwlock);
r_vertices = vertices;
r_polygons.resize(polygons.size());
for (int i = 0; i < polygons.size(); i++) {
r_polygons.write[i] = polygons[i].indices;
}
r_polygons = polygons;
}

#ifdef DEBUG_ENABLED
7 changes: 3 additions & 4 deletions scene/resources/navigation_mesh.h
Original file line number Diff line number Diff line change
@@ -39,10 +39,7 @@ class NavigationMesh : public Resource {
RWLock rwlock;

Vector<Vector3> vertices;
struct Polygon {
Vector<int> indices;
};
Vector<Polygon> polygons;
Vector<Vector<int>> polygons;
Ref<ArrayMesh> debug_mesh;

protected:
@@ -194,6 +191,8 @@ class NavigationMesh : public Resource {
int get_polygon_count() const;
Vector<int> get_polygon(int p_idx);
void clear_polygons();
void set_polygons(const Vector<Vector<int>> &p_polygons);
Vector<Vector<int>> get_polygons() const;

void clear();