Fix thread-use causing navigation source geometry data corruption

Fixes navigation source geometry data corruption caused by thread-use that changed vertices or indices while the source geometry data was used in a parsing process or read from by the navmesh baking.
This commit is contained in:
smix8 2024-06-20 20:01:04 +02:00
parent 6fb3b72756
commit d4722b9e1f
6 changed files with 131 additions and 60 deletions

View file

@ -852,8 +852,15 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
}
int outline_count = p_navigation_mesh->get_outline_count();
const Vector<Vector<Vector2>> &traversable_outlines = p_source_geometry_data->_get_traversable_outlines();
const Vector<Vector<Vector2>> &obstruction_outlines = p_source_geometry_data->_get_obstruction_outlines();
Vector<Vector<Vector2>> traversable_outlines;
Vector<Vector<Vector2>> obstruction_outlines;
Vector<NavigationMeshSourceGeometryData2D::ProjectedObstruction> projected_obstructions;
p_source_geometry_data->get_data(
traversable_outlines,
obstruction_outlines,
projected_obstructions);
if (outline_count == 0 && traversable_outlines.size() == 0) {
return;
@ -898,8 +905,6 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
obstruction_polygon_paths.push_back(clip_path);
}
const Vector<NavigationMeshSourceGeometryData2D::ProjectedObstruction> &projected_obstructions = p_source_geometry_data->_get_projected_obstructions();
if (!projected_obstructions.is_empty()) {
for (const NavigationMeshSourceGeometryData2D::ProjectedObstruction &projected_obstruction : projected_obstructions) {
if (projected_obstruction.carve) {

View file

@ -672,10 +672,16 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
return;
}
const Vector<float> &vertices = p_source_geometry_data->get_vertices();
const Vector<int> &indices = p_source_geometry_data->get_indices();
Vector<float> source_geometry_vertices;
Vector<int> source_geometry_indices;
Vector<NavigationMeshSourceGeometryData3D::ProjectedObstruction> projected_obstructions;
if (vertices.size() < 3 || indices.size() < 3) {
p_source_geometry_data->get_data(
source_geometry_vertices,
source_geometry_indices,
projected_obstructions);
if (source_geometry_vertices.size() < 3 || source_geometry_indices.size() < 3) {
return;
}
@ -691,10 +697,10 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
bake_state = "Setting up Configuration..."; // step #1
const float *verts = vertices.ptr();
const int nverts = vertices.size() / 3;
const int *tris = indices.ptr();
const int ntris = indices.size() / 3;
const float *verts = source_geometry_vertices.ptr();
const int nverts = source_geometry_vertices.size() / 3;
const int *tris = source_geometry_indices.ptr();
const int ntris = source_geometry_indices.size() / 3;
float bmin[3], bmax[3];
rcCalcBounds(verts, nverts, bmin, bmax);
@ -818,8 +824,6 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
rcFreeHeightField(hf);
hf = nullptr;
const Vector<NavigationMeshSourceGeometryData3D::ProjectedObstruction> &projected_obstructions = p_source_geometry_data->_get_projected_obstructions();
// Add obstacles to the source geometry. Those will be affected by e.g. agent_radius.
if (!projected_obstructions.is_empty()) {
for (const NavigationMeshSourceGeometryData3D::ProjectedObstruction &projected_obstruction : projected_obstructions) {