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
|
|
@ -237,11 +237,29 @@ real_t GodotNavigationServer3D::map_get_link_connection_radius(RID p_map) const
|
|||
return map->get_link_connection_radius();
|
||||
}
|
||||
|
||||
Vector<Vector3> GodotNavigationServer3D::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers) const {
|
||||
Vector<Vector3> GodotNavigationServer3D::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers) {
|
||||
const NavMap *map = map_owner.get_or_null(p_map);
|
||||
ERR_FAIL_NULL_V(map, Vector<Vector3>());
|
||||
|
||||
return map->get_path(p_origin, p_destination, p_optimize, p_navigation_layers, nullptr, nullptr, nullptr);
|
||||
Ref<NavigationPathQueryParameters3D> query_parameters;
|
||||
query_parameters.instantiate();
|
||||
|
||||
query_parameters->set_map(p_map);
|
||||
query_parameters->set_start_position(p_origin);
|
||||
query_parameters->set_target_position(p_destination);
|
||||
query_parameters->set_navigation_layers(p_navigation_layers);
|
||||
query_parameters->set_pathfinding_algorithm(NavigationPathQueryParameters3D::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR);
|
||||
query_parameters->set_path_postprocessing(NavigationPathQueryParameters3D::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL);
|
||||
if (!p_optimize) {
|
||||
query_parameters->set_path_postprocessing(NavigationPathQueryParameters3D::PATH_POSTPROCESSING_EDGECENTERED);
|
||||
}
|
||||
|
||||
Ref<NavigationPathQueryResult3D> query_result;
|
||||
query_result.instantiate();
|
||||
|
||||
query_path(query_parameters, query_result);
|
||||
|
||||
return query_result->get_path();
|
||||
}
|
||||
|
||||
Vector3 GodotNavigationServer3D::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
|
||||
|
|
@ -346,6 +364,19 @@ RID GodotNavigationServer3D::agent_get_map(RID p_agent) const {
|
|||
return RID();
|
||||
}
|
||||
|
||||
COMMAND_2(map_set_use_async_iterations, RID, p_map, bool, p_enabled) {
|
||||
NavMap *map = map_owner.get_or_null(p_map);
|
||||
ERR_FAIL_NULL(map);
|
||||
map->set_use_async_iterations(p_enabled);
|
||||
}
|
||||
|
||||
bool GodotNavigationServer3D::map_get_use_async_iterations(RID p_map) const {
|
||||
const NavMap *map = map_owner.get_or_null(p_map);
|
||||
ERR_FAIL_NULL_V(map, false);
|
||||
|
||||
return map->get_use_async_iterations();
|
||||
}
|
||||
|
||||
Vector3 GodotNavigationServer3D::map_get_random_point(RID p_map, uint32_t p_navigation_layers, bool p_uniformly) const {
|
||||
const NavMap *map = map_owner.get_or_null(p_map);
|
||||
ERR_FAIL_NULL_V(map, Vector3());
|
||||
|
|
@ -509,22 +540,52 @@ void GodotNavigationServer3D::region_bake_navigation_mesh(Ref<NavigationMesh> p_
|
|||
int GodotNavigationServer3D::region_get_connections_count(RID p_region) const {
|
||||
NavRegion *region = region_owner.get_or_null(p_region);
|
||||
ERR_FAIL_NULL_V(region, 0);
|
||||
|
||||
return region->get_connections_count();
|
||||
NavMap *map = region->get_map();
|
||||
if (map) {
|
||||
return map->get_region_connections_count(region);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vector3 GodotNavigationServer3D::region_get_connection_pathway_start(RID p_region, int p_connection_id) const {
|
||||
NavRegion *region = region_owner.get_or_null(p_region);
|
||||
ERR_FAIL_NULL_V(region, Vector3());
|
||||
|
||||
return region->get_connection_pathway_start(p_connection_id);
|
||||
NavMap *map = region->get_map();
|
||||
if (map) {
|
||||
return map->get_region_connection_pathway_start(region, p_connection_id);
|
||||
}
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
Vector3 GodotNavigationServer3D::region_get_connection_pathway_end(RID p_region, int p_connection_id) const {
|
||||
NavRegion *region = region_owner.get_or_null(p_region);
|
||||
ERR_FAIL_NULL_V(region, Vector3());
|
||||
NavMap *map = region->get_map();
|
||||
if (map) {
|
||||
return map->get_region_connection_pathway_end(region, p_connection_id);
|
||||
}
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
return region->get_connection_pathway_end(p_connection_id);
|
||||
Vector3 GodotNavigationServer3D::region_get_closest_point_to_segment(RID p_region, const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const {
|
||||
const NavRegion *region = region_owner.get_or_null(p_region);
|
||||
ERR_FAIL_NULL_V(region, Vector3());
|
||||
|
||||
return region->get_closest_point_to_segment(p_from, p_to, p_use_collision);
|
||||
}
|
||||
|
||||
Vector3 GodotNavigationServer3D::region_get_closest_point(RID p_region, const Vector3 &p_point) const {
|
||||
const NavRegion *region = region_owner.get_or_null(p_region);
|
||||
ERR_FAIL_NULL_V(region, Vector3());
|
||||
|
||||
return region->get_closest_point_info(p_point).point;
|
||||
}
|
||||
|
||||
Vector3 GodotNavigationServer3D::region_get_closest_point_normal(RID p_region, const Vector3 &p_point) const {
|
||||
const NavRegion *region = region_owner.get_or_null(p_region);
|
||||
ERR_FAIL_NULL_V(region, Vector3());
|
||||
|
||||
return region->get_closest_point_info(p_point).normal;
|
||||
}
|
||||
|
||||
Vector3 GodotNavigationServer3D::region_get_random_point(RID p_region, uint32_t p_navigation_layers, bool p_uniformly) const {
|
||||
|
|
@ -534,6 +595,13 @@ Vector3 GodotNavigationServer3D::region_get_random_point(RID p_region, uint32_t
|
|||
return region->get_random_point(p_navigation_layers, p_uniformly);
|
||||
}
|
||||
|
||||
AABB GodotNavigationServer3D::region_get_bounds(RID p_region) const {
|
||||
const NavRegion *region = region_owner.get_or_null(p_region);
|
||||
ERR_FAIL_NULL_V(region, AABB());
|
||||
|
||||
return region->get_bounds();
|
||||
}
|
||||
|
||||
RID GodotNavigationServer3D::link_create() {
|
||||
MutexLock lock(operations_mutex);
|
||||
|
||||
|
|
@ -1102,7 +1170,7 @@ uint32_t GodotNavigationServer3D::obstacle_get_avoidance_layers(RID p_obstacle)
|
|||
void GodotNavigationServer3D::parse_source_geometry_data(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, Node *p_root_node, const Callable &p_callback) {
|
||||
#ifndef _3D_DISABLED
|
||||
ERR_FAIL_COND_MSG(!Thread::is_main_thread(), "The SceneTree can only be parsed on the main thread. Call this function from the main thread or use call_deferred().");
|
||||
ERR_FAIL_COND_MSG(!p_navigation_mesh.is_valid(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_MSG(p_navigation_mesh.is_null(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_NULL_MSG(p_root_node, "No parsing root node specified.");
|
||||
ERR_FAIL_COND_MSG(!p_root_node->is_inside_tree(), "The root node needs to be inside the SceneTree.");
|
||||
|
||||
|
|
@ -1113,8 +1181,8 @@ void GodotNavigationServer3D::parse_source_geometry_data(const Ref<NavigationMes
|
|||
|
||||
void GodotNavigationServer3D::bake_from_source_geometry_data(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, const Callable &p_callback) {
|
||||
#ifndef _3D_DISABLED
|
||||
ERR_FAIL_COND_MSG(!p_navigation_mesh.is_valid(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_MSG(!p_source_geometry_data.is_valid(), "Invalid NavigationMeshSourceGeometryData3D.");
|
||||
ERR_FAIL_COND_MSG(p_navigation_mesh.is_null(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_MSG(p_source_geometry_data.is_null(), "Invalid NavigationMeshSourceGeometryData3D.");
|
||||
|
||||
ERR_FAIL_NULL(NavMeshGenerator3D::get_singleton());
|
||||
NavMeshGenerator3D::get_singleton()->bake_from_source_geometry_data(p_navigation_mesh, p_source_geometry_data, p_callback);
|
||||
|
|
@ -1123,8 +1191,8 @@ void GodotNavigationServer3D::bake_from_source_geometry_data(const Ref<Navigatio
|
|||
|
||||
void GodotNavigationServer3D::bake_from_source_geometry_data_async(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, const Callable &p_callback) {
|
||||
#ifndef _3D_DISABLED
|
||||
ERR_FAIL_COND_MSG(!p_navigation_mesh.is_valid(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_MSG(!p_source_geometry_data.is_valid(), "Invalid NavigationMeshSourceGeometryData3D.");
|
||||
ERR_FAIL_COND_MSG(p_navigation_mesh.is_null(), "Invalid navigation mesh.");
|
||||
ERR_FAIL_COND_MSG(p_source_geometry_data.is_null(), "Invalid NavigationMeshSourceGeometryData3D.");
|
||||
|
||||
ERR_FAIL_NULL(NavMeshGenerator3D::get_singleton());
|
||||
NavMeshGenerator3D::get_singleton()->bake_from_source_geometry_data_async(p_navigation_mesh, p_source_geometry_data, p_callback);
|
||||
|
|
@ -1202,10 +1270,17 @@ COMMAND_1(free, RID, p_object) {
|
|||
} else if (obstacle_owner.owns(p_object)) {
|
||||
internal_free_obstacle(p_object);
|
||||
|
||||
} else if (geometry_parser_owner.owns(p_object)) {
|
||||
RWLockWrite write_lock(geometry_parser_rwlock);
|
||||
|
||||
NavMeshGeometryParser3D *parser = geometry_parser_owner.get_or_null(p_object);
|
||||
ERR_FAIL_NULL(parser);
|
||||
|
||||
generator_parsers.erase(parser);
|
||||
#ifndef _3D_DISABLED
|
||||
} else if (navmesh_generator_3d && navmesh_generator_3d->owns(p_object)) {
|
||||
navmesh_generator_3d->free(p_object);
|
||||
#endif // _3D_DISABLED
|
||||
NavMeshGenerator3D::get_singleton()->set_generator_parsers(generator_parsers);
|
||||
#endif
|
||||
geometry_parser_owner.free(parser->self);
|
||||
|
||||
} else {
|
||||
ERR_PRINT("Attempted to free a NavigationServer RID that did not exist (or was already freed).");
|
||||
|
|
@ -1298,6 +1373,7 @@ void GodotNavigationServer3D::process(real_t p_delta_time) {
|
|||
int _new_pm_edge_merge_count = 0;
|
||||
int _new_pm_edge_connection_count = 0;
|
||||
int _new_pm_edge_free_count = 0;
|
||||
int _new_pm_obstacle_count = 0;
|
||||
|
||||
// In c++ we can't be sure that this is performed in the main thread
|
||||
// even with mutable functions.
|
||||
|
|
@ -1315,6 +1391,7 @@ void GodotNavigationServer3D::process(real_t p_delta_time) {
|
|||
_new_pm_edge_merge_count += active_maps[i]->get_pm_edge_merge_count();
|
||||
_new_pm_edge_connection_count += active_maps[i]->get_pm_edge_connection_count();
|
||||
_new_pm_edge_free_count += active_maps[i]->get_pm_edge_free_count();
|
||||
_new_pm_obstacle_count += active_maps[i]->get_pm_obstacle_count();
|
||||
|
||||
// Emit a signal if a map changed.
|
||||
const uint32_t new_map_iteration_id = active_maps[i]->get_iteration_id();
|
||||
|
|
@ -1332,11 +1409,14 @@ void GodotNavigationServer3D::process(real_t p_delta_time) {
|
|||
pm_edge_merge_count = _new_pm_edge_merge_count;
|
||||
pm_edge_connection_count = _new_pm_edge_connection_count;
|
||||
pm_edge_free_count = _new_pm_edge_free_count;
|
||||
pm_obstacle_count = _new_pm_obstacle_count;
|
||||
}
|
||||
|
||||
void GodotNavigationServer3D::init() {
|
||||
#ifndef _3D_DISABLED
|
||||
navmesh_generator_3d = memnew(NavMeshGenerator3D);
|
||||
RWLockRead read_lock(geometry_parser_rwlock);
|
||||
navmesh_generator_3d->set_generator_parsers(generator_parsers);
|
||||
#endif // _3D_DISABLED
|
||||
}
|
||||
|
||||
|
|
@ -1351,103 +1431,38 @@ void GodotNavigationServer3D::finish() {
|
|||
#endif // _3D_DISABLED
|
||||
}
|
||||
|
||||
PathQueryResult GodotNavigationServer3D::_query_path(const PathQueryParameters &p_parameters) const {
|
||||
PathQueryResult r_query_result;
|
||||
void GodotNavigationServer3D::query_path(const Ref<NavigationPathQueryParameters3D> &p_query_parameters, Ref<NavigationPathQueryResult3D> p_query_result, const Callable &p_callback) {
|
||||
ERR_FAIL_COND(p_query_parameters.is_null());
|
||||
ERR_FAIL_COND(p_query_result.is_null());
|
||||
|
||||
const NavMap *map = map_owner.get_or_null(p_parameters.map);
|
||||
ERR_FAIL_NULL_V(map, r_query_result);
|
||||
NavMap *map = map_owner.get_or_null(p_query_parameters->get_map());
|
||||
ERR_FAIL_NULL(map);
|
||||
|
||||
// run the pathfinding
|
||||
|
||||
if (p_parameters.pathfinding_algorithm == PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR) {
|
||||
// while postprocessing is still part of map.get_path() need to check and route it here for the correct "optimize" post-processing
|
||||
if (p_parameters.path_postprocessing == PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL) {
|
||||
r_query_result.path = map->get_path(
|
||||
p_parameters.start_position,
|
||||
p_parameters.target_position,
|
||||
true,
|
||||
p_parameters.navigation_layers,
|
||||
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_TYPES) ? &r_query_result.path_types : nullptr,
|
||||
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_RIDS) ? &r_query_result.path_rids : nullptr,
|
||||
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_OWNERS) ? &r_query_result.path_owner_ids : nullptr);
|
||||
} else if (p_parameters.path_postprocessing == PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED) {
|
||||
r_query_result.path = map->get_path(
|
||||
p_parameters.start_position,
|
||||
p_parameters.target_position,
|
||||
false,
|
||||
p_parameters.navigation_layers,
|
||||
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_TYPES) ? &r_query_result.path_types : nullptr,
|
||||
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_RIDS) ? &r_query_result.path_rids : nullptr,
|
||||
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_OWNERS) ? &r_query_result.path_owner_ids : nullptr);
|
||||
}
|
||||
} else {
|
||||
return r_query_result;
|
||||
}
|
||||
|
||||
// add path postprocessing
|
||||
|
||||
if (r_query_result.path.size() > 2 && p_parameters.simplify_path) {
|
||||
const LocalVector<uint32_t> &simplified_path_indices = get_simplified_path_indices(r_query_result.path, p_parameters.simplify_epsilon);
|
||||
|
||||
uint32_t indices_count = simplified_path_indices.size();
|
||||
|
||||
{
|
||||
Vector3 *w = r_query_result.path.ptrw();
|
||||
const Vector3 *r = r_query_result.path.ptr();
|
||||
for (uint32_t i = 0; i < indices_count; i++) {
|
||||
w[i] = r[simplified_path_indices[i]];
|
||||
}
|
||||
r_query_result.path.resize(indices_count);
|
||||
}
|
||||
|
||||
if (p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_TYPES)) {
|
||||
int32_t *w = r_query_result.path_types.ptrw();
|
||||
const int32_t *r = r_query_result.path_types.ptr();
|
||||
for (uint32_t i = 0; i < indices_count; i++) {
|
||||
w[i] = r[simplified_path_indices[i]];
|
||||
}
|
||||
r_query_result.path_types.resize(indices_count);
|
||||
}
|
||||
|
||||
if (p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_RIDS)) {
|
||||
TypedArray<RID> simplified_path_rids;
|
||||
simplified_path_rids.resize(indices_count);
|
||||
for (uint32_t i = 0; i < indices_count; i++) {
|
||||
simplified_path_rids[i] = r_query_result.path_rids[i];
|
||||
}
|
||||
r_query_result.path_rids = simplified_path_rids;
|
||||
}
|
||||
|
||||
if (p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_OWNERS)) {
|
||||
int64_t *w = r_query_result.path_owner_ids.ptrw();
|
||||
const int64_t *r = r_query_result.path_owner_ids.ptr();
|
||||
for (uint32_t i = 0; i < indices_count; i++) {
|
||||
w[i] = r[simplified_path_indices[i]];
|
||||
}
|
||||
r_query_result.path_owner_ids.resize(indices_count);
|
||||
}
|
||||
}
|
||||
|
||||
// add path stats
|
||||
|
||||
return r_query_result;
|
||||
NavMeshQueries3D::map_query_path(map, p_query_parameters, p_query_result, p_callback);
|
||||
}
|
||||
|
||||
RID GodotNavigationServer3D::source_geometry_parser_create() {
|
||||
RWLockWrite write_lock(geometry_parser_rwlock);
|
||||
|
||||
RID rid = geometry_parser_owner.make_rid();
|
||||
|
||||
NavMeshGeometryParser3D *parser = geometry_parser_owner.get_or_null(rid);
|
||||
parser->self = rid;
|
||||
|
||||
generator_parsers.push_back(parser);
|
||||
#ifndef _3D_DISABLED
|
||||
if (navmesh_generator_3d) {
|
||||
return navmesh_generator_3d->source_geometry_parser_create();
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
return RID();
|
||||
NavMeshGenerator3D::get_singleton()->set_generator_parsers(generator_parsers);
|
||||
#endif
|
||||
return rid;
|
||||
}
|
||||
|
||||
void GodotNavigationServer3D::source_geometry_parser_set_callback(RID p_parser, const Callable &p_callback) {
|
||||
#ifndef _3D_DISABLED
|
||||
if (navmesh_generator_3d) {
|
||||
navmesh_generator_3d->source_geometry_parser_set_callback(p_parser, p_callback);
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
RWLockWrite write_lock(geometry_parser_rwlock);
|
||||
|
||||
NavMeshGeometryParser3D *parser = geometry_parser_owner.get_or_null(p_parser);
|
||||
ERR_FAIL_NULL(parser);
|
||||
|
||||
parser->callback = p_callback;
|
||||
}
|
||||
|
||||
Vector<Vector3> GodotNavigationServer3D::simplify_path(const Vector<Vector3> &p_path, real_t p_epsilon) {
|
||||
|
|
@ -1457,86 +1472,32 @@ Vector<Vector3> GodotNavigationServer3D::simplify_path(const Vector<Vector3> &p_
|
|||
|
||||
p_epsilon = MAX(0.0, p_epsilon);
|
||||
|
||||
LocalVector<uint32_t> simplified_path_indices = get_simplified_path_indices(p_path, p_epsilon);
|
||||
LocalVector<Vector3> source_path;
|
||||
{
|
||||
source_path.resize(p_path.size());
|
||||
const Vector3 *r = p_path.ptr();
|
||||
for (uint32_t i = 0; i < p_path.size(); i++) {
|
||||
source_path[i] = r[i];
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t indices_count = simplified_path_indices.size();
|
||||
LocalVector<uint32_t> simplified_path_indices = NavMeshQueries3D::get_simplified_path_indices(source_path, p_epsilon);
|
||||
|
||||
uint32_t index_count = simplified_path_indices.size();
|
||||
|
||||
Vector<Vector3> simplified_path;
|
||||
simplified_path.resize(indices_count);
|
||||
|
||||
Vector3 *w = simplified_path.ptrw();
|
||||
const Vector3 *r = p_path.ptr();
|
||||
for (uint32_t i = 0; i < indices_count; i++) {
|
||||
w[i] = r[simplified_path_indices[i]];
|
||||
{
|
||||
simplified_path.resize(index_count);
|
||||
Vector3 *w = simplified_path.ptrw();
|
||||
const Vector3 *r = source_path.ptr();
|
||||
for (uint32_t i = 0; i < index_count; i++) {
|
||||
w[i] = r[simplified_path_indices[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return simplified_path;
|
||||
}
|
||||
|
||||
LocalVector<uint32_t> GodotNavigationServer3D::get_simplified_path_indices(const Vector<Vector3> &p_path, real_t p_epsilon) {
|
||||
p_epsilon = MAX(0.0, p_epsilon);
|
||||
real_t squared_epsilon = p_epsilon * p_epsilon;
|
||||
|
||||
LocalVector<bool> valid_points;
|
||||
valid_points.resize(p_path.size());
|
||||
for (uint32_t i = 0; i < valid_points.size(); i++) {
|
||||
valid_points[i] = false;
|
||||
}
|
||||
|
||||
simplify_path_segment(0, p_path.size() - 1, p_path, squared_epsilon, valid_points);
|
||||
|
||||
int valid_point_index = 0;
|
||||
|
||||
for (bool valid : valid_points) {
|
||||
if (valid) {
|
||||
valid_point_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
LocalVector<uint32_t> simplified_path_indices;
|
||||
simplified_path_indices.resize(valid_point_index);
|
||||
valid_point_index = 0;
|
||||
|
||||
for (uint32_t i = 0; i < valid_points.size(); i++) {
|
||||
if (valid_points[i]) {
|
||||
simplified_path_indices[valid_point_index] = i;
|
||||
valid_point_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return simplified_path_indices;
|
||||
}
|
||||
|
||||
void GodotNavigationServer3D::simplify_path_segment(int p_start_inx, int p_end_inx, const Vector<Vector3> &p_points, real_t p_epsilon, LocalVector<bool> &r_valid_points) {
|
||||
r_valid_points[p_start_inx] = true;
|
||||
r_valid_points[p_end_inx] = true;
|
||||
|
||||
const Vector3 &start_point = p_points[p_start_inx];
|
||||
const Vector3 &end_point = p_points[p_end_inx];
|
||||
|
||||
Vector3 path_segment[2] = { start_point, end_point };
|
||||
|
||||
real_t point_max_distance = 0.0;
|
||||
int point_max_index = 0;
|
||||
|
||||
for (int i = p_start_inx; i < p_end_inx; i++) {
|
||||
const Vector3 &checked_point = p_points[i];
|
||||
|
||||
const Vector3 closest_point = Geometry3D::get_closest_point_to_segment(checked_point, path_segment);
|
||||
real_t distance_squared = closest_point.distance_squared_to(checked_point);
|
||||
|
||||
if (distance_squared > point_max_distance) {
|
||||
point_max_index = i;
|
||||
point_max_distance = distance_squared;
|
||||
}
|
||||
}
|
||||
|
||||
if (point_max_distance > p_epsilon) {
|
||||
simplify_path_segment(p_start_inx, point_max_index, p_points, p_epsilon, r_valid_points);
|
||||
simplify_path_segment(point_max_index, p_end_inx, p_points, p_epsilon, r_valid_points);
|
||||
}
|
||||
}
|
||||
|
||||
int GodotNavigationServer3D::get_process_info(ProcessInfo p_info) const {
|
||||
switch (p_info) {
|
||||
case INFO_ACTIVE_MAPS: {
|
||||
|
|
@ -1566,6 +1527,9 @@ int GodotNavigationServer3D::get_process_info(ProcessInfo p_info) const {
|
|||
case INFO_EDGE_FREE_COUNT: {
|
||||
return pm_edge_free_count;
|
||||
} break;
|
||||
case INFO_OBSTACLE_COUNT: {
|
||||
return pm_obstacle_count;
|
||||
} break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue