Revert RedFox's changes to Spatial subdivisions in the simplest possible way (hopefully won't cause OOS, but at least we'll get reports). Fixes #2573, Refs #2430 . There probably are opportunities to remove more things.
This was SVN commit r15617.
This commit is contained in:
parent
c0e7208130
commit
e865dc797d
@ -547,9 +547,9 @@ bool CCmpObstructionManager::TestLine(const IObstructionTestFilter& filter, enti
|
||||
CFixedVector2D posMin (std::min(x0, x1) - r, std::min(z0, z1) - r);
|
||||
CFixedVector2D posMax (std::max(x0, x1) + r, std::max(z0, z1) + r);
|
||||
|
||||
SpatialQueryArray unitShapes;
|
||||
std::vector<entity_id_t> unitShapes;
|
||||
m_UnitSubdivision.GetInRange(unitShapes, posMin, posMax);
|
||||
for (int i = 0; i < unitShapes.size(); ++i)
|
||||
for (size_t i = 0; i < unitShapes.size(); ++i)
|
||||
{
|
||||
std::map<u32, UnitShape>::iterator it = m_UnitShapes.find(unitShapes[i]);
|
||||
ENSURE(it != m_UnitShapes.end());
|
||||
@ -563,9 +563,9 @@ bool CCmpObstructionManager::TestLine(const IObstructionTestFilter& filter, enti
|
||||
return true;
|
||||
}
|
||||
|
||||
SpatialQueryArray staticShapes;
|
||||
std::vector<entity_id_t> staticShapes;
|
||||
m_StaticSubdivision.GetInRange(staticShapes, posMin, posMax);
|
||||
for (int i = 0; i < staticShapes.size(); ++i)
|
||||
for (size_t i = 0; i < staticShapes.size(); ++i)
|
||||
{
|
||||
std::map<u32, StaticShape>::iterator it = m_StaticShapes.find(staticShapes[i]);
|
||||
ENSURE(it != m_StaticShapes.end());
|
||||
@ -885,9 +885,9 @@ void CCmpObstructionManager::GetObstructionsInRange(const IObstructionTestFilter
|
||||
|
||||
ENSURE(x0 <= x1 && z0 <= z1);
|
||||
|
||||
SpatialQueryArray unitShapes;
|
||||
std::vector<entity_id_t> unitShapes;
|
||||
m_UnitSubdivision.GetInRange(unitShapes, CFixedVector2D(x0, z0), CFixedVector2D(x1, z1));
|
||||
for (int i = 0; i < unitShapes.size(); ++i)
|
||||
for (size_t i = 0; i < unitShapes.size(); ++i)
|
||||
{
|
||||
std::map<u32, UnitShape>::iterator it = m_UnitShapes.find(unitShapes[i]);
|
||||
ENSURE(it != m_UnitShapes.end());
|
||||
@ -907,9 +907,9 @@ void CCmpObstructionManager::GetObstructionsInRange(const IObstructionTestFilter
|
||||
squares.push_back(s);
|
||||
}
|
||||
|
||||
SpatialQueryArray staticShapes;
|
||||
std::vector<entity_id_t> staticShapes;
|
||||
m_StaticSubdivision.GetInRange(staticShapes, CFixedVector2D(x0, z0), CFixedVector2D(x1, z1));
|
||||
for (int i = 0; i < staticShapes.size(); ++i)
|
||||
for (size_t i = 0; i < staticShapes.size(); ++i)
|
||||
{
|
||||
std::map<u32, StaticShape>::iterator it = m_StaticShapes.find(staticShapes[i]);
|
||||
ENSURE(it != m_StaticShapes.end());
|
||||
|
@ -981,10 +981,10 @@ public:
|
||||
CFixedVector3D pos3d = cmpSourcePosition->GetPosition()+
|
||||
CFixedVector3D(entity_pos_t::Zero(), q.elevationBonus, entity_pos_t::Zero()) ;
|
||||
// Get a quick list of entities that are potentially in range, with a cutoff of 2*maxRange
|
||||
SpatialQueryArray ents;
|
||||
std::vector<entity_id_t> ents;
|
||||
m_Subdivision.GetNear(ents, pos, q.maxRange*2);
|
||||
|
||||
for (int i = 0; i < ents.size(); ++i)
|
||||
for (size_t i = 0; i < ents.size(); ++i)
|
||||
{
|
||||
EntityMap<EntityData>::const_iterator it = m_EntityData.find(ents[i]);
|
||||
ENSURE(it != m_EntityData.end());
|
||||
@ -1018,10 +1018,10 @@ public:
|
||||
else
|
||||
{
|
||||
// Get a quick list of entities that are potentially in range
|
||||
SpatialQueryArray ents;
|
||||
std::vector<entity_id_t> ents;
|
||||
m_Subdivision.GetNear(ents, pos, q.maxRange);
|
||||
|
||||
for (int i = 0; i < ents.size(); ++i)
|
||||
for (size_t i = 0; i < ents.size(); ++i)
|
||||
{
|
||||
EntityMap<EntityData>::const_iterator it = m_EntityData.find(ents[i]);
|
||||
ENSURE(it != m_EntityData.end());
|
||||
|
@ -49,12 +49,12 @@ std::vector<entity_id_t> EntitySelection::PickEntitiesAtPoint(CSimulation2& simu
|
||||
CFixedVector2D pos(fixed::FromFloat(pos3d.X), fixed::FromFloat(pos3d.Z));
|
||||
|
||||
// Get a rough group of entities using our approximated origin.
|
||||
SpatialQueryArray ents;
|
||||
std::vector<entity_id_t> ents;
|
||||
cmpRangeManager->GetSubdivision()->GetNear(ents, pos, entity_pos_t::FromInt(range));
|
||||
|
||||
// Filter for relevent entities and calculate precise distances.
|
||||
std::vector<std::pair<float, entity_id_t> > hits; // (dist^2, entity) pairs
|
||||
for (int i = 0; i < ents.size(); ++i)
|
||||
for (size_t i = 0; i < ents.size(); ++i)
|
||||
{
|
||||
CmpPtr<ICmpSelectable> cmpSelectable(simulation, ents[i]);
|
||||
if (!cmpSelectable)
|
||||
|
@ -20,36 +20,10 @@
|
||||
|
||||
#include "simulation2/system/Component.h"
|
||||
#include "simulation2/serialization/SerializeTemplates.h"
|
||||
#include "ps/CLogger.h"
|
||||
|
||||
/**
|
||||
* A simple fixed-size array that works similar to an std::vector
|
||||
* but is obviously limited in its max items
|
||||
*/
|
||||
struct SpatialQueryArray
|
||||
{
|
||||
enum { MAX_COUNT = 2048 };
|
||||
int count;
|
||||
uint32_t items[MAX_COUNT];
|
||||
|
||||
inline SpatialQueryArray() : count(0) {}
|
||||
inline const uint32_t& operator[](int index) const { return items[index]; }
|
||||
inline uint32_t& operator[](int index) { return items[index]; }
|
||||
inline int size() const { return count; }
|
||||
inline void clear() { count = 0; }
|
||||
void make_unique() // removes any duplicate entries
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
std::sort(items, items + count); // we need a sorted list for std::unique to work
|
||||
count = int(std::unique(items, items + count) - items);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A very basic subdivision scheme for finding items in ranges.
|
||||
* Items are stored in lists in fixed-size divisions.
|
||||
* Items are stored in lists in dynamic-sized divisions.
|
||||
* Items have a size (min/max values of their axis-aligned bounding box)
|
||||
* and are stored in all divisions overlapping that area.
|
||||
*
|
||||
@ -80,23 +54,9 @@ class SpatialSubdivision
|
||||
items.pop_back();
|
||||
}
|
||||
|
||||
void copy_items(SpatialQueryArray& out)
|
||||
void copy_items_at_end(std::vector<uint32_t>& out)
|
||||
{
|
||||
if (items.empty())
|
||||
return; // nothing to copy
|
||||
|
||||
int dsti = out.count; // the index in [out] where to start copying
|
||||
int count = (int)items.size();
|
||||
if ((dsti + count) > SpatialQueryArray::MAX_COUNT)
|
||||
{
|
||||
LOGWARNING(L"SpatialSubdivision Query too large. Results truncated.");
|
||||
count = SpatialQueryArray::MAX_COUNT - dsti; // don't copy overflowing items
|
||||
}
|
||||
uint32_t* dst = &out.items[dsti];
|
||||
uint32_t* src = &items[0];
|
||||
for (int i = 0; i < count; ++i) // copy all items
|
||||
dst[i] = src[i];
|
||||
out.count += count;
|
||||
out.insert(out.end(), items.begin(), items.end());
|
||||
}
|
||||
};
|
||||
|
||||
@ -288,7 +248,7 @@ public:
|
||||
* Returns a sorted list of unique items that includes all items
|
||||
* within the given axis-aligned square range.
|
||||
*/
|
||||
void GetInRange(SpatialQueryArray& out, CFixedVector2D posMin, CFixedVector2D posMax)
|
||||
void GetInRange(std::vector<uint32_t>& out, CFixedVector2D posMin, CFixedVector2D posMax)
|
||||
{
|
||||
out.clear();
|
||||
ENSURE(posMin.X <= posMax.X && posMin.Y <= posMax.Y);
|
||||
@ -301,18 +261,19 @@ public:
|
||||
{
|
||||
for (u32 i = i0; i <= i1; ++i)
|
||||
{
|
||||
m_Divisions[i + j*m_DivisionsW].copy_items(out);
|
||||
m_Divisions[i + j*m_DivisionsW].copy_items_at_end(out);
|
||||
}
|
||||
}
|
||||
// some buildings span several tiles, so we need to make it unique
|
||||
out.make_unique();
|
||||
std::sort(out.begin(), out.end());
|
||||
out.erase(std::unique(out.begin(), out.end()), out.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sorted list of unique items that includes all items
|
||||
* within the given circular distance of the given point.
|
||||
*/
|
||||
void GetNear(SpatialQueryArray& out, CFixedVector2D pos, entity_pos_t range)
|
||||
void GetNear(std::vector<uint32_t>& out, CFixedVector2D pos, entity_pos_t range)
|
||||
{
|
||||
// TODO: be cleverer and return a circular pattern of divisions,
|
||||
// not this square over-approximation
|
||||
|
Loading…
Reference in New Issue
Block a user