Skip to content

Commit

Permalink
World: Map now maintains/provides fast Id to Subsector lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Aug 9, 2016
1 parent 56c60d8 commit e8aca67
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 71 deletions.
10 changes: 10 additions & 0 deletions doomsday/apps/client/include/world/map.h
Expand Up @@ -30,6 +30,7 @@
#include <doomsday/world/map.h>
#include <doomsday/uri.h>
#include <de/BinaryTree>
#include <de/Id>
#include <de/Observers>
#include <de/Vector>

Expand Down Expand Up @@ -522,6 +523,15 @@ class Map : public world::BaseMap
*/
de::LoopResult forAllSectorsTouchingMobj(struct mobj_s &mob, std::function<de::LoopResult (Sector &)> callback) const;

/// Thrown when the referenced subsector is missing/unknown.
DENG2_ERROR(MissingSubsectorError);

/**
* Lookup a Subsector in the map by it's unique identifier @a id.
*/
Subsector &subsector (de::Id id) const;
Subsector *subsectorPtr(de::Id id) const;

/**
* Determine the Subsector which contains @a point and which is on the back side of
* the binary map space partition which, lies in front of @a point.
Expand Down
9 changes: 0 additions & 9 deletions doomsday/apps/client/include/world/sector.h
Expand Up @@ -190,9 +190,6 @@ class Sector : public world::MapElement

//- Subsectors --------------------------------------------------------------------------

/// Thrown when the referenced subsector is missing/unknown.
DENG2_ERROR(MissingSubsectorError);

typedef std::function<world::Subsector * (QList<world::ConvexSubspace *> const &)> SubsectorConstructor;

static void setSubsectorConstructor(SubsectorConstructor func);
Expand Down Expand Up @@ -241,12 +238,6 @@ class Sector : public world::MapElement
*/
world::Subsector *addSubsector(QList<world::ConvexSubspace *> const &subspaces);

bool hasSubsector(de::Id id) const;

world::Subsector &findSubsector(de::Id id) const;

world::Subsector *tryFindSubsector(de::Id id) const;

//- Sides -------------------------------------------------------------------------------

/**
Expand Down
99 changes: 63 additions & 36 deletions doomsday/apps/client/src/world/base/map.cpp
Expand Up @@ -165,6 +165,7 @@ DENG2_PIMPL(Map)

Bsp bsp;
QList<ConvexSubspace *> subspaces; ///< All player-traversable subspaces.
QHash<Id, Subsector *> subsectorsById; ///< Not owned.

//
// Map entities and element properties (things, line specials, etc...).
Expand Down Expand Up @@ -778,9 +779,18 @@ DENG2_PIMPL(Map)
// Clustering complete.

// Build subsectors.
dint needed = 0;
for (Subspaces const &subspaceSet : subspaceSets)
{
sector.addSubsector(subspaceSet);
needed += subspaceSet.count();
}
subsectorsById.clear();
subsectorsById.reserve(needed);
for (Subspaces const &subspaceSet : subspaceSets)
{
Subsector *subsec = sector.addSubsector(subspaceSet);
DENG2_ASSERT(subsec != nullptr);
subsectorsById.insert(subsec->id(), subsec);
}
}

Expand Down Expand Up @@ -2103,31 +2113,6 @@ dint Map::sectorCount() const
return d->sectors.count();
}

Sector &Map::sector(dint index) const
{
if (Sector *sec = sectorPtr(index)) return *sec;
/// @throw MissingElementError Invalid Sector reference specified.
throw MissingElementError("Map::sector", "Unknown Sector index:" + String::number(index));
}

Sector *Map::sectorPtr(dint index) const
{
if (index >= 0 && index < d->sectors.count())
{
return d->sectors.at(index);
}
return nullptr;
}

LoopResult Map::forAllSectors(std::function<LoopResult (Sector &)> func) const
{
for (Sector *sec : d->sectors)
{
if (auto result = func(*sec)) return result;
}
return LoopContinue;
}

#ifdef __CLIENT__
bool Map::isPointInVoid(de::Vector3d const &point) const
{
Expand Down Expand Up @@ -2295,6 +2280,58 @@ void Map::initNodePiles()
LOGDEV_MAP_MSG("Initialized node piles in %.2f seconds") << begunAt.since();
}

Sector &Map::sector(dint index) const
{
if (Sector *sec = sectorPtr(index)) return *sec;
/// @throw MissingElementError Invalid Sector reference specified.
throw MissingElementError("Map::sector", "Unknown Sector index:" + String::number(index));
}

Sector *Map::sectorPtr(dint index) const
{
if (index >= 0 && index < d->sectors.count())
{
return d->sectors.at(index);
}
return nullptr;
}

LoopResult Map::forAllSectors(std::function<LoopResult (Sector &)> func) const
{
for (Sector *sec : d->sectors)
{
if (auto result = func(*sec)) return result;
}
return LoopContinue;
}

Subsector *Map::subsectorAt(Vector2d const &point) const
{
BspLeaf &bspLeaf = bspLeafAt(point);
if (bspLeaf.hasSubspace() && bspLeaf.subspace().contains(point))
{
return bspLeaf.subspace().subsectorPtr();
}
return nullptr;
}

Subsector &Map::subsector(de::Id id) const
{
if (Subsector *subsec = subsectorPtr(id)) return *subsec;
/// @throw MissingElementError Invalid Sector reference specified.
throw MissingSubsectorError("Map::subsector", "Unknown Subsector \"" + id.asText() + "\"");
}

Subsector *Map::subsectorPtr(de::Id id) const
{
auto found = d->subsectorsById.constFind(id);
if (found != d->subsectorsById.constEnd())
{
return found.value();
}
return nullptr;
}

Blockmap const &Map::mobjBlockmap() const
{
if (bool(d->mobjBlockmap)) return *d->mobjBlockmap;
Expand Down Expand Up @@ -2649,16 +2686,6 @@ BspLeaf &Map::bspLeafAt_FixedPrecision(Vector2d const &point) const
return bspTree->userData()->as<BspLeaf>();
}

Subsector *Map::subsectorAt(Vector2d const &point) const
{
BspLeaf &bspLeaf = bspLeafAt(point);
if (bspLeaf.hasSubspace() && bspLeaf.subspace().contains(point))
{
return bspLeaf.subspace().subsectorPtr();
}
return nullptr;
}

#ifdef __CLIENT__

void Map::updateScrollingSurfaces()
Expand Down
28 changes: 2 additions & 26 deletions doomsday/apps/client/src/world/base/sector.cpp
Expand Up @@ -208,15 +208,15 @@ DENG2_PIMPL(Sector)
}
}

void updateAllSideEmitterOrigins()
void updateAllEmitterOrigins()
{
updateEmitterOriginZ();
updateSideEmitterOrigins();
}

void planeHeightChanged(Plane &)
{
updateAllSideEmitterOrigins();
updateAllEmitterOrigins();
}

DENG2_PIMPL_AUDIENCE(LightLevelChange)
Expand Down Expand Up @@ -368,30 +368,6 @@ Subsector *Sector::addSubsector(QList<ConvexSubspace *> const &subspaces)
return subsec.release();
}

bool Sector::hasSubsector(de::Id id) const
{
for (Subsector *subsec : d->subsectors)
{
if (subsec->id() == id) return true;
}
return false;
}

Subsector *Sector::tryFindSubsector(de::Id id) const
{
for (Subsector *subsec : d->subsectors)
{
if (subsec->id() == id) return subsec;
}
return nullptr;
}

Subsector &Sector::findSubsector(de::Id id) const
{
if (Subsector *subsec = tryFindSubsector(id)) return *subsec;
throw MissingSubsectorError("Sector::findSubsector", "Unknown subsector \"" + id.asText() + "\"");
}

dint Sector::sideCount() const
{
return d->sides.count();
Expand Down

0 comments on commit e8aca67

Please sign in to comment.