diff --git a/apps/openmw_test_suite/detournavigator/recastmeshbuilder.cpp b/apps/openmw_test_suite/detournavigator/recastmeshbuilder.cpp index 63f6aa6b4c..a227df8031 100644 --- a/apps/openmw_test_suite/detournavigator/recastmeshbuilder.cpp +++ b/apps/openmw_test_suite/detournavigator/recastmeshbuilder.cpp @@ -31,9 +31,11 @@ namespace } }; - TEST_F(DetourNavigatorRecastMeshBuilderTest, create_for_empty_should_throw_exception) + TEST_F(DetourNavigatorRecastMeshBuilderTest, create_for_empty_should_return_empty) { - EXPECT_THROW(mBuilder.create(), std::invalid_argument); + const auto recastMesh = mBuilder.create(); + EXPECT_EQ(recastMesh->getVertices(), std::vector()); + EXPECT_EQ(recastMesh->getIndices(), std::vector()); } TEST_F(DetourNavigatorRecastMeshBuilderTest, add_bhv_triangle_mesh_shape) diff --git a/components/detournavigator/chunkytrimesh.cpp b/components/detournavigator/chunkytrimesh.cpp index 1b7f53845b..cdce8b0e1e 100644 --- a/components/detournavigator/chunkytrimesh.cpp +++ b/components/detournavigator/chunkytrimesh.cpp @@ -120,7 +120,7 @@ namespace DetourNavigator const auto trianglesCount = indices.size() / 3; if (trianglesCount == 0) - throw InvalidArgument("ChunkyTriMesh tris should contain at least 3 values"); + return; const auto nchunks = (trianglesCount + trisPerChunk - 1) / trisPerChunk; diff --git a/components/detournavigator/makenavmesh.cpp b/components/detournavigator/makenavmesh.cpp index a1c6d732a0..52fa530689 100644 --- a/components/detournavigator/makenavmesh.cpp +++ b/components/detournavigator/makenavmesh.cpp @@ -269,9 +269,6 @@ namespace DetourNavigator getRadius(settings, agentHalfExtents), " changedTile=", changedTile); - const auto& boundsMin = recastMesh.getBoundsMin(); - const auto& boundsMax = recastMesh.getBoundsMax(); - auto& navMesh = navMeshCacheItem.mValue; const auto& params = *navMesh.lock()->getParams(); const osg::Vec3f origin(params.orig[0], params.orig[1], params.orig[2]); @@ -287,6 +284,15 @@ namespace DetourNavigator nullptr, nullptr)); } + const auto& boundsMin = recastMesh.getBoundsMin(); + const auto& boundsMax = recastMesh.getBoundsMax(); + + if (boundsMin == boundsMax) + { + log("ignore add tile: recastMesh is empty"); + return; + } + const auto tileBounds = makeTileBounds(settings, changedTile); const osg::Vec3f tileBorderMin(tileBounds.mMin.x(), boundsMin.y() - 1, tileBounds.mMin.y()); const osg::Vec3f tileBorderMax(tileBounds.mMax.x(), boundsMax.y() + 1, tileBounds.mMax.y()); @@ -307,5 +313,5 @@ namespace DetourNavigator else log("failed to add tile with status=", WriteDtStatus {status}); navMeshData.mValue.release(); - } +} } diff --git a/components/detournavigator/recastmesh.cpp b/components/detournavigator/recastmesh.cpp index 45c2f98e78..d765656e45 100644 --- a/components/detournavigator/recastmesh.cpp +++ b/components/detournavigator/recastmesh.cpp @@ -10,6 +10,7 @@ namespace DetourNavigator , mVertices(std::move(vertices)) , mChunkyTriMesh(mVertices, mIndices, settings.mTrianglesPerChunk) { - rcCalcBounds(mVertices.data(), static_cast(getVerticesCount()), mBoundsMin.ptr(), mBoundsMax.ptr()); + if (getVerticesCount()) + rcCalcBounds(mVertices.data(), static_cast(getVerticesCount()), mBoundsMin.ptr(), mBoundsMax.ptr()); } }