Skip to content

Commit

Permalink
xrGame/space_restriction_shape.h: parallelize iterate_vertices in fil…
Browse files Browse the repository at this point in the history
…l_shape
  • Loading branch information
olefirenque committed Feb 1, 2024
1 parent ff3fac7 commit b846569
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/xrAICore/Navigation/level_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ class XRAICORE_API CLevelGraph
IC void assign_y_values(xr_vector<T>& path);
template <typename P>
IC void iterate_vertices(const Fvector& min_position, const Fvector& max_position, const P& predicate) const;
IC std::pair<CLevelVertex*, CLevelVertex*> get_range(const Fvector& min_position, const Fvector& max_position) const;
IC bool check_vertex_in_direction(u32 start_vertex_id, const Fvector2& start_position, u32 finish_vertex_id) const;
IC u32 check_position_in_direction(
u32 start_vertex_id, const Fvector2& start_position, const Fvector2& finish_position) const;
Expand Down
11 changes: 9 additions & 2 deletions src/xrAICore/Navigation/level_graph_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,14 @@ IC void CLevelGraph::clear_mask_no_check(u32 vertex_id) { m_access_mask[vertex_i
template <typename P>
IC void CLevelGraph::iterate_vertices(
const Fvector& min_position, const Fvector& max_position, const P& predicate) const
{
auto [I, E] = get_range(min_position, max_position);

for (; I != E; ++I)
predicate(*I);
}

IC std::pair<CLevelGraph::CLevelVertex *, CLevelGraph::CLevelVertex *> CLevelGraph::get_range(const Fvector& min_position, const Fvector& max_position) const
{
const auto begin = m_nodes->begin(), end = m_nodes->end();

Expand All @@ -591,8 +599,7 @@ IC void CLevelGraph::iterate_vertices(
else
E = end;

for (; I != E; ++I)
predicate(*I);
return {I, E};
}

IC u32 CLevelGraph::max_x() const { return (m_max_x); }
Expand Down
3 changes: 1 addition & 2 deletions src/xrGame/Level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,7 @@ void CLevel::OnFrame()
if (g_mt_config.test(mtMap))
{
R_ASSERT(m_map_manager);
Device.seqParallel.push_back(
fastdelegate::FastDelegate0<>(m_map_manager, &CMapManager::Update));
Device.seqParallel.emplace_back(m_map_manager, &CMapManager::Update);
}
else
MapManager().Update();
Expand Down
38 changes: 36 additions & 2 deletions src/xrGame/space_restriction_shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "xrAICore/Navigation/level_graph.h"
#include "space_restrictor.h"
#include "xrAICore/Navigation/graph_engine.h"
#include "xrCore/Threading/ParallelFor.hpp"

struct CBorderMergePredicate
{
Expand Down Expand Up @@ -79,10 +80,43 @@ void CSpaceRestrictionShape::fill_shape(const CCF_Shape::shape_def& shape)
}
default: NODEFAULT;
}
ai().level_graph().iterate_vertices(start, dest, CBorderMergePredicate(this));

CLevelGraph& graph = ai().level_graph();

std::mutex mergeMutex;

auto [begin, end] = graph.get_range(start, dest);
xr_parallel_for(TaskRange{begin, end}, [this, &mergeMutex, &graph] (auto &range) {
xr_vector<u32> m_border_chunk;
m_border_chunk.reserve(range.size());
for (auto &vertex : range)
{
if (inside(graph.vertex_id(&vertex), true) &&
!inside(graph.vertex_id(&vertex), false))
m_border_chunk.push_back(graph.vertex_id(&vertex));
}
std::lock_guard lock(mergeMutex);
if (m_border.capacity() < m_border.size() + m_border_chunk.size())
m_border.reserve(m_border.size() + m_border_chunk.size());
for (auto x : m_border_chunk)
m_border.push_back(x);
});

#ifdef DEBUG
ai().level_graph().iterate_vertices(start, dest, CShapeTestPredicate(this));
xr_parallel_for(TaskRange{begin, end}, [this, &mergeMutex, &graph] (const auto &range) {
xr_vector<u32> m_test_storage_chunk;
m_test_storage_chunk.reserve(range.size());
for (auto &vertex : range)
{
if (inside(graph.vertex_id(&vertex), false))
m_test_storage_chunk.push_back(graph.vertex_id(&vertex));
}
std::lock_guard lock(mergeMutex);
if (m_test_storage.capacity() < m_test_storage.size() + m_test_storage_chunk.size())
m_test_storage.reserve(m_test_storage.size() + m_test_storage_chunk.size());
for (auto x : m_test_storage_chunk)
m_test_storage.push_back(x);
});
#endif
}

Expand Down
9 changes: 8 additions & 1 deletion src/xrGame/space_restrictor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,14 @@ void CSpaceRestrictor::net_Destroy()
bool CSpaceRestrictor::inside(const Fsphere& sphere) const
{
if (!actual())
prepare();
{
static std::mutex prepareMutex;
std::lock_guard lock(prepareMutex);

// Double-checked locking
if (!actual())
prepare();
}

if (!m_selfbounds.intersect(sphere))
return (false);
Expand Down

0 comments on commit b846569

Please sign in to comment.