Mercator
Public Types | Public Member Functions | Private Member Functions | Private Attributes
Mercator::Segment Class Reference

Class storing heightfield and other data for a single fixed size square area of terrain defined by four adjacent BasePoint objects. More...

#include <Segment.h>

List of all members.

Public Types

typedef std::map< int, Surface * > Surfacestore
 STL map of pointers to Surface objects.
typedef std::multimap< int,
const Area * > 
Areastore
 STL multimap of pointers to Area objects affecting this segment.

Public Member Functions

 Segment (int x, int y, unsigned int resolution)
 Construct an empty segment with the given resolution.
 ~Segment ()
 Destruct the Segment.
const int getResolution () const
 Accessor for resolution of this segment.
const int getSize () const
 Accessor for array size of this segment.
const int getXRef () const
 Accessor for Global x reference of this segment.
const int getYRef () const
 Accessor for Global y reference of this segment.
const bool isValid () const
 Check whether this Segment contains valid point data.
void setMinMax (float min, float max)
 Set min and max height values for this Segment.
void invalidate (bool points=true)
 Mark the contents of this Segment as stale.
void setCornerPoint (unsigned int x, unsigned int y, const BasePoint &bp)
 Set the BasePoint data for one of the four that define this Segment.
const Matrix< 2, 2, BasePoint > & getControlPoints () const
 Accessor for 2D matrix of base points.
Matrix< 2, 2, BasePoint > & getControlPoints ()
 Accessor for modifying 2D matrix of base points.
const SurfacestoregetSurfaces () const
 Accessor for list of attached Surface objects.
SurfacestoregetSurfaces ()
 Accessor for modifying list of attached Surface objects.
const float * getPoints () const
 Accessor for buffer containing height points.
float * getPoints ()
 Accessor for write access to buffer containing height points.
const float * getNormals () const
 Accessor for buffer containing surface normals.
float * getNormals ()
 Accessor for write access to buffer containing surface normals.
float get (int x, int y) const
 Get the height at a relative integer position in the Segment.
void getHeightAndNormal (float x, float y, float &h, WFMath::Vector< 3 > &normal) const
 Get an accurate height and normal vector at a given coordinate relative to this segment.
bool clipToSegment (const WFMath::AxisBox< 2 > &bbox, int &lx, int &hx, int &ly, int &hy) const
 Determine the intersection between an axis aligned box and this segment.
void populate ()
 Populate the Segment with heightfield data.
void populateNormals ()
 Populate the Segment with surface normal data.
void populateSurfaces ()
 Populate the surfaces associated with this Segment.
float getMax () const
 Accessor for the maximum height value in this Segment.
float getMin () const
 Accessor for the minimum height value in this Segment.
WFMath::AxisBox< 2 > getRect () const
 The 2d area covered by this segment.
WFMath::AxisBox< 3 > getBox () const
 The 3d box covered by this segment.
int addMod (const TerrainMod *t)
 Add a TerrainMod to this Segment.
int updateMod (const TerrainMod *t)
 Update a TerrainMod in this Segment.
int removeMod (const TerrainMod *t)
 Remove a TerrainMod from this Segment.
void clearMods ()
 Delete all the modifications applied to this Segment.
const AreastoregetAreas () const
 Accessor for multimap of Area objects.
const ModList & getMods () const
int addArea (const Area *a)
 Add an area to those that affect this segment.
int updateArea (const Area *a)
int removeArea (const Area *a)
 Remove an area from those that affect this segment.

Private Member Functions

void checkMaxMin (float h)
 Check a value against m_min and m_max and set one of them if appropriate.
void fill1d (const BasePoint &l, const BasePoint &h, float *array) const
 One dimensional midpoint displacement fractal.
void fill2d (const BasePoint &p1, const BasePoint &p2, const BasePoint &p3, const BasePoint &p4)
 Two dimensional midpoint displacement fractal.
float qRMD (WFMath::MTRand &rng, float nn, float fn, float ff, float nf, float roughness, float falloff, int depth) const
 quasi-Random Midpoint Displacement (qRMD) algorithm.
void applyMod (const TerrainMod *t)
 Modify the heightfield data using the TerrainMod objects which are attached to this Segment.
void invalidateSurfaces ()
 Mark surfaces as stale.

Private Attributes

const int m_res
 Distance between segments.
const int m_size
 Size of segment, m_res + 1.
const int m_xRef
 Global x reference of this segment.
const int m_yRef
 Global y reference of this segment.
Matrix< 2, 2, BasePointm_controlPoints
 2x2 matrix of points which control this segment
float * m_points
 Pointer to buffer containing height points.
float * m_normals
 Pointer to buffer containing normals for height points.
float m_max
 Maximum height of any point in this segment.
float m_min
 Minimum height of any point in this segment.
Surfacestore m_surfaces
 Store of surfaces which can be rendered on this terrain.
Areastore m_areas
 Areas which intersect this segment.
ModList m_modList
 List of TerrainMod objects that are applied to this Segment.

Detailed Description

Class storing heightfield and other data for a single fixed size square area of terrain defined by four adjacent BasePoint objects.


Constructor & Destructor Documentation

Mercator::Segment::Segment ( int  x,
int  y,
unsigned int  resolution 
) [explicit]

Construct an empty segment with the given resolution.

Generally it is not necessary to call this from outside the Mercator library Segment objects are created as required. The Segment is constructed without allocating any storage for heightfield or surface normal data. The m_min and m_max members are initialised to extreme values, and should be set to appropriate using setMinMax() as soon as possible after construction. Similarly the control points should be set soon after construction.

Destruct the Segment.

Generally it is not necessary to delete Segment objects from application code, as Segment instances are owned by the Terrain object. Storage allocated for heightfield and surface normals is implicitly deleted as well as all surfaces.

References clearMods(), m_normals, m_points, and m_surfaces.


Member Function Documentation

int Mercator::Segment::addArea ( const Area ar)

Add an area to those that affect this segment.

Call from Terrain when an Area is added which is found to intersect this segment.

Parameters:
arthe area to be added.
Returns:
zero if the area was added, non-zero otherwise

References Mercator::Area::getLayer(), m_areas, m_surfaces, and Mercator::Shader::newSurface().

Add a TerrainMod to this Segment.

Called from Terrain::addMod(). If this point data is already valid, the modification will be applied directly.

References invalidate(), and m_modList.

void Mercator::Segment::applyMod ( const TerrainMod t) [private]

Modify the heightfield data using the TerrainMod objects which are attached to this Segment.

Usually called from Segment::populate(). It is not normally necessary to call this function from the application.

References Mercator::TerrainMod::apply(), Mercator::Effector::bbox(), clipToSegment(), invalidate(), m_points, m_size, m_xRef, and m_yRef.

Referenced by populate().

void Mercator::Segment::checkMaxMin ( float  h) [inline, private]

Check a value against m_min and m_max and set one of them if appropriate.

Called by internal functions whenever a new data point is generated.

References m_max, and m_min.

Referenced by fill2d().

Delete all the modifications applied to this Segment.

Usually called from the destructor. It is not normally necessary to call this function from the application.

References invalidate(), and m_modList.

Referenced by ~Segment().

bool Mercator::Segment::clipToSegment ( const WFMath::AxisBox< 2 > &  bbox,
int &  lx,
int &  hx,
int &  ly,
int &  hy 
) const

Determine the intersection between an axis aligned box and this segment.

Parameters:
bboxaxis aligned box to be tested.
lxlower x coordinate of intersection area.
hxupper x coordinate of intersection area.
lylower y coordinate of intersection area.
hyupper y coordinate of intersection area.
Returns:
true if the box intersects with this Segment, false otherwise.

References m_res.

Referenced by applyMod().

void Mercator::Segment::fill1d ( const BasePoint l,
const BasePoint h,
float *  array 
) const [private]

One dimensional midpoint displacement fractal.

Size must be a power of 2. Falloff is the decay of displacement as the fractal is refined. Array is size + 1 long. array[0] and array[size] are filled with the control points for the fractal.

References Mercator::BasePoint::FALLOFF, Mercator::BasePoint::height(), m_res, Mercator::BasePoint::roughness(), and Mercator::BasePoint::seed().

Referenced by fill2d().

void Mercator::Segment::fill2d ( const BasePoint p1,
const BasePoint p2,
const BasePoint p3,
const BasePoint p4 
) [private]

Two dimensional midpoint displacement fractal.

For a tile where edges are to be filled by 1d fractals. Size must be a power of 2, array is (size + 1) * (size + 1) with the corners the control points.

References checkMaxMin(), Mercator::BasePoint::FALLOFF, fill1d(), m_points, m_res, m_size, qRMD(), Mercator::BasePoint::roughness(), and Mercator::BasePoint::seed().

Referenced by populate().

void Mercator::Segment::getHeightAndNormal ( float  x,
float  y,
float &  h,
WFMath::Vector< 3 > &  normal 
) const

Get an accurate height and normal vector at a given coordinate relative to this segment.

The height and surface normal are determined by finding the four adjacent height points nearest to the coordinate, and interpolating between those height values. The square area defined by the 4 height points is considered as two triangles for the purposes of interpolation to ensure that the calculated height falls on the surface rendered by a 3D graphics engine from the same heightfield data. The line used to divide the area is defined by the gradient y = x, so the first triangle has relative vertex coordinates (0,0) (1,0) (1,1) and the second triangle has vertex coordinates (0,0) (0,1) (1,1).

References m_res.

Referenced by Mercator::Terrain::getHeightAndNormal().

void Mercator::Segment::invalidate ( bool  points = true)

Mark the contents of this Segment as stale.

This is called internally whenever changes occur that mean that the heightfield and surface normal data are no longer valid. If surface normal storage is deallocated, and if the points argument is true the heightfield storage is also deallocated.

References invalidateSurfaces(), m_normals, and m_points.

Referenced by addMod(), applyMod(), clearMods(), removeMod(), setCornerPoint(), and updateMod().

Mark surfaces as stale.

This is called internally from Segment::invalidate() when changes occur that mean the surface data is no longer valid. The Surface::invalidate() method is called for each surface.

References m_surfaces.

Referenced by invalidate().

const bool Mercator::Segment::isValid ( ) const [inline]

Check whether this Segment contains valid point data.

Returns:
true if this Segment is valid, false otherwise.

References m_points.

Referenced by Mercator::Terrain::get(), and Mercator::Terrain::getHeightAndNormal().

Populate the Segment with heightfield data.

Storage for the heightfield data is allocated if necessary, the qRMD algorithm is used to calculate the heightfield data, and required modifications are applied.

References applyMod(), fill2d(), m_controlPoints, m_modList, m_points, and m_size.

Populate the Segment with surface normal data.

Storage for the normals is allocated if necessary, and the average normal at each heightpoint is calculated. The middle normals are calculated first, followed by the boundaries which are done in 2 dimensions to ensure that there is no visible seam between segments.

References m_normals, m_points, m_res, and m_size.

Populate the surfaces associated with this Segment.

Call Surface::populate() for each Surface in turn.

References m_surfaces.

Referenced by Mercator::Terrain::shadeSurfaces().

Remove a TerrainMod from this Segment.

Called from Terrain::removeMod().

References invalidate(), and m_modList.

void Mercator::Segment::setCornerPoint ( unsigned int  x,
unsigned int  y,
const BasePoint bp 
) [inline]

Set the BasePoint data for one of the four that define this Segment.

Parameters:
xrelative x coord of base point. Must be 0 or 1.
yrelative y coord of base point. Must be 0 or 1.
bpBasePoint data to be used.

References invalidate(), and m_controlPoints.

Referenced by Mercator::Terrain::setBasePoint().

void Mercator::Segment::setMinMax ( float  min,
float  max 
) [inline]

Set min and max height values for this Segment.

This is used after construction to set the initial values, and should not be used after populate has been called.

References m_max, and m_min.

Referenced by Mercator::Terrain::setBasePoint().

Update a TerrainMod in this Segment.

Called from Terrain::removeMod().

References invalidate(), and m_modList.


The documentation for this class was generated from the following files: