feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -32,11 +32,17 @@
|
|||
|
||||
#include "nav_map.h"
|
||||
|
||||
#include "3d/nav_map_builder_3d.h"
|
||||
#include "3d/nav_mesh_queries_3d.h"
|
||||
#include "3d/nav_region_iteration_3d.h"
|
||||
|
||||
void NavRegion::set_map(NavMap *p_map) {
|
||||
if (map == p_map) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancel_sync_request();
|
||||
|
||||
if (map) {
|
||||
map->remove_region(this);
|
||||
}
|
||||
|
|
@ -44,10 +50,9 @@ void NavRegion::set_map(NavMap *p_map) {
|
|||
map = p_map;
|
||||
polygons_dirty = true;
|
||||
|
||||
connections.clear();
|
||||
|
||||
if (map) {
|
||||
map->add_region(this);
|
||||
request_sync();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -59,13 +64,17 @@ void NavRegion::set_enabled(bool p_enabled) {
|
|||
|
||||
// TODO: This should not require a full rebuild as the region has not really changed.
|
||||
polygons_dirty = true;
|
||||
};
|
||||
|
||||
request_sync();
|
||||
}
|
||||
|
||||
void NavRegion::set_use_edge_connections(bool p_enabled) {
|
||||
if (use_edge_connections != p_enabled) {
|
||||
use_edge_connections = p_enabled;
|
||||
polygons_dirty = true;
|
||||
}
|
||||
|
||||
request_sync();
|
||||
}
|
||||
|
||||
void NavRegion::set_transform(Transform3D p_transform) {
|
||||
|
|
@ -75,6 +84,8 @@ void NavRegion::set_transform(Transform3D p_transform) {
|
|||
transform = p_transform;
|
||||
polygons_dirty = true;
|
||||
|
||||
request_sync();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (map && Math::rad_to_deg(map->get_up().angle_to(transform.basis.get_column(1))) >= 90.0f) {
|
||||
ERR_PRINT_ONCE("Attempted to update a navigation region transform rotated 90 degrees or more away from the current navigation map UP orientation.");
|
||||
|
|
@ -103,111 +114,81 @@ void NavRegion::set_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh) {
|
|||
}
|
||||
|
||||
polygons_dirty = true;
|
||||
|
||||
request_sync();
|
||||
}
|
||||
|
||||
int NavRegion::get_connections_count() const {
|
||||
if (!map) {
|
||||
return 0;
|
||||
}
|
||||
return connections.size();
|
||||
Vector3 NavRegion::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const {
|
||||
RWLockRead read_lock(region_rwlock);
|
||||
|
||||
return NavMeshQueries3D::polygons_get_closest_point_to_segment(
|
||||
get_polygons(), p_from, p_to, p_use_collision);
|
||||
}
|
||||
|
||||
Vector3 NavRegion::get_connection_pathway_start(int p_connection_id) const {
|
||||
ERR_FAIL_NULL_V(map, Vector3());
|
||||
ERR_FAIL_INDEX_V(p_connection_id, connections.size(), Vector3());
|
||||
return connections[p_connection_id].pathway_start;
|
||||
}
|
||||
gd::ClosestPointQueryResult NavRegion::get_closest_point_info(const Vector3 &p_point) const {
|
||||
RWLockRead read_lock(region_rwlock);
|
||||
|
||||
Vector3 NavRegion::get_connection_pathway_end(int p_connection_id) const {
|
||||
ERR_FAIL_NULL_V(map, Vector3());
|
||||
ERR_FAIL_INDEX_V(p_connection_id, connections.size(), Vector3());
|
||||
return connections[p_connection_id].pathway_end;
|
||||
return NavMeshQueries3D::polygons_get_closest_point_info(get_polygons(), p_point);
|
||||
}
|
||||
|
||||
Vector3 NavRegion::get_random_point(uint32_t p_navigation_layers, bool p_uniformly) const {
|
||||
RWLockRead read_lock(region_rwlock);
|
||||
|
||||
if (!get_enabled()) {
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
const LocalVector<gd::Polygon> ®ion_polygons = get_polygons();
|
||||
return NavMeshQueries3D::polygons_get_random_point(get_polygons(), p_navigation_layers, p_uniformly);
|
||||
}
|
||||
|
||||
if (region_polygons.is_empty()) {
|
||||
return Vector3();
|
||||
void NavRegion::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||
if (navigation_layers == p_navigation_layers) {
|
||||
return;
|
||||
}
|
||||
navigation_layers = p_navigation_layers;
|
||||
region_dirty = true;
|
||||
|
||||
if (p_uniformly) {
|
||||
real_t accumulated_area = 0;
|
||||
RBMap<real_t, uint32_t> region_area_map;
|
||||
request_sync();
|
||||
}
|
||||
|
||||
for (uint32_t rp_index = 0; rp_index < region_polygons.size(); rp_index++) {
|
||||
const gd::Polygon ®ion_polygon = region_polygons[rp_index];
|
||||
real_t polyon_area = region_polygon.surface_area;
|
||||
|
||||
if (polyon_area == 0.0) {
|
||||
continue;
|
||||
}
|
||||
region_area_map[accumulated_area] = rp_index;
|
||||
accumulated_area += polyon_area;
|
||||
}
|
||||
if (region_area_map.is_empty() || accumulated_area == 0) {
|
||||
// All polygons have no real surface / no area.
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
real_t region_area_map_pos = Math::random(real_t(0), accumulated_area);
|
||||
|
||||
RBMap<real_t, uint32_t>::Iterator region_E = region_area_map.find_closest(region_area_map_pos);
|
||||
ERR_FAIL_COND_V(!region_E, Vector3());
|
||||
uint32_t rrp_polygon_index = region_E->value;
|
||||
ERR_FAIL_UNSIGNED_INDEX_V(rrp_polygon_index, region_polygons.size(), Vector3());
|
||||
|
||||
const gd::Polygon &rr_polygon = region_polygons[rrp_polygon_index];
|
||||
|
||||
real_t accumulated_polygon_area = 0;
|
||||
RBMap<real_t, uint32_t> polygon_area_map;
|
||||
|
||||
for (uint32_t rpp_index = 2; rpp_index < rr_polygon.points.size(); rpp_index++) {
|
||||
real_t face_area = Face3(rr_polygon.points[0].pos, rr_polygon.points[rpp_index - 1].pos, rr_polygon.points[rpp_index].pos).get_area();
|
||||
|
||||
if (face_area == 0.0) {
|
||||
continue;
|
||||
}
|
||||
polygon_area_map[accumulated_polygon_area] = rpp_index;
|
||||
accumulated_polygon_area += face_area;
|
||||
}
|
||||
if (polygon_area_map.is_empty() || accumulated_polygon_area == 0) {
|
||||
// All faces have no real surface / no area.
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
real_t polygon_area_map_pos = Math::random(real_t(0), accumulated_polygon_area);
|
||||
|
||||
RBMap<real_t, uint32_t>::Iterator polygon_E = polygon_area_map.find_closest(polygon_area_map_pos);
|
||||
ERR_FAIL_COND_V(!polygon_E, Vector3());
|
||||
uint32_t rrp_face_index = polygon_E->value;
|
||||
ERR_FAIL_UNSIGNED_INDEX_V(rrp_face_index, rr_polygon.points.size(), Vector3());
|
||||
|
||||
const Face3 face(rr_polygon.points[0].pos, rr_polygon.points[rrp_face_index - 1].pos, rr_polygon.points[rrp_face_index].pos);
|
||||
|
||||
Vector3 face_random_position = face.get_random_point_inside();
|
||||
return face_random_position;
|
||||
|
||||
} else {
|
||||
uint32_t rrp_polygon_index = Math::random(int(0), region_polygons.size() - 1);
|
||||
|
||||
const gd::Polygon &rr_polygon = region_polygons[rrp_polygon_index];
|
||||
|
||||
uint32_t rrp_face_index = Math::random(int(2), rr_polygon.points.size() - 1);
|
||||
|
||||
const Face3 face(rr_polygon.points[0].pos, rr_polygon.points[rrp_face_index - 1].pos, rr_polygon.points[rrp_face_index].pos);
|
||||
|
||||
Vector3 face_random_position = face.get_random_point_inside();
|
||||
return face_random_position;
|
||||
void NavRegion::set_enter_cost(real_t p_enter_cost) {
|
||||
real_t new_enter_cost = MAX(p_enter_cost, 0.0);
|
||||
if (enter_cost == new_enter_cost) {
|
||||
return;
|
||||
}
|
||||
enter_cost = new_enter_cost;
|
||||
region_dirty = true;
|
||||
|
||||
request_sync();
|
||||
}
|
||||
|
||||
void NavRegion::set_travel_cost(real_t p_travel_cost) {
|
||||
real_t new_travel_cost = MAX(p_travel_cost, 0.0);
|
||||
if (travel_cost == new_travel_cost) {
|
||||
return;
|
||||
}
|
||||
travel_cost = new_travel_cost;
|
||||
region_dirty = true;
|
||||
|
||||
request_sync();
|
||||
}
|
||||
|
||||
void NavRegion::set_owner_id(ObjectID p_owner_id) {
|
||||
if (owner_id == p_owner_id) {
|
||||
return;
|
||||
}
|
||||
owner_id = p_owner_id;
|
||||
region_dirty = true;
|
||||
|
||||
request_sync();
|
||||
}
|
||||
|
||||
bool NavRegion::sync() {
|
||||
bool something_changed = polygons_dirty /* || something_dirty? */;
|
||||
RWLockWrite write_lock(region_rwlock);
|
||||
|
||||
bool something_changed = region_dirty || polygons_dirty;
|
||||
|
||||
region_dirty = false;
|
||||
|
||||
update_polygons();
|
||||
|
||||
|
|
@ -218,8 +199,9 @@ void NavRegion::update_polygons() {
|
|||
if (!polygons_dirty) {
|
||||
return;
|
||||
}
|
||||
polygons.clear();
|
||||
navmesh_polygons.clear();
|
||||
surface_area = 0.0;
|
||||
bounds = AABB();
|
||||
polygons_dirty = false;
|
||||
|
||||
if (map == nullptr) {
|
||||
|
|
@ -239,14 +221,15 @@ void NavRegion::update_polygons() {
|
|||
|
||||
const Vector3 *vertices_r = pending_navmesh_vertices.ptr();
|
||||
|
||||
polygons.resize(pending_navmesh_polygons.size());
|
||||
navmesh_polygons.resize(pending_navmesh_polygons.size());
|
||||
|
||||
real_t _new_region_surface_area = 0.0;
|
||||
AABB _new_bounds;
|
||||
|
||||
// Build
|
||||
bool first_vertex = true;
|
||||
int navigation_mesh_polygon_index = 0;
|
||||
for (gd::Polygon &polygon : polygons) {
|
||||
polygon.owner = this;
|
||||
|
||||
for (gd::Polygon &polygon : navmesh_polygons) {
|
||||
polygon.surface_area = 0.0;
|
||||
|
||||
Vector<int> navigation_mesh_polygon = pending_navmesh_polygons[navigation_mesh_polygon_index];
|
||||
|
|
@ -286,7 +269,14 @@ void NavRegion::update_polygons() {
|
|||
|
||||
Vector3 point_position = transform.xform(vertices_r[idx]);
|
||||
polygon.points[j].pos = point_position;
|
||||
polygon.points[j].key = map->get_point_key(point_position);
|
||||
polygon.points[j].key = NavMapBuilder3D::get_point_key(point_position, map->get_merge_rasterizer_cell_size());
|
||||
|
||||
if (first_vertex) {
|
||||
first_vertex = false;
|
||||
_new_bounds.position = point_position;
|
||||
} else {
|
||||
_new_bounds.expand_to(point_position);
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
|
|
@ -295,4 +285,49 @@ void NavRegion::update_polygons() {
|
|||
}
|
||||
|
||||
surface_area = _new_region_surface_area;
|
||||
bounds = _new_bounds;
|
||||
}
|
||||
|
||||
void NavRegion::get_iteration_update(NavRegionIteration &r_iteration) {
|
||||
r_iteration.navigation_layers = get_navigation_layers();
|
||||
r_iteration.enter_cost = get_enter_cost();
|
||||
r_iteration.travel_cost = get_travel_cost();
|
||||
r_iteration.owner_object_id = get_owner_id();
|
||||
r_iteration.owner_type = get_type();
|
||||
r_iteration.owner_rid = get_self();
|
||||
|
||||
r_iteration.enabled = get_enabled();
|
||||
r_iteration.transform = get_transform();
|
||||
r_iteration.owner_use_edge_connections = get_use_edge_connections();
|
||||
r_iteration.bounds = get_bounds();
|
||||
r_iteration.surface_area = get_surface_area();
|
||||
|
||||
r_iteration.navmesh_polygons.clear();
|
||||
r_iteration.navmesh_polygons.resize(navmesh_polygons.size());
|
||||
for (uint32_t i = 0; i < navmesh_polygons.size(); i++) {
|
||||
gd::Polygon &navmesh_polygon = navmesh_polygons[i];
|
||||
navmesh_polygon.owner = &r_iteration;
|
||||
r_iteration.navmesh_polygons[i] = navmesh_polygon;
|
||||
}
|
||||
}
|
||||
|
||||
void NavRegion::request_sync() {
|
||||
if (map && !sync_dirty_request_list_element.in_list()) {
|
||||
map->add_region_sync_dirty_request(&sync_dirty_request_list_element);
|
||||
}
|
||||
}
|
||||
|
||||
void NavRegion::cancel_sync_request() {
|
||||
if (map && sync_dirty_request_list_element.in_list()) {
|
||||
map->remove_region_sync_dirty_request(&sync_dirty_request_list_element);
|
||||
}
|
||||
}
|
||||
|
||||
NavRegion::NavRegion() :
|
||||
sync_dirty_request_list_element(this) {
|
||||
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_REGION;
|
||||
}
|
||||
|
||||
NavRegion::~NavRegion() {
|
||||
cancel_sync_request();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue