Skip to content

Commit

Permalink
SectionEdge: Model the internal representation as a half-plane
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed May 4, 2013
1 parent 07d615f commit bfa7175
Show file tree
Hide file tree
Showing 8 changed files with 298 additions and 71 deletions.
2 changes: 2 additions & 0 deletions doomsday/client/client.pro
Expand Up @@ -116,6 +116,7 @@ DENG_HEADERS += \
include/Game \
include/Games \
include/HEdge \
include/IHPlane \
include/Line \
include/Plane \
include/Polyobj \
Expand Down Expand Up @@ -217,6 +218,7 @@ DENG_HEADERS += \
include/gl/sys_opengl.h \
include/gl/texturecontent.h \
include/gridmap.h \
include/ihplane.h \
include/library.h \
include/m_decomp64.h \
include/m_misc.h \
Expand Down
1 change: 1 addition & 0 deletions doomsday/client/include/IHPlane
@@ -0,0 +1 @@
#include "ihplane.h"
127 changes: 127 additions & 0 deletions doomsday/client/include/ihplane.h
@@ -0,0 +1,127 @@
/** @file ihplane.h Interface for a geometric half-plane.
*
* @authors Copyright © 2013 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#ifndef DENG_MATH_IHPLANE
#define DENG_MATH_IHPLANE

#include <de/Error>
#include <de/Vector>

#include "partition.h"

namespace de {

/**
* Interface for an interceptable geometric half-plane, which provides direct
* access to the data/class instance used to model an intersection point.
*/
class IHPlane
{
public:
/// An invalid reference to an intercept was specified. @ingroup errors
DENG2_ERROR(UnknownInterceptError);

/**
* Interface for an intercept in the implementing half-plane.
*/
class IIntercept
{
public:
IIntercept(ddouble distance) : _distance(distance) {}

virtual ~IIntercept() {}

/**
* Determines the distance between "this" and the @a other intercept
* along the half-plane. The default implementation simply subtracts
* the other distance from that of "this".
*/
virtual double operator - (IIntercept const &other) const {
return distance() - other.distance();
}

/**
* Determines whether the distance relative to the half-plane origin
* for "this" intercept is logically less than that of @a other. The
* default implementation simply compares the distance values.
*/
virtual bool operator < (IIntercept const &other) const {
return distance() < other.distance();
}

/**
* Returns distance along the half-plane relative to the origin.
* Implementors may override this for special functionality.
*/
virtual ddouble distance() const { return _distance; }

private:
ddouble _distance;
};

public:
virtual ~IHPlane() {}

/**
* Reconfigure the half-plane according to the given Partition line.
*
* @param newPartition The "new" partition line to configure using.
*/
virtual void configure(Partition const &newPartition) = 0;

/**
* Returns the Partition (immutable) used to model the partitioning line
* of the half-plane.
*/
virtual Partition const &partition() const = 0;

/**
* Clear the list of intercept "points" for the half-plane.
*/
virtual void clearIntercepts() = 0;

/**
* Attempt interception of the half-plane at @a distance from the origin.
*
* @param distance Distance along the half-plane to intersect.
*
* @return Resultant intercept if intersection occurs. Otherwise @c 0.
*/
virtual IIntercept const *intercept(ddouble distance) = 0;

/**
* Returns the total number of half-plane intercept points.
*/
virtual int interceptCount() const = 0;

/**
* Prepare the list of intercepts for search queries.
*/
virtual void sortAndMergeIntercepts() {}

/**
* @note Implementors are obligated to throw UnknownInterceptError if the
* specified @a index is not valid.
*/
virtual IIntercept const &at(int index) const = 0;
};

} // namespace de

#endif // DENG_MATH_IHPLANE
2 changes: 1 addition & 1 deletion doomsday/client/include/map/bsp/hplane.h
Expand Up @@ -205,7 +205,7 @@ class HPlane
* @note This list may or may not yet be sorted. If a sorted list is desired
* then sortAndMergeIntercepts() should first be called.
*
* @see interceptLineSegment(), intercepts()
* @see interceptLineSegment()
*/
Intercepts const &intercepts() const;

Expand Down
29 changes: 12 additions & 17 deletions doomsday/client/include/map/sectionedge.h
Expand Up @@ -21,20 +21,20 @@
#define DENG_WORLD_MAP_SECTIONEDGE

#include <QList>
#include <QtAlgorithms>

#include <de/Error>
#include <de/Vector>

#include "Line"
#include "HEdge"
#include "IHPlane"

/// Maximum number of intercepts in a SectionEdge.
#define SECTIONEDGE_MAX_INTERCEPTS 64

/**
* Helper/utility class intended to simplify the process of generating
* sections of drawable geometry from a map line segment.
* sections of geometry from a map line segment.
*
* @ingroup map
*/
Expand All @@ -44,19 +44,18 @@ class SectionEdge
/// Invalid range geometry was found during prepare() @ingroup errors
DENG2_ERROR(InvalidError);

struct Intercept
class Intercept : public de::IHPlane::IIntercept
{
SectionEdge *owner;
double distance;

public:
Intercept(SectionEdge *owner, double distance = 0);
Intercept(Intercept const &other);

inline bool operator < (Intercept const &other) const {
return distance < other.distance;
}
SectionEdge &owner() const;

de::Vector3d origin() const;

private:
SectionEdge *_owner;
};

typedef QList<Intercept> Intercepts;
Expand All @@ -79,13 +78,9 @@ class SectionEdge
d.swap(other.d);
}

inline Intercept const & operator [] (int index) const {
return at(index);
}
inline Intercept const & operator [] (int index) const { return at(index); }

Intercept const &at(int index) const {
return intercepts()[index];
}
Intercept const &at(int index) const;

void prepare();

Expand All @@ -101,9 +96,9 @@ class SectionEdge

int divisionCount() const;

Intercept &bottom() const;
Intercept const &bottom() const;

Intercept &top() const;
Intercept const &top() const;

int firstDivision() const;

Expand Down

0 comments on commit bfa7175

Please sign in to comment.