Skip to content

Commit

Permalink
Refactor|World: Switched rest of the map geometry traversals to use h…
Browse files Browse the repository at this point in the history
…alf-edges

Todo: Cleanup. Much of this additional complexity will disappear
along with Segment when this component is removed.
  • Loading branch information
danij-deng committed Aug 9, 2013
1 parent 7b96dcc commit 52e58d2
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 52 deletions.
44 changes: 31 additions & 13 deletions doomsday/client/src/audio/s_environ.cpp
Expand Up @@ -230,6 +230,32 @@ void S_DetermineBspLeafsAffectingSectorReverb(Map *map)
LOG_INFO(String("Completed in %1 seconds.").arg(begunAt.since(), 0, 'g', 2));
}

static void accumReverbForFaceEdges(Face const &face,
float envSpaceAccum[NUM_AUDIO_ENVIRONMENT_CLASSES], float &total)
{
HEdge *base = face.hedge();
HEdge *hedge = base;
do
{
DENG_ASSERT(hedge->mapElement() != 0);
Segment *seg = hedge->mapElement()->as<Segment>();

if(!seg->hasLineSide() || !seg->lineSide().hasSections() ||
!seg->lineSide().middle().hasMaterial())
continue;

Material &material = seg->lineSide().middle().material();
AudioEnvironmentClass env = material.audioEnvironment();
if(!(env >= 0 && env < NUM_AUDIO_ENVIRONMENT_CLASSES))
env = AEC_WOOD; // Assume it's wood if unknown.

total += seg->length();

envSpaceAccum[env] += seg->length();

} while((hedge = &hedge->next()) != base);
}

static boolean calcBspLeafReverb(BspLeaf *bspLeaf)
{
DENG2_ASSERT(bspLeaf);
Expand All @@ -251,22 +277,14 @@ static boolean calcBspLeafReverb(BspLeaf *bspLeaf)
(bspLeaf->poly().aaBox().maxY - bspLeaf->poly().aaBox().minY);

float total = 0;

// The other reverb properties can be found out by taking a look at the
// materials of all surfaces in the BSP leaf.
foreach(Segment *segment, bspLeaf->allSegments())
accumReverbForFaceEdges(bspLeaf->poly(), envSpaceAccum, total);
foreach(Mesh *mesh, bspLeaf->extraMeshes())
foreach(Face *face, mesh->faces())
{
if(!segment->hasLineSide() || !segment->lineSide().hasSections() ||
!segment->lineSide().middle().hasMaterial())
continue;

Material &material = segment->lineSide().middle().material();
AudioEnvironmentClass env = material.audioEnvironment();
if(!(env >= 0 && env < NUM_AUDIO_ENVIRONMENT_CLASSES))
env = AEC_WOOD; // Assume it's wood if unknown.

total += segment->length();

envSpaceAccum[env] += segment->length();
accumReverbForFaceEdges(*face, envSpaceAccum, total);
}

if(!total)
Expand Down
43 changes: 35 additions & 8 deletions doomsday/client/src/world/api_map.cpp
Expand Up @@ -423,16 +423,43 @@ int P_Iteratep(void *elPtr, uint prop, void *context, int (*callback) (void *p,
case DMU_BSPLEAF:
switch(prop)
{
case DMU_LINE:
foreach(Segment *seg, elem->as<BspLeaf>()->allSegments())
{
if(!seg->hasLineSide())
continue;
case DMU_LINE: {
BspLeaf *bspLeaf = elem->as<BspLeaf>();

int result = callback(&seg->line(), context);
if(result) return result;
/// @todo cleanup: BspLeaf could provide a list of Line::Side.
if(!bspLeaf->isDegenerate())
{
HEdge *base = bspLeaf->poly().hedge();
HEdge *hedge = base;
do
{
DENG_ASSERT(hedge->mapElement() != 0);
Segment *seg = hedge->mapElement()->as<Segment>();

if(seg->hasLineSide())
{
int result = callback(&seg->line(), context);
if(result) return result;
}
} while((hedge = &hedge->next()) != base);

foreach(Mesh *mesh, bspLeaf->extraMeshes())
foreach(Face *face, mesh->faces())
{
HEdge *base = face->hedge();
HEdge *hedge = base;
do
{
DENG_ASSERT(hedge->mapElement() != 0);
Segment *seg = hedge->mapElement()->as<Segment>();

int result = callback(&seg->line(), context);
if(result) return result;

} while((hedge = &hedge->next()) != base);
}
}
return false; // Continue iteration.
return false; /* Continue iteration */ }

default:
throw Error("P_Iteratep", QString("Property %1 unknown/not vector").arg(DMU_Str(prop)));
Expand Down
48 changes: 46 additions & 2 deletions doomsday/client/src/world/bspleaf.cpp
Expand Up @@ -541,25 +541,69 @@ int BspLeaf::numFanVertices() const
return d->poly->hedgeCount() + (fanBase()? 0 : 2);
}

static void updateBiasAfterGeometryMoveToFaceEdges(Face const &face)
{
HEdge *base = face.hedge();
HEdge *hedge = base;
do
{
DENG_ASSERT(hedge->mapElement() != 0);
Segment *seg = hedge->mapElement()->as<Segment>();

seg->updateBiasAfterGeometryMove(Line::Side::Middle);
seg->updateBiasAfterGeometryMove(Line::Side::Bottom);
seg->updateBiasAfterGeometryMove(Line::Side::Top);

} while((hedge = &hedge->next()) != base);
}

void BspLeaf::updateBiasAfterGeometryMove(int group)
{
if(isDegenerate())
return;

if(GeometryGroup *geomGroup = d->geometryGroup(group, false /*don't allocate*/))
{
geomGroup->biasTracker.updateAllContributors();
}

updateBiasAfterGeometryMoveToFaceEdges(poly());

foreach(Mesh *mesh, extraMeshes())
foreach(Face *face, mesh->faces())
{
updateBiasAfterGeometryMoveToFaceEdges(*face);
}
}

static void applyBiasDigestToFaceEdges(Face const &face, BiasDigest &changes)
{
HEdge *base = face.hedge();
HEdge *hedge = base;
do
{
DENG_ASSERT(hedge->mapElement() != 0);
Segment *seg = hedge->mapElement()->as<Segment>();
seg->applyBiasDigest(changes);
} while((hedge = &hedge->next()) != base);
}

void BspLeaf::applyBiasDigest(BiasDigest &changes)
{
if(isDegenerate()) return;

for(GeometryGroups::iterator it = d->geomGroups.begin();
it != d->geomGroups.end(); ++it)
{
it.value().biasTracker.applyChanges(changes);
}

foreach(Segment *seg, allSegments())
applyBiasDigestToFaceEdges(poly(), changes);

foreach(Mesh *mesh, extraMeshes())
foreach(Face *face, mesh->faces())
{
seg->applyBiasDigest(changes);
applyBiasDigestToFaceEdges(*face, changes);
}

foreach(Polyobj *polyobj, d->polyobjs)
Expand Down
40 changes: 26 additions & 14 deletions doomsday/client/src/world/linesighttest.cpp
Expand Up @@ -97,7 +97,12 @@ DENG2_PIMPL(LineSightTest)
#define RTOP 0x1 ///< Top range.
#define RBOTTOM 0x2 ///< Bottom range.

Line const &line = side.line();
Line &line = side.line();

if(line.validCount() == validCount)
return true; // Ignore

line.setValidCount(validCount);

// Does the ray intercept the line on the X/Y plane?
// Try a quick bounding-box rejection.
Expand Down Expand Up @@ -242,28 +247,35 @@ DENG2_PIMPL(LineSightTest)
foreach(Polyobj *po, bspLeaf.polyobjs())
foreach(Line *line, po->lines())
{
if(line->validCount() == validCount)
continue;

line->setValidCount(validCount);

if(!crossLine(line->front()))
return false; // Stop traversal.
}

// Check the line segment geometries.
foreach(Segment const *seg, bspLeaf.allSegments())
// Check the BSP leaf line geometries.
HEdge *base = bspLeaf.poly().hedge();
HEdge *hedge = base;
do
{
if(!seg->hasLineSide())
continue;

if(seg->line().validCount() != validCount)
DENG_ASSERT(hedge->mapElement() != 0);
Segment *seg = hedge->mapElement()->as<Segment>();
if(seg->hasLineSide())
{
seg->line().setValidCount(validCount);

if(!crossLine(seg->lineSide()))
return false;
}
} while((hedge = &hedge->next()) != base);

foreach(Mesh *mesh, bspLeaf.extraMeshes())
foreach(Face *face, mesh->faces())
{
HEdge *base = face->hedge();
HEdge *hedge = base;
do
{
DENG_ASSERT(hedge->mapElement() != 0);
if(!crossLine(hedge->mapElement()->as<Segment>()->lineSide()))
return false;
} while((hedge = &hedge->next()) != base);
}

return true; // Continue traversal.
Expand Down
22 changes: 20 additions & 2 deletions doomsday/client/src/world/map.cpp
Expand Up @@ -451,6 +451,18 @@ DENG2_OBSERVES(bsp::Partitioner, UnclosedSectorFound)
}
}

static void assignMapToSegmentsForFace(Face const &face, Map *map)
{
HEdge *base = face.hedge();
HEdge *hedge = base;
do
{
DENG_ASSERT(hedge->mapElement() != 0);
Segment *seg = hedge->mapElement()->as<Segment>();
seg->setMap(map);
} while((hedge = &hedge->next()) != base);
}

void collateBspElements(bsp::Partitioner &partitioner, BspTreeNode &tree)
{
if(tree.isLeaf())
Expand All @@ -465,9 +477,15 @@ DENG2_OBSERVES(bsp::Partitioner, UnclosedSectorFound)
leaf->setIndexInMap(bspLeafs.count());
bspLeafs.append(leaf);

foreach(Segment *seg, leaf->allSegments())
if(!leaf->isDegenerate())
{
seg->setMap(thisPublic);
assignMapToSegmentsForFace(leaf->poly(), thisPublic);

foreach(Mesh *mesh, leaf->extraMeshes())
foreach(Face *face, mesh->faces())
{
assignMapToSegmentsForFace(*face, thisPublic);
}
}

return;
Expand Down
13 changes: 0 additions & 13 deletions doomsday/client/src/world/sector.cpp
Expand Up @@ -172,19 +172,6 @@ DENG2_OBSERVES(Plane, HeightChange)
// Inform the shadow bias of changed geometry.
foreach(BspLeaf *bspLeaf, bspLeafs)
{
if(bspLeaf->isDegenerate())
continue;

foreach(Segment *seg, bspLeaf->allSegments())
{
if(!seg->hasLineSide())
continue;

seg->updateBiasAfterGeometryMove(Line::Side::Middle);
seg->updateBiasAfterGeometryMove(Line::Side::Bottom);
seg->updateBiasAfterGeometryMove(Line::Side::Top);
}

bspLeaf->updateBiasAfterGeometryMove(plane.indexInSector());
}
}
Expand Down

0 comments on commit 52e58d2

Please sign in to comment.