You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-10 13:00:37 +00:00
Add NavigationServer random point queries
Adds query functions to get random points on navigation mesh to the NavigationServer.
This commit is contained in:
@@ -769,6 +769,70 @@ void NavMap::remove_agent_as_controlled(NavAgent *agent) {
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 NavMap::get_random_point(uint32_t p_navigation_layers, bool p_uniformly) const {
|
||||
const LocalVector<NavRegion *> map_regions = get_regions();
|
||||
|
||||
if (map_regions.is_empty()) {
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
LocalVector<const NavRegion *> accessible_regions;
|
||||
|
||||
for (const NavRegion *region : map_regions) {
|
||||
if (!region->get_enabled() || (p_navigation_layers & region->get_navigation_layers()) == 0) {
|
||||
continue;
|
||||
}
|
||||
accessible_regions.push_back(region);
|
||||
}
|
||||
|
||||
if (accessible_regions.is_empty()) {
|
||||
// All existing region polygons are disabled.
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
if (p_uniformly) {
|
||||
real_t accumulated_region_surface_area = 0;
|
||||
RBMap<real_t, uint32_t> accessible_regions_area_map;
|
||||
|
||||
for (uint32_t accessible_region_index = 0; accessible_region_index < accessible_regions.size(); accessible_region_index++) {
|
||||
const NavRegion *region = accessible_regions[accessible_region_index];
|
||||
|
||||
real_t region_surface_area = region->get_surface_area();
|
||||
|
||||
if (region_surface_area == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
accessible_regions_area_map[accumulated_region_surface_area] = accessible_region_index;
|
||||
accumulated_region_surface_area += region_surface_area;
|
||||
}
|
||||
if (accessible_regions_area_map.is_empty() || accumulated_region_surface_area == 0) {
|
||||
// All faces have no real surface / no area.
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
real_t random_accessible_regions_area_map = Math::random(real_t(0), accumulated_region_surface_area);
|
||||
|
||||
RBMap<real_t, uint32_t>::Iterator E = accessible_regions_area_map.find_closest(random_accessible_regions_area_map);
|
||||
ERR_FAIL_COND_V(!E, Vector3());
|
||||
uint32_t random_region_index = E->value;
|
||||
ERR_FAIL_INDEX_V(random_region_index, accessible_regions.size(), Vector3());
|
||||
|
||||
const NavRegion *random_region = accessible_regions[random_region_index];
|
||||
ERR_FAIL_NULL_V(random_region, Vector3());
|
||||
|
||||
return random_region->get_random_point(p_navigation_layers, p_uniformly);
|
||||
|
||||
} else {
|
||||
uint32_t random_region_index = Math::random(int(0), accessible_regions.size() - 1);
|
||||
|
||||
const NavRegion *random_region = accessible_regions[random_region_index];
|
||||
ERR_FAIL_NULL_V(random_region, Vector3());
|
||||
|
||||
return random_region->get_random_point(p_navigation_layers, p_uniformly);
|
||||
}
|
||||
}
|
||||
|
||||
void NavMap::sync() {
|
||||
// Performance Monitor
|
||||
int _new_pm_region_count = regions.size();
|
||||
|
||||
Reference in New Issue
Block a user