#include <Segment.h>
Public Types | |
typedef std::map< int, Surface * > | Surfacestore |
STL list of pointers to Surface objects. | |
typedef std::multimap< int, Area * > | Areastore |
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 Surfacestore & | getSurfaces () const |
Accessor for list of attached Surface objects. | |
Surfacestore & | getSurfaces () |
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. | |
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. | |
void | addMod (TerrainMod *t) |
Add a TerrainMod to this Segment. | |
void | clearMods () |
Delete all the modifications applied to this Segment. | |
const Areastore & | getAreas () const |
void | addArea (Area *a) |
void | clearAreas () |
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 (float nn, float fn, float ff, float nf, float roughness, float falloff, int depth) const |
quasi-Random Midpoint Displacement (qRMD) algorithm. | |
bool | clipToSegment (const WFMath::AxisBox< 2 > &bbox, int &lx, int &hx, int &ly, int &hy) |
Determine the intersection between an axis aligned box and this segment. | |
void | applyMod (TerrainMod *t) |
Modify the heightfield data using the TerrainMod objects which are attached to this Segment. | |
void | invalidateSurfaces () |
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, BasePoint > | m_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. |
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.
Mercator::Segment::~Segment | ( | ) |
void Mercator::Segment::addMod | ( | TerrainMod * | t | ) |
Add a TerrainMod to this Segment.
Called from Terrain::addMod(). If this point data is already valid, the modification will be applied directly.
void Mercator::Segment::applyMod | ( | 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.
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.
void Mercator::Segment::clearMods | ( | ) |
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.
bool Mercator::Segment::clipToSegment | ( | const WFMath::AxisBox< 2 > & | bbox, | |
int & | lx, | |||
int & | hx, | |||
int & | ly, | |||
int & | hy | |||
) | [private] |
Determine the intersection between an axis aligned box and this segment.
bbox | axis aligned box to be tested. | |
lx | lower x coordinate of intersection area. | |
hx | upper x coordinate of intersection area. | |
ly | lower y coordinate of intersection area. | |
hy | upper y coordinate of intersection area. |
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.
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.
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).
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. The Surface::invalidate() method is called for each surface associated with this Segment.
const bool Mercator::Segment::isValid | ( | ) | const [inline] |
void Mercator::Segment::populate | ( | ) |
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.
void Mercator::Segment::populateNormals | ( | ) |
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.
void Mercator::Segment::populateSurfaces | ( | ) |
Populate the surfaces associated with this Segment.
Call Surface::populate() for each Surface in turn.
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.
x | relative x coord of base point. Must be 0 or 1. | |
y | relative y coord of base point. Must be 0 or 1. | |
bp | BasePoint data to be used. |
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.