Skip to content

Commit

Permalink
Cleanup|World|LineSightTest: Simplified de::LineSightTest's internal …
Browse files Browse the repository at this point in the history
…structure, cleanup

The private implementation of this class does not need a reference
to the public instance.
  • Loading branch information
danij-deng committed Mar 15, 2015
1 parent 27e2c0a commit 63b6236
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 63 deletions.
29 changes: 14 additions & 15 deletions doomsday/client/include/world/linesighttest.h
@@ -1,7 +1,7 @@
/** @file linesighttest.h World map line of sight testing.
*
* @authors Copyright © 2003-2014 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2006-2014 Daniel Swanson <danij@dengine.net>
* @authors Copyright © 2006-2015 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
Expand Down Expand Up @@ -31,12 +31,11 @@ namespace de {
* Models the logic, parameters and state of a line (of) sight (LOS) test.
*
* @todo fixme: The state of a discrete trace is not fully encapsulated here
* due to the manipulation of the validCount properties of the various
* map data elements. (Which is used to avoid testing the same element
* multiple times during a trace.)
* due to the manipulation of the validCount properties of the various map data elements.
* (Which is used to avoid testing the same element multiple times during a trace.)
*
* @todo optimize: Make use of the blockmap to take advantage of the inherent
* spatial locality in this data structure.
* @todo optimize: Make use of the blockmap to take advantage of the inherent spatial
* locality in this data structure.
*
* @ingroup world
*/
Expand All @@ -49,11 +48,11 @@ class LineSightTest
/**
* Constructs a new line (of) sight test.
*
* @param from Trace origin point in the map coordinate space.
* @param to Trace target point in the map coordinate space.
* @param bottomSlope Lower limit to the Z axis angle/slope range.
* @param topSlope Upper limit to the Z axis angle/slope range.
* @param flags @ref lineSightFlags dictate trace behavior/logic.
* @param from Trace origin point in the map coordinate space.
* @param to Trace target point in the map coordinate space.
* @param bottomSlope Lower limit to the Z axis angle/slope range.
* @param topSlope Upper limit to the Z axis angle/slope range.
* @param flags @ref lineSightFlags dictate trace behavior/logic.
*/
LineSightTest(Vector3d const &from, Vector3d const &to,
dfloat bottomSlope = -1,
Expand All @@ -65,15 +64,15 @@ class LineSightTest
*
* @param bspRoot Root of BSP to be traced.
*
* @return @c true iff an uninterrupted path exists between the preconfigured
* Start and End points of the trace line.
* @return @c true iff an uninterrupted path exists between the preconfigured Start
* and End points of the trace line.
*/
bool trace(BspTree const &bspRoot);

private:
DENG2_PRIVATE(d)
};

} // namespace de
} // namespace de

#endif // DENG_WORLD_LINE_SIGHT_TEST_H
#endif // DENG_WORLD_LINE_SIGHT_TEST_H
99 changes: 51 additions & 48 deletions doomsday/client/src/world/linesighttest.cpp
@@ -1,7 +1,7 @@
/** @file linesighttest.cpp World map line of sight testing.
*
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2006-2013 Daniel Swanson <danij@dengine.net>
* @authors Copyright © 2006-2015 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
Expand All @@ -21,30 +21,30 @@
#include "de_base.h"
#include "world/linesighttest.h"

#include <cmath>
#include <de/aabox.h>
#include <de/fixedpoint.h>
#include <de/vector1.h>

#include "Face"

#include "world/worldsystem.h" /// For validCount, @todo Remove me.
#include "world/worldsystem.h" /// For validCount, @todo Remove me.
#include "BspLeaf"
#include "BspNode"
#include "ConvexSubspace"
#include "Line"
#include "Polyobj"
#include "Sector"

#include <de/aabox.h>
#include <de/fixedpoint.h>
#include <de/vector1.h> /// @todo remove me
#include <cmath>

using namespace de;

DENG2_PIMPL(LineSightTest)
DENG2_PIMPL_NOREF(LineSightTest)
{
dint flags; ///< LS_* flags @ref lineSightFlags
Vector3d from; ///< Ray origin.
Vector3d to; ///< Ray target.
dfloat bottomSlope; ///< Slope to bottom of target.
dfloat topSlope; ///< Slope to top of target.
dint flags = 0; ///< LS_* flags @ref lineSightFlags
Vector3d from; ///< Ray origin.
Vector3d to; ///< Ray target.
dfloat bottomSlope; ///< Slope to bottom of target.
dfloat topSlope; ///< Slope to top of target.

/// The ray to be traced.
struct Ray
Expand All @@ -55,10 +55,10 @@ DENG2_PIMPL(LineSightTest)

Ray(Vector3d const &from, Vector3d const &to)
{
origin[VX] = DBL2FIX(from.x);
origin[VY] = DBL2FIX(from.y);
direction[VX] = DBL2FIX(to.x - from.x);
direction[VY] = DBL2FIX(to.y - from.y);
origin[0] = DBL2FIX(from.x);
origin[1] = DBL2FIX(from.y);
direction[0] = DBL2FIX(to.x - from.x);
direction[1] = DBL2FIX(to.y - from.y);

ddouble v1From[2] = { from.x, from.y };
V2d_InitBox(aabox.arvec2, v1From);
Expand All @@ -68,15 +68,12 @@ DENG2_PIMPL(LineSightTest)
}
} ray;

Instance(Public *i, Vector3d const &from, Vector3d const to,
dfloat bottomSlope, dfloat topSlope, dint flags)
: Base(i)
, flags(flags)
, from(from)
, to(to)
Instance(Vector3d const &from, Vector3d const to, dfloat bottomSlope, dfloat topSlope)
: from (from)
, to (to)
, bottomSlope(bottomSlope)
, topSlope(topSlope)
, ray(from, to)
, topSlope (topSlope)
, ray (from, to)
{}

/**
Expand All @@ -87,13 +84,13 @@ DENG2_PIMPL(LineSightTest)
*/
bool crossLine(LineSide &side)
{
#define RTOP 0x1 ///< Top range.
#define RBOTTOM 0x2 ///< Bottom range.
#define RTOP 0x1 ///< Top range.
#define RBOTTOM 0x2 ///< Bottom range.

Line &line = side.line();

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

line.setValidCount(validCount);

Expand All @@ -105,17 +102,17 @@ DENG2_PIMPL(LineSightTest)
line.aaBox().maxY < ray.aabox.minY)
return true;

fixed_t lineV1OriginX[2] = { DBL2FIX(line.fromOrigin().x), DBL2FIX(line.fromOrigin().y) };
fixed_t lineV2OriginX[2] = { DBL2FIX(line.toOrigin().x), DBL2FIX(line.toOrigin().y) };
fixed_t const lineV1OriginX[2] = { DBL2FIX(line.fromOrigin().x), DBL2FIX(line.fromOrigin().y) };
fixed_t const lineV2OriginX[2] = { DBL2FIX(line.toOrigin ().x), DBL2FIX(line.toOrigin ().y) };

if(V2x_PointOnLineSide(lineV1OriginX, ray.origin, ray.direction) ==
V2x_PointOnLineSide(lineV2OriginX, ray.origin, ray.direction))
return true;

fixed_t lineDirectionX[2] = { DBL2FIX(line.direction().x), DBL2FIX(line.direction().y) };

fixed_t fromPointX[2] = { DBL2FIX(from.x), DBL2FIX(from.y) };
fixed_t toPointX[2] = { DBL2FIX(to.x), DBL2FIX(to.y) };
fixed_t const fromPointX[2] = { DBL2FIX(from.x), DBL2FIX(from.y) };
fixed_t const toPointX[2] = { DBL2FIX(to .x), DBL2FIX(to .y) };

if(V2x_PointOnLineSide(fromPointX, lineV1OriginX, lineDirectionX) ==
V2x_PointOnLineSide(toPointX, lineV1OriginX, lineDirectionX))
Expand Down Expand Up @@ -229,15 +226,10 @@ DENG2_PIMPL(LineSightTest)
}

/**
* @return @c true if the ray passes @a bspLeaf; otherwise @c false.
* @return @c true if the ray passes @a subspace; otherwise @c false.
*/
bool crossBspLeaf(BspLeaf const &bspLeaf)
bool crossSubspace(ConvexSubspace const &subspace)
{
if(!bspLeaf.hasSubspace())
return false;

ConvexSubspace const &subspace = bspLeaf.subspace();

// Check polyobj lines.
LoopResult blocked = subspace.forAllPolyobjs([this] (Polyobj &pob)
{
Expand All @@ -251,7 +243,7 @@ DENG2_PIMPL(LineSightTest)
if(blocked) return false;

// Check lines for the edges of the subspace geometry.
HEdge *base = subspace.poly().hedge();
HEdge *base = subspace.poly().hedge();
HEdge *hedge = base;
do
{
Expand Down Expand Up @@ -285,10 +277,11 @@ DENG2_PIMPL(LineSightTest)
*/
bool crossBspNode(BspTree const *bspTree)
{
DENG2_ASSERT(bspTree != 0);
DENG2_ASSERT(bspTree);

while(!bspTree->isLeaf())
{
DENG2_ASSERT(bspTree->userData());
BspNode const &bspNode = bspTree->userData()->as<BspNode>();

// Does the ray intersect the partition?
Expand All @@ -299,9 +292,9 @@ DENG2_PIMPL(LineSightTest)
{
// Yes.
if(!crossBspNode(bspTree->childPtr(BspTree::ChildId(fromSide))))
return false; // Cross the From side.
return false; // Cross the From side.

bspTree = bspTree->childPtr(BspTree::ChildId(fromSide ^ 1)); // Cross the To side.
bspTree = bspTree->childPtr(BspTree::ChildId(fromSide ^ 1)); // Cross the To side.
}
else
{
Expand All @@ -311,14 +304,24 @@ DENG2_PIMPL(LineSightTest)
}

// We've arrived at a leaf.
return crossBspLeaf(bspTree->userData()->as<BspLeaf>());
auto const &bspLeaf = bspTree->userData()->as<BspLeaf>();

if(bspLeaf.hasSubspace())
{
return crossSubspace(bspLeaf.subspace());
}

// No subspace geometry implies a mapping error.
return false;
}
};

LineSightTest::LineSightTest(Vector3d const &from, Vector3d const &to,
dfloat bottomSlope, dfloat topSlope, dint flags)
: d(new Instance(this, from, to, bottomSlope, topSlope, flags))
{}
LineSightTest::LineSightTest(Vector3d const &from, Vector3d const &to, dfloat bottomSlope,
dfloat topSlope, dint flags)
: d(new Instance(from, to, bottomSlope, topSlope))
{
d->flags = flags;
}

bool LineSightTest::trace(BspTree const &bspRoot)
{
Expand Down

0 comments on commit 63b6236

Please sign in to comment.