1
0
mirror of https://github.com/luanti-org/luanti.git synced 2026-01-14 05:15:21 +01:00

Add spatial index for objects (#14631)

This commit is contained in:
Lars Müller
2025-04-08 08:44:53 +02:00
committed by GitHub
parent bed36139db
commit a3648b0b16
17 changed files with 982 additions and 116 deletions

View File

@@ -26,7 +26,7 @@ void ActiveObjectMgr::clearIf(const std::function<bool(ServerActiveObject *, u16
continue;
if (cb(it.second.get(), it.first)) {
// Remove reference from m_active_objects
m_active_objects.remove(it.first);
removeObject(it.first);
}
}
}
@@ -68,16 +68,17 @@ bool ActiveObjectMgr::registerObject(std::unique_ptr<ServerActiveObject> obj)
return false;
}
if (objectpos_over_limit(obj->getBasePosition())) {
v3f p = obj->getBasePosition();
const v3f pos = obj->getBasePosition();
if (objectpos_over_limit(pos)) {
warningstream << "Server::ActiveObjectMgr::addActiveObjectRaw(): "
<< "object position (" << p.X << "," << p.Y << "," << p.Z
<< "object position (" << pos.X << "," << pos.Y << "," << pos.Z
<< ") outside maximum range" << std::endl;
return false;
}
auto obj_id = obj->getId();
m_active_objects.put(obj_id, std::move(obj));
m_spatial_index.insert(pos.toArray(), obj_id);
auto new_size = m_active_objects.size();
verbosestream << "Server::ActiveObjectMgr::addActiveObjectRaw(): "
@@ -100,6 +101,8 @@ void ActiveObjectMgr::removeObject(u16 id)
if (!ok) {
infostream << "Server::ActiveObjectMgr::removeObject(): "
<< "id=" << id << " not found" << std::endl;
} else {
m_spatial_index.remove(id);
}
}
@@ -113,43 +116,47 @@ void ActiveObjectMgr::invalidateActiveObjectObserverCaches()
}
}
void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius,
void ActiveObjectMgr::updateObjectPos(u16 id, v3f pos)
{
// HACK defensively only update if we already know the object,
// otherwise we're still waiting to be inserted into the index
// (or have already been removed).
if (m_active_objects.get(id))
m_spatial_index.update(pos.toArray(), id);
}
void ActiveObjectMgr::getObjectsInsideRadius(v3f pos, float radius,
std::vector<ServerActiveObject *> &result,
std::function<bool(ServerActiveObject *obj)> include_obj_cb)
{
float r2 = radius * radius;
for (auto &activeObject : m_active_objects.iter()) {
ServerActiveObject *obj = activeObject.second.get();
if (!obj)
continue;
const v3f &objectpos = obj->getBasePosition();
if (objectpos.getDistanceFromSQ(pos) > r2)
continue;
float r_squared = radius * radius;
m_spatial_index.rangeQuery((pos - v3f(radius)).toArray(), (pos + v3f(radius)).toArray(), [&](auto objPos, u16 id) {
if (v3f(objPos).getDistanceFromSQ(pos) > r_squared)
return;
auto obj = m_active_objects.get(id).get();
if (!obj)
return;
if (!include_obj_cb || include_obj_cb(obj))
result.push_back(obj);
}
});
}
void ActiveObjectMgr::getObjectsInArea(const aabb3f &box,
std::vector<ServerActiveObject *> &result,
std::function<bool(ServerActiveObject *obj)> include_obj_cb)
{
for (auto &activeObject : m_active_objects.iter()) {
ServerActiveObject *obj = activeObject.second.get();
m_spatial_index.rangeQuery(box.MinEdge.toArray(), box.MaxEdge.toArray(), [&](auto _, u16 id) {
auto obj = m_active_objects.get(id).get();
if (!obj)
continue;
const v3f &objectpos = obj->getBasePosition();
if (!box.isPointInside(objectpos))
continue;
return;
if (!include_obj_cb || include_obj_cb(obj))
result.push_back(obj);
}
});
}
void ActiveObjectMgr::getAddedActiveObjectsAroundPos(
const v3f &player_pos, const std::string &player_name,
v3f player_pos, const std::string &player_name,
f32 radius, f32 player_radius,
const std::set<u16> &current_objects,
std::vector<u16> &added_objects)