|
@@ -41,6 +41,12 @@ void NavigationMeshSourceGeometryData3D::set_indices(const Vector<int> &p_indice
|
|
|
void NavigationMeshSourceGeometryData3D::clear() {
|
|
|
vertices.clear();
|
|
|
indices.clear();
|
|
|
+ clear_projected_obstructions();
|
|
|
+}
|
|
|
+
|
|
|
+void NavigationMeshSourceGeometryData3D::clear_projected_obstructions() {
|
|
|
+ RWLockWrite write_lock(geometry_rwlock);
|
|
|
+ _projected_obstructions.clear();
|
|
|
}
|
|
|
|
|
|
void NavigationMeshSourceGeometryData3D::_add_vertex(const Vector3 &p_vec3) {
|
|
@@ -174,6 +180,121 @@ void NavigationMeshSourceGeometryData3D::merge(const Ref<NavigationMeshSourceGeo
|
|
|
for (int64_t i = number_of_indices_before_merge; i < indices.size(); i++) {
|
|
|
indices.set(i, indices[i] + number_of_vertices_before_merge / 3);
|
|
|
}
|
|
|
+
|
|
|
+ if (p_other_geometry->_projected_obstructions.size() > 0) {
|
|
|
+ RWLockWrite write_lock(geometry_rwlock);
|
|
|
+
|
|
|
+ for (const ProjectedObstruction &other_projected_obstruction : p_other_geometry->_projected_obstructions) {
|
|
|
+ ProjectedObstruction projected_obstruction;
|
|
|
+ projected_obstruction.vertices.resize(other_projected_obstruction.vertices.size());
|
|
|
+
|
|
|
+ const float *other_obstruction_vertices_ptr = other_projected_obstruction.vertices.ptr();
|
|
|
+ float *obstruction_vertices_ptrw = projected_obstruction.vertices.ptrw();
|
|
|
+
|
|
|
+ for (int j = 0; j < other_projected_obstruction.vertices.size(); j++) {
|
|
|
+ obstruction_vertices_ptrw[j] = other_obstruction_vertices_ptr[j];
|
|
|
+ }
|
|
|
+
|
|
|
+ projected_obstruction.elevation = other_projected_obstruction.elevation;
|
|
|
+ projected_obstruction.height = other_projected_obstruction.height;
|
|
|
+ projected_obstruction.carve = other_projected_obstruction.carve;
|
|
|
+
|
|
|
+ _projected_obstructions.push_back(projected_obstruction);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void NavigationMeshSourceGeometryData3D::add_projected_obstruction(const Vector<Vector3> &p_vertices, float p_elevation, float p_height, bool p_carve) {
|
|
|
+ ERR_FAIL_COND(p_vertices.size() < 3);
|
|
|
+ ERR_FAIL_COND(p_height < 0.0);
|
|
|
+
|
|
|
+ ProjectedObstruction projected_obstruction;
|
|
|
+ projected_obstruction.vertices.resize(p_vertices.size() * 3);
|
|
|
+ projected_obstruction.elevation = p_elevation;
|
|
|
+ projected_obstruction.height = p_height;
|
|
|
+ projected_obstruction.carve = p_carve;
|
|
|
+
|
|
|
+ float *obstruction_vertices_ptrw = projected_obstruction.vertices.ptrw();
|
|
|
+
|
|
|
+ int vertex_index = 0;
|
|
|
+ for (const Vector3 &vertex : p_vertices) {
|
|
|
+ obstruction_vertices_ptrw[vertex_index++] = vertex.x;
|
|
|
+ obstruction_vertices_ptrw[vertex_index++] = vertex.y;
|
|
|
+ obstruction_vertices_ptrw[vertex_index++] = vertex.z;
|
|
|
+ }
|
|
|
+
|
|
|
+ RWLockWrite write_lock(geometry_rwlock);
|
|
|
+ _projected_obstructions.push_back(projected_obstruction);
|
|
|
+}
|
|
|
+
|
|
|
+void NavigationMeshSourceGeometryData3D::set_projected_obstructions(const Array &p_array) {
|
|
|
+ clear_projected_obstructions();
|
|
|
+
|
|
|
+ for (int i = 0; i < p_array.size(); i++) {
|
|
|
+ Dictionary data = p_array[i];
|
|
|
+ ERR_FAIL_COND(!data.has("version"));
|
|
|
+
|
|
|
+ uint32_t po_version = data["version"];
|
|
|
+
|
|
|
+ if (po_version == 1) {
|
|
|
+ ERR_FAIL_COND(!data.has("vertices"));
|
|
|
+ ERR_FAIL_COND(!data.has("elevation"));
|
|
|
+ ERR_FAIL_COND(!data.has("height"));
|
|
|
+ ERR_FAIL_COND(!data.has("carve"));
|
|
|
+ }
|
|
|
+
|
|
|
+ ProjectedObstruction projected_obstruction;
|
|
|
+ projected_obstruction.vertices = Vector<float>(data["vertices"]);
|
|
|
+ projected_obstruction.elevation = data["elevation"];
|
|
|
+ projected_obstruction.height = data["height"];
|
|
|
+ projected_obstruction.carve = data["carve"];
|
|
|
+
|
|
|
+ RWLockWrite write_lock(geometry_rwlock);
|
|
|
+ _projected_obstructions.push_back(projected_obstruction);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+Vector<NavigationMeshSourceGeometryData3D::ProjectedObstruction> NavigationMeshSourceGeometryData3D::_get_projected_obstructions() const {
|
|
|
+ RWLockRead read_lock(geometry_rwlock);
|
|
|
+ return _projected_obstructions;
|
|
|
+}
|
|
|
+
|
|
|
+Array NavigationMeshSourceGeometryData3D::get_projected_obstructions() const {
|
|
|
+ RWLockRead read_lock(geometry_rwlock);
|
|
|
+
|
|
|
+ Array ret;
|
|
|
+ ret.resize(_projected_obstructions.size());
|
|
|
+
|
|
|
+ for (int i = 0; i < _projected_obstructions.size(); i++) {
|
|
|
+ const ProjectedObstruction &projected_obstruction = _projected_obstructions[i];
|
|
|
+
|
|
|
+ Dictionary data;
|
|
|
+ data["version"] = (int)ProjectedObstruction::VERSION;
|
|
|
+ data["vertices"] = projected_obstruction.vertices;
|
|
|
+ data["elevation"] = projected_obstruction.elevation;
|
|
|
+ data["height"] = projected_obstruction.height;
|
|
|
+ data["carve"] = projected_obstruction.carve;
|
|
|
+
|
|
|
+ ret[i] = data;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+bool NavigationMeshSourceGeometryData3D::_set(const StringName &p_name, const Variant &p_value) {
|
|
|
+ if (p_name == "projected_obstructions") {
|
|
|
+ set_projected_obstructions(p_value);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool NavigationMeshSourceGeometryData3D::_get(const StringName &p_name, Variant &r_ret) const {
|
|
|
+ if (p_name == "projected_obstructions") {
|
|
|
+ r_ret = get_projected_obstructions();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
void NavigationMeshSourceGeometryData3D::_bind_methods() {
|
|
@@ -191,6 +312,12 @@ void NavigationMeshSourceGeometryData3D::_bind_methods() {
|
|
|
ClassDB::bind_method(D_METHOD("add_faces", "faces", "xform"), &NavigationMeshSourceGeometryData3D::add_faces);
|
|
|
ClassDB::bind_method(D_METHOD("merge", "other_geometry"), &NavigationMeshSourceGeometryData3D::merge);
|
|
|
|
|
|
+ ClassDB::bind_method(D_METHOD("add_projected_obstruction", "vertices", "elevation", "height", "carve"), &NavigationMeshSourceGeometryData3D::add_projected_obstruction);
|
|
|
+ ClassDB::bind_method(D_METHOD("clear_projected_obstructions"), &NavigationMeshSourceGeometryData3D::clear_projected_obstructions);
|
|
|
+ ClassDB::bind_method(D_METHOD("set_projected_obstructions", "projected_obstructions"), &NavigationMeshSourceGeometryData3D::set_projected_obstructions);
|
|
|
+ ClassDB::bind_method(D_METHOD("get_projected_obstructions"), &NavigationMeshSourceGeometryData3D::get_projected_obstructions);
|
|
|
+
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices");
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "indices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_indices", "get_indices");
|
|
|
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "projected_obstructions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_projected_obstructions", "get_projected_obstructions");
|
|
|
}
|