Merge branch 'feature/region-enhancements' into develop
This commit is contained in:
@ -32,6 +32,19 @@ namespace PolyVox
|
||||
{
|
||||
POLYVOX_API uint8_t logBase2(uint32_t uInput);
|
||||
POLYVOX_API bool isPowerOf2(uint32_t uInput);
|
||||
|
||||
int32_t roundTowardsNegInf(float r);
|
||||
int32_t roundToInteger(float r);
|
||||
|
||||
inline int32_t roundTowardsNegInf(float r)
|
||||
{
|
||||
return (r > 0.0) ? static_cast<int32_t>(r) : static_cast<int32_t>(r - 1.0f);
|
||||
}
|
||||
|
||||
inline int32_t roundToNearestInteger(float r)
|
||||
{
|
||||
return (r > 0.0) ? static_cast<int32_t>(r + 0.5f) : static_cast<int32_t>(r - 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -30,21 +30,25 @@ freely, subject to the following restrictions:
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
/**
|
||||
Represents a part of a Volume.
|
||||
|
||||
Many operations in PolyVox are constrained to only part of a volume. For example, when running the surface extractors
|
||||
it is unlikely that you will want to run it on the whole volume at once, as this will give a very large mesh which may
|
||||
be too much to render. Instead you will probably want to run a surface extractor a number of times on different parts
|
||||
of the volume, there by giving a number of meshes which can be culled and rendered seperately.
|
||||
|
||||
The Region class is used to define these parts (regions) of the volume. Essentially it consists of an upper and lower
|
||||
bound which specify the range of voxels positions considered to be part of the region. Note that these bounds are
|
||||
<em>inclusive</em>. The class also provides functions for modifying the regions in a variety of ways.
|
||||
|
||||
\Note The dimensions of a region can be measured either in voxels or in cells. See the manual for more information
|
||||
about these definitions.
|
||||
*/
|
||||
/// Represents a part of a Volume.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Many operations in PolyVox are constrained to only part of a volume. For example, when running the surface extractors
|
||||
/// it is unlikely that you will want to run it on the whole volume at once, as this will give a very large mesh which may
|
||||
/// be too much to render. Instead you will probably want to run a surface extractor a number of times on different parts
|
||||
/// of the volume, there by giving a number of meshes which can be culled and rendered seperately.
|
||||
///
|
||||
/// The Region class is used to define these parts (regions) of the volume. Essentially it consists of an upper and lower
|
||||
/// bound which specify the range of voxels positions considered to be part of the region. Note that these bounds are
|
||||
/// <em>inclusive</em>.
|
||||
///
|
||||
/// As well as the expected set of getters and setters, this class also provide utility functions for increasing and decresing
|
||||
/// the size of the Region, shifting the Region in 3D space, testing whether it contains a given position, enlarging it so that
|
||||
/// it does contain a given position, croppng it to another Region, and various other utility functions.
|
||||
///
|
||||
/// \Note The dimensions of a region can be measured either in voxels or in cells. See the manual for more information
|
||||
/// about these definitions.
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef SWIG
|
||||
class Region
|
||||
#else
|
||||
@ -53,11 +57,16 @@ namespace PolyVox
|
||||
{
|
||||
public:
|
||||
|
||||
/// A Region with the lower corner set as low as possible and the upper corner set as high as possible.
|
||||
static const Region MaxRegion;
|
||||
/// A Region with the lower corner set as high as possible and the upper corner set as low as possible.
|
||||
static const Region InvertedRegion;
|
||||
|
||||
/// Constructor
|
||||
Region();
|
||||
/// Constructor
|
||||
Region(const Vector3DInt32& v3dLowerCorner, const Vector3DInt32& v3dUpperCorner);
|
||||
/// Constructor
|
||||
Region(int32_t iLowerX, int32_t iLowerY, int32_t iLowerZ, int32_t iUpperX, int32_t iUpperY, int32_t iUpperZ);
|
||||
|
||||
/// Equality Operator.
|
||||
@ -65,65 +74,117 @@ namespace PolyVox
|
||||
/// Inequality Operator.
|
||||
bool operator!=(const Region& rhs) const;
|
||||
|
||||
/// Gets the 'x' position of the lower corner.
|
||||
int32_t getLowerX(void) const;
|
||||
/// Gets the 'y' position of the lower corner.
|
||||
int32_t getLowerY(void) const;
|
||||
/// Gets the 'z' position of the lower corner.
|
||||
int32_t getLowerZ(void) const;
|
||||
/// Gets the 'x' position of the upper corner.
|
||||
int32_t getUpperX(void) const;
|
||||
/// Gets the 'y' position of the upper corner.
|
||||
int32_t getUpperY(void) const;
|
||||
/// Gets the 'z' position of the upper corner.
|
||||
int32_t getUpperZ(void) const;
|
||||
|
||||
/// Gets the position of the lower corner.
|
||||
Vector3DInt32 getLowerCorner(void) const;
|
||||
/// Gets the position of the upper corner.
|
||||
Vector3DInt32 getUpperCorner(void) const;
|
||||
|
||||
/// Gets the width of the region measured in voxels
|
||||
/// Gets the width of the region measured in voxels.
|
||||
int32_t getWidthInVoxels(void) const;
|
||||
/// Gets the height of the region measured in voxels
|
||||
/// Gets the height of the region measured in voxels.
|
||||
int32_t getHeightInVoxels(void) const;
|
||||
/// Gets the depth of the region measured in voxels
|
||||
/// Gets the depth of the region measured in voxels.
|
||||
int32_t getDepthInVoxels(void) const;
|
||||
/// Gets the dimensions of the region measured in voxels
|
||||
/// Gets the dimensions of the region measured in voxels.
|
||||
Vector3DInt32 getDimensionsInVoxels(void) const;
|
||||
|
||||
/// Gets the width of the region measured in cells
|
||||
/// Gets the width of the region measured in cells.
|
||||
int32_t getWidthInCells(void) const;
|
||||
/// Gets the height of the region measured in cells
|
||||
/// Gets the height of the region measured in cells.
|
||||
int32_t getHeightInCells(void) const;
|
||||
/// Gets the depth of the region measured in cells
|
||||
/// Gets the depth of the region measured in cells.
|
||||
int32_t getDepthInCells(void) const;
|
||||
/// Gets the dimensions of the region measured in cells
|
||||
/// Gets the dimensions of the region measured in cells.
|
||||
Vector3DInt32 getDimensionsInCells(void) const;
|
||||
|
||||
bool isValid(void);
|
||||
|
||||
/// Sets the 'x' position of the lower corner.
|
||||
void setLowerX(int32_t iX);
|
||||
/// Sets the 'y' position of the lower corner.
|
||||
void setLowerY(int32_t iY);
|
||||
/// Sets the 'z' position of the lower corner.
|
||||
void setLowerZ(int32_t iZ);
|
||||
/// Sets the 'x' position of the upper corner.
|
||||
void setUpperX(int32_t iX);
|
||||
/// Sets the 'y' position of the upper corner.
|
||||
void setUpperY(int32_t iY);
|
||||
/// Sets the 'z' position of the upper corner.
|
||||
void setUpperZ(int32_t iZ);
|
||||
|
||||
/// Sets the position of the lower corner.
|
||||
void setLowerCorner(const Vector3DInt32& v3dLowerCorner);
|
||||
/// Sets the position of the upper corner.
|
||||
void setUpperCorner(const Vector3DInt32& v3dUpperCorner);
|
||||
|
||||
/// Tests whether the given point is contained in this Region.
|
||||
bool containsPoint(const Vector3DFloat& pos, float boundary = 0.0f) const;
|
||||
/// Tests whether the given point is contained in this Region.
|
||||
bool containsPoint(const Vector3DInt32& pos, uint8_t boundary = 0) const;
|
||||
//FIXME - Don't like these. Make containsPoint take flags indicating which axes to check?
|
||||
/// Tests whether the given position is contained in the 'x' range of this Region.
|
||||
bool containsPointInX(float pos, float boundary = 0.0f) const;
|
||||
/// Tests whether the given position is contained in the 'x' range of this Region.
|
||||
bool containsPointInX(int32_t pos, uint8_t boundary = 0) const;
|
||||
/// Tests whether the given position is contained in the 'y' range of this Region.
|
||||
bool containsPointInY(float pos, float boundary = 0.0f) const;
|
||||
/// Tests whether the given position is contained in the 'y' range of this Region.
|
||||
bool containsPointInY(int32_t pos, uint8_t boundary = 0) const;
|
||||
/// Tests whether the given position is contained in the 'z' range of this Region.
|
||||
bool containsPointInZ(float pos, float boundary = 0.0f) const;
|
||||
/// Tests whether the given position is contained in the 'z' range of this Region.
|
||||
bool containsPointInZ(int32_t pos, uint8_t boundary = 0) const;
|
||||
void cropTo(const Region& other);
|
||||
|
||||
void shift(const Vector3DInt32& amount);
|
||||
void shiftLowerCorner(const Vector3DInt32& amount);
|
||||
void shiftUpperCorner(const Vector3DInt32& amount);
|
||||
//FIXME - Add dilate and erode functions?
|
||||
|
||||
void dilate(int32_t amount);
|
||||
void erode(int32_t amount);
|
||||
|
||||
/// Enlarges the Region so that it contains the specified position.
|
||||
void accumulate(int32_t iX, int32_t iY, int32_t iZ);
|
||||
/// Enlarges the Region so that it contains the specified position.
|
||||
void accumulate(const Vector3DInt32& v3dPos);
|
||||
/// Enlarges the Region so that it contains the specified Region.
|
||||
void accumulate(const Region& reg);
|
||||
|
||||
/// Crops the extents of this Region accoring to another Region.
|
||||
void cropTo(const Region& other);
|
||||
|
||||
/// Enlarges this region by the amount specified.
|
||||
void dilate(int32_t iAmount);
|
||||
/// Enlarges this region by the amounts specified.
|
||||
void dilate(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ);
|
||||
/// Enlarges this region by the amounts specified.
|
||||
void dilate(const Vector3DInt32& v3dAmount);
|
||||
|
||||
/// Shrinks this region by the amount specified.
|
||||
void erode(int32_t iAmount);
|
||||
/// Shrinks this region by the amounts specified.
|
||||
void erode(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ);
|
||||
/// Shrinks this region by the amounts specified.
|
||||
void erode(const Vector3DInt32& v3dAmount);
|
||||
|
||||
/// Tests whether all components of the upper corner are at least
|
||||
/// as great as the corresponding components of the lower corner.
|
||||
bool isValid(void) const;
|
||||
|
||||
/// Moves the Region by the amount specified.
|
||||
void shift(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ);
|
||||
/// Moves the Region by the amount specified.
|
||||
void shift(const Vector3DInt32& v3dAmount);
|
||||
/// Moves the lower corner of the Region by the amount specified.
|
||||
void shiftLowerCorner(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ);
|
||||
/// Moves the lower corner of the Region by the amount specified.
|
||||
void shiftLowerCorner(const Vector3DInt32& v3dAmount);
|
||||
/// Moves the upper corner of the Region by the amount specified.
|
||||
void shiftUpperCorner(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ);
|
||||
/// Moves the upper corner of the Region by the amount specified.
|
||||
void shiftUpperCorner(const Vector3DInt32& v3dAmount);
|
||||
|
||||
private:
|
||||
int32_t m_iLowerX;
|
||||
@ -133,6 +194,214 @@ namespace PolyVox
|
||||
int32_t m_iUpperY;
|
||||
int32_t m_iUpperZ;
|
||||
};
|
||||
|
||||
// Functions to be inlined to to be in the header rather than the .cpp.
|
||||
// 'inline' keyword is used for the definition rather than the declaration.
|
||||
// See also http://www.parashift.com/c++-faq-lite/inline-functions.html
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The 'x' position of the lower corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getLowerX(void) const
|
||||
{
|
||||
return m_iLowerX;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The 'y' position of the lower corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getLowerY(void) const
|
||||
{
|
||||
return m_iLowerY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The 'z' position of the lower corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getLowerZ(void) const
|
||||
{
|
||||
return m_iLowerZ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The 'x' position of the upper corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getUpperX(void) const
|
||||
{
|
||||
return m_iUpperX;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The 'y' position of the upper corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getUpperY(void) const
|
||||
{
|
||||
return m_iUpperY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The 'z' position of the upper corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getUpperZ(void) const
|
||||
{
|
||||
return m_iUpperZ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The position of the lower corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline Vector3DInt32 Region::getLowerCorner(void) const
|
||||
{
|
||||
return Vector3DInt32(m_iLowerX, m_iLowerY, m_iLowerZ);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The position of the upper corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline Vector3DInt32 Region::getUpperCorner(void) const
|
||||
{
|
||||
return Vector3DInt32(m_iUpperX, m_iUpperY, m_iUpperZ);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The width of the region measured in voxels.
|
||||
/// \sa getWidthInCells()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getWidthInVoxels(void) const
|
||||
{
|
||||
return getWidthInCells() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The height of the region measured in voxels.
|
||||
/// \sa getHeightInCells()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getHeightInVoxels(void) const
|
||||
{
|
||||
return getHeightInCells() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The depth of the region measured in voxels.
|
||||
/// \sa getDepthInCells()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getDepthInVoxels(void) const
|
||||
{
|
||||
return getDepthInCells() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The dimensions of the region measured in voxels.
|
||||
/// \sa getDimensionsInCells()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline Vector3DInt32 Region::getDimensionsInVoxels(void) const
|
||||
{
|
||||
return getDimensionsInCells() + Vector3DInt32(1, 1, 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The width of the region measured in cells.
|
||||
/// \sa getWidthInVoxels()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getWidthInCells(void) const
|
||||
{
|
||||
return m_iUpperX - m_iLowerX;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The height of the region measured in cells.
|
||||
/// \sa getHeightInVoxels()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getHeightInCells(void) const
|
||||
{
|
||||
return m_iUpperY - m_iLowerY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The depth of the region measured in cells.
|
||||
/// \sa getDepthInVoxels()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline int32_t Region::getDepthInCells(void) const
|
||||
{
|
||||
return m_iUpperZ - m_iLowerZ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \return The dimensions of the region measured in cells.
|
||||
/// \sa getDimensionsInVoxels()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline Vector3DInt32 Region::getDimensionsInCells(void) const
|
||||
{
|
||||
return Vector3DInt32(getWidthInCells(), getHeightInCells(), getDepthInCells());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iX The new 'x' position of the lower corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline void Region::setLowerX(int32_t iX)
|
||||
{
|
||||
m_iLowerX = iX;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iY The new 'y' position of the lower corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline void Region::setLowerY(int32_t iY)
|
||||
{
|
||||
m_iLowerY = iY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iZ The new 'z' position of the lower corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline void Region::setLowerZ(int32_t iZ)
|
||||
{
|
||||
m_iLowerZ = iZ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iX The new 'x' position of the upper corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline void Region::setUpperX(int32_t iX)
|
||||
{
|
||||
m_iUpperX = iX;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iY The new 'y' position of the upper corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline void Region::setUpperY(int32_t iY)
|
||||
{
|
||||
m_iUpperY = iY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iZ The new 'z' position of the upper corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline void Region::setUpperZ(int32_t iZ)
|
||||
{
|
||||
m_iUpperZ = iZ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dLowerCorner The new position of the lower corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline void Region::setLowerCorner(const Vector3DInt32& v3dLowerCorner)
|
||||
{
|
||||
m_iLowerX = v3dLowerCorner.getX();
|
||||
m_iLowerY = v3dLowerCorner.getY();
|
||||
m_iLowerZ = v3dLowerCorner.getZ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dUpperCorner The new position of the upper corner.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline void Region::setUpperCorner(const Vector3DInt32& v3dUpperCorner)
|
||||
{
|
||||
m_iUpperX = v3dUpperCorner.getX();
|
||||
m_iUpperY = v3dUpperCorner.getY();
|
||||
m_iUpperZ = v3dUpperCorner.getZ();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -23,22 +23,75 @@ freely, subject to the following restrictions:
|
||||
|
||||
#include "PolyVoxCore/Region.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
namespace PolyVox
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const Region Region::MaxRegion
|
||||
(
|
||||
Vector3DInt32((std::numeric_limits<int32_t>::min)(), (std::numeric_limits<int32_t>::min)(), (std::numeric_limits<int32_t>::min)()),
|
||||
Vector3DInt32((std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)())
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// This Region is not considered valid as defined by isValid(). It's main application
|
||||
/// is to initialise a Region to this value and then() accumulate positions. The result
|
||||
/// of this will be a Region which encompasses all positions specified.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const Region Region::InvertedRegion
|
||||
(
|
||||
Vector3DInt32((std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)(), (std::numeric_limits<int32_t>::max)()),
|
||||
Vector3DInt32((std::numeric_limits<int32_t>::min)(), (std::numeric_limits<int32_t>::min)(), (std::numeric_limits<int32_t>::min)())
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iX The 'x' component of the position to accumulate.
|
||||
/// \param iY The 'y' component of the position to accumulate.
|
||||
/// \param iZ The 'z' component of the position to accumulate.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::accumulate(int32_t iX, int32_t iY, int32_t iZ)
|
||||
{
|
||||
m_iLowerX = ((std::min)(m_iLowerX, iX));
|
||||
m_iLowerY = ((std::min)(m_iLowerY, iY));
|
||||
m_iLowerZ = ((std::min)(m_iLowerZ, iZ));
|
||||
m_iUpperX = ((std::max)(m_iUpperX, iX));
|
||||
m_iUpperY = ((std::max)(m_iUpperY, iY));
|
||||
m_iUpperZ = ((std::max)(m_iUpperZ, iZ));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dPos The position to accumulate.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::accumulate(const Vector3DInt32& v3dPos)
|
||||
{
|
||||
accumulate(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Note that this is not the same as computing the union of two Regions (as the result of
|
||||
/// such a union may not be a shape which can be exactly represented by a Region). Instead,
|
||||
/// the result is simply big enough to contain both this Region and the one passed as a parameter.
|
||||
/// \param reg The Region to accumulate. This must be valid as defined by the isValid() function.
|
||||
/// \sa isValid()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::accumulate(const Region& reg)
|
||||
{
|
||||
assert(reg.isValid(), "The result of accumulating an invalid region is not defined.");
|
||||
|
||||
m_iLowerX = ((std::min)(m_iLowerX, reg.getLowerX()));
|
||||
m_iLowerY = ((std::min)(m_iLowerY, reg.getLowerY()));
|
||||
m_iLowerZ = ((std::min)(m_iLowerZ, reg.getLowerZ()));
|
||||
m_iUpperX = ((std::max)(m_iUpperX, reg.getUpperX()));
|
||||
m_iUpperY = ((std::max)(m_iUpperY, reg.getUpperY()));
|
||||
m_iUpperZ = ((std::max)(m_iUpperZ, reg.getUpperZ()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constructs a Region and clears all extents to zero.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Region::Region()
|
||||
:m_iLowerX(0)
|
||||
,m_iLowerY(0)
|
||||
@ -49,6 +102,11 @@ namespace PolyVox
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constructs a Region and sets the lower and upper corners to the specified values.
|
||||
/// \param v3dLowerCorner The desired lower corner of the Region.
|
||||
/// \param v3dUpperCorner The desired upper corner of the Region.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Region::Region(const Vector3DInt32& v3dLowerCorner, const Vector3DInt32& v3dUpperCorner)
|
||||
:m_iLowerX(v3dLowerCorner.getX())
|
||||
,m_iLowerY(v3dLowerCorner.getY())
|
||||
@ -59,6 +117,15 @@ namespace PolyVox
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constructs a Region and sets the extents to the specified values.
|
||||
/// \param iLowerX The desired lower 'x' extent of the Region.
|
||||
/// \param iLowerY The desired lower 'y' extent of the Region.
|
||||
/// \param iLowerZ The desired lower 'z' extent of the Region.
|
||||
/// \param iUpperX The desired upper 'x' extent of the Region.
|
||||
/// \param iUpperY The desired upper 'y' extent of the Region.
|
||||
/// \param iUpperZ The desired upper 'z' extent of the Region.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Region::Region(int32_t iLowerX, int32_t iLowerY, int32_t iLowerZ, int32_t iUpperX, int32_t iUpperY, int32_t iUpperZ)
|
||||
:m_iLowerX(iLowerX)
|
||||
,m_iLowerY(iLowerY)
|
||||
@ -69,158 +136,36 @@ namespace PolyVox
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
Checks whether two Regions are equal.
|
||||
\param rhs The Region to compare to.
|
||||
\return true if the Regions match.
|
||||
\see operator!=
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Two regions are considered equal if all their extents match.
|
||||
/// \param rhs The Region to compare to.
|
||||
/// \return true if the Regions match.
|
||||
/// \sa operator!=
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::operator==(const Region& rhs) const
|
||||
{
|
||||
return ((m_iLowerX == rhs.m_iLowerX) && (m_iLowerY == rhs.m_iLowerY) && (m_iLowerZ == rhs.m_iLowerZ)
|
||||
&& (m_iUpperX == rhs.m_iUpperX) && (m_iUpperY == rhs.m_iUpperY) && (m_iUpperZ == rhs.m_iUpperZ));
|
||||
}
|
||||
|
||||
/**
|
||||
Checks whether two Regions are not equal.
|
||||
\param rhs The Region to compare to.
|
||||
\return true if the Regions do not match.
|
||||
\see operator==
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Two regions are considered different if any of their extents differ.
|
||||
/// \param rhs The Region to compare to.
|
||||
/// \return true if the Regions are different.
|
||||
/// \sa operator==
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::operator!=(const Region& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
int32_t Region::getLowerX(void) const
|
||||
{
|
||||
return m_iLowerX;
|
||||
}
|
||||
|
||||
int32_t Region::getLowerY(void) const
|
||||
{
|
||||
return m_iLowerY;
|
||||
}
|
||||
|
||||
int32_t Region::getLowerZ(void) const
|
||||
{
|
||||
return m_iLowerZ;
|
||||
}
|
||||
|
||||
int32_t Region::getUpperX(void) const
|
||||
{
|
||||
return m_iUpperX;
|
||||
}
|
||||
|
||||
int32_t Region::getUpperY(void) const
|
||||
{
|
||||
return m_iUpperY;
|
||||
}
|
||||
|
||||
int32_t Region::getUpperZ(void) const
|
||||
{
|
||||
return m_iUpperZ;
|
||||
}
|
||||
|
||||
Vector3DInt32 Region::getLowerCorner(void) const
|
||||
{
|
||||
return Vector3DInt32(m_iLowerX, m_iLowerY, m_iLowerZ);
|
||||
}
|
||||
|
||||
Vector3DInt32 Region::getUpperCorner(void) const
|
||||
{
|
||||
return Vector3DInt32(m_iUpperX, m_iUpperY, m_iUpperZ);
|
||||
}
|
||||
|
||||
int32_t Region::getWidthInVoxels(void) const
|
||||
{
|
||||
return getWidthInCells() + 1;
|
||||
}
|
||||
|
||||
int32_t Region::getHeightInVoxels(void) const
|
||||
{
|
||||
return getHeightInCells() + 1;
|
||||
}
|
||||
|
||||
int32_t Region::getDepthInVoxels(void) const
|
||||
{
|
||||
return getDepthInCells() + 1;
|
||||
}
|
||||
|
||||
Vector3DInt32 Region::getDimensionsInVoxels(void) const
|
||||
{
|
||||
return getDimensionsInCells() + Vector3DInt32(1, 1, 1);
|
||||
}
|
||||
|
||||
int32_t Region::getWidthInCells(void) const
|
||||
{
|
||||
return m_iUpperX - m_iLowerX;
|
||||
}
|
||||
|
||||
int32_t Region::getHeightInCells(void) const
|
||||
{
|
||||
return m_iUpperY - m_iLowerY;
|
||||
}
|
||||
|
||||
Vector3DInt32 Region::getDimensionsInCells(void) const
|
||||
{
|
||||
return Vector3DInt32(getWidthInCells(), getHeightInCells(), getDepthInCells());
|
||||
}
|
||||
|
||||
int32_t Region::getDepthInCells(void) const
|
||||
{
|
||||
return m_iUpperZ - m_iLowerZ;
|
||||
}
|
||||
|
||||
bool Region::isValid(void)
|
||||
{
|
||||
return (m_iUpperX >= m_iLowerX) && (m_iUpperY >= m_iLowerY) && (m_iUpperZ >= m_iLowerZ);
|
||||
}
|
||||
|
||||
void Region::setLowerX(int32_t iX)
|
||||
{
|
||||
m_iLowerX = iX;
|
||||
}
|
||||
|
||||
void Region::setLowerY(int32_t iY)
|
||||
{
|
||||
m_iLowerY = iY;
|
||||
}
|
||||
|
||||
void Region::setLowerZ(int32_t iZ)
|
||||
{
|
||||
m_iLowerZ = iZ;
|
||||
}
|
||||
|
||||
void Region::setUpperX(int32_t iX)
|
||||
{
|
||||
m_iUpperX = iX;
|
||||
}
|
||||
|
||||
void Region::setUpperY(int32_t iY)
|
||||
{
|
||||
m_iUpperY = iY;
|
||||
}
|
||||
|
||||
void Region::setUpperZ(int32_t iZ)
|
||||
{
|
||||
m_iUpperZ = iZ;
|
||||
}
|
||||
|
||||
void Region::setLowerCorner(const Vector3DInt32& v3dLowerCorner)
|
||||
{
|
||||
m_iLowerX = v3dLowerCorner.getX();
|
||||
m_iLowerY = v3dLowerCorner.getY();
|
||||
m_iLowerZ = v3dLowerCorner.getZ();
|
||||
}
|
||||
|
||||
void Region::setUpperCorner(const Vector3DInt32& v3dUpperCorner)
|
||||
{
|
||||
m_iUpperX = v3dUpperCorner.getX();
|
||||
m_iUpperY = v3dUpperCorner.getY();
|
||||
m_iUpperZ = v3dUpperCorner.getZ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The boundary value can be used to ensure a position is only considered to be inside
|
||||
/// the Region if it is that far in in all directions. Also, the test is inclusive such
|
||||
/// that positions lying exactly on the edge of the Region are considered to be inside it.
|
||||
/// \param pos The position to test.
|
||||
/// \param boundary The desired boundary value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::containsPoint(const Vector3DFloat& pos, float boundary) const
|
||||
{
|
||||
return (pos.getX() <= m_iUpperX - boundary)
|
||||
@ -231,6 +176,13 @@ namespace PolyVox
|
||||
&& (pos.getZ() >= m_iLowerZ + boundary);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The boundary value can be used to ensure a position is only considered to be inside
|
||||
/// the Region if it is that far in in all directions. Also, the test is inclusive such
|
||||
/// that positions lying exactly on the edge of the Region are considered to be inside it.
|
||||
/// \param pos The position to test.
|
||||
/// \param boundary The desired boundary value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::containsPoint(const Vector3DInt32& pos, uint8_t boundary) const
|
||||
{
|
||||
return (pos.getX() <= m_iUpperX - boundary)
|
||||
@ -241,42 +193,89 @@ namespace PolyVox
|
||||
&& (pos.getZ() >= m_iLowerZ + boundary);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The boundary value can be used to ensure a position is only considered to be inside
|
||||
/// the Region if it is that far in in the 'x' direction. Also, the test is inclusive such
|
||||
/// that positions lying exactly on the edge of the Region are considered to be inside it.
|
||||
/// \param pos The position to test.
|
||||
/// \param boundary The desired boundary value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::containsPointInX(float pos, float boundary) const
|
||||
{
|
||||
return (pos <= m_iUpperX - boundary)
|
||||
&& (pos >= m_iLowerX + boundary);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The boundary value can be used to ensure a position is only considered to be inside
|
||||
/// the Region if it is that far in in the 'x' direction. Also, the test is inclusive such
|
||||
/// that positions lying exactly on the edge of the Region are considered to be inside it.
|
||||
/// \param pos The position to test.
|
||||
/// \param boundary The desired boundary value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::containsPointInX(int32_t pos, uint8_t boundary) const
|
||||
{
|
||||
return (pos <= m_iUpperX - boundary)
|
||||
&& (pos >= m_iLowerX + boundary);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The boundary value can be used to ensure a position is only considered to be inside
|
||||
/// the Region if it is that far in in the 'y' direction. Also, the test is inclusive such
|
||||
/// that positions lying exactly on the edge of the Region are considered to be inside it.
|
||||
/// \param pos The position to test.
|
||||
/// \param boundary The desired boundary value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::containsPointInY(float pos, float boundary) const
|
||||
{
|
||||
return (pos <= m_iUpperY - boundary)
|
||||
&& (pos >= m_iLowerY + boundary);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The boundary value can be used to ensure a position is only considered to be inside
|
||||
/// the Region if it is that far in in the 'y' direction. Also, the test is inclusive such
|
||||
/// that positions lying exactly on the edge of the Region are considered to be inside it.
|
||||
/// \param pos The position to test.
|
||||
/// \param boundary The desired boundary value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::containsPointInY(int32_t pos, uint8_t boundary) const
|
||||
{
|
||||
return (pos <= m_iUpperY - boundary)
|
||||
&& (pos >= m_iLowerY + boundary);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The boundary value can be used to ensure a position is only considered to be inside
|
||||
/// the Region if it is that far in in the 'z' direction. Also, the test is inclusive such
|
||||
/// that positions lying exactly on the edge of the Region are considered to be inside it.
|
||||
/// \param pos The position to test.
|
||||
/// \param boundary The desired boundary value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::containsPointInZ(float pos, float boundary) const
|
||||
{
|
||||
return (pos <= m_iUpperZ - boundary)
|
||||
&& (pos >= m_iLowerZ + boundary);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The boundary value can be used to ensure a position is only considered to be inside
|
||||
/// the Region if it is that far in in the 'z' direction. Also, the test is inclusive such
|
||||
/// that positions lying exactly on the edge of the Region are considered to be inside it.
|
||||
/// \param pos The position to test.
|
||||
/// \param boundary The desired boundary value.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::containsPointInZ(int32_t pos, uint8_t boundary) const
|
||||
{
|
||||
return (pos <= m_iUpperZ - boundary)
|
||||
&& (pos >= m_iLowerZ + boundary);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// After calling this functions, the extents of this Region are given by the intersection
|
||||
/// of this Region and the one it was cropped to.
|
||||
/// \param other The Region to crop to.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::cropTo(const Region& other)
|
||||
{
|
||||
m_iLowerX = ((std::max)(m_iLowerX, other.m_iLowerX));
|
||||
@ -287,45 +286,158 @@ namespace PolyVox
|
||||
m_iUpperZ = ((std::min)(m_iUpperZ, other.m_iUpperZ));
|
||||
}
|
||||
|
||||
void Region::shift(const Vector3DInt32& amount)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The same amount of dilation is applied in all directions. Negative dilations
|
||||
/// are possible but you should prefer the erode() function for clarity.
|
||||
/// \param iAmount The amount to dilate by.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::dilate(int32_t iAmount)
|
||||
{
|
||||
shiftLowerCorner(amount);
|
||||
shiftUpperCorner(amount);
|
||||
m_iLowerX -= iAmount;
|
||||
m_iLowerY -= iAmount;
|
||||
m_iLowerZ -= iAmount;
|
||||
|
||||
m_iUpperX += iAmount;
|
||||
m_iUpperY += iAmount;
|
||||
m_iUpperZ += iAmount;
|
||||
}
|
||||
|
||||
void Region::shiftLowerCorner(const Vector3DInt32& amount)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The dilation can be specified seperatly for each direction. Negative dilations
|
||||
/// are possible but you should prefer the erode() function for clarity.
|
||||
/// \param iAmountX The amount to dilate by in 'x'.
|
||||
/// \param iAmountY The amount to dilate by in 'y'.
|
||||
/// \param iAmountZ The amount to dilate by in 'z'.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::dilate(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ)
|
||||
{
|
||||
m_iLowerX += amount.getX();
|
||||
m_iLowerY += amount.getY();
|
||||
m_iLowerZ += amount.getZ();
|
||||
m_iLowerX -= iAmountX;
|
||||
m_iLowerY -= iAmountY;
|
||||
m_iLowerZ -= iAmountZ;
|
||||
|
||||
m_iUpperX += iAmountX;
|
||||
m_iUpperY += iAmountY;
|
||||
m_iUpperZ += iAmountZ;
|
||||
}
|
||||
|
||||
void Region::shiftUpperCorner(const Vector3DInt32& amount)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The dilation can be specified seperatly for each direction. Negative dilations
|
||||
/// are possible but you should prefer the erode() function for clarity.
|
||||
/// \param v3dAmount The amount to dilate by (one components for each direction).
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::dilate(const Vector3DInt32& v3dAmount)
|
||||
{
|
||||
m_iUpperX += amount.getX();
|
||||
m_iUpperY += amount.getY();
|
||||
m_iUpperZ += amount.getZ();
|
||||
dilate(v3dAmount.getX(), v3dAmount.getY(), v3dAmount.getZ());
|
||||
}
|
||||
|
||||
void Region::dilate(int32_t amount)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The same amount of erosion is applied in all directions. Negative erosions
|
||||
/// are possible but you should prefer the dilate() function for clarity.
|
||||
/// \param iAmount The amount to erode by.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::erode(int32_t iAmount)
|
||||
{
|
||||
m_iLowerX -= amount;
|
||||
m_iLowerY -= amount;
|
||||
m_iLowerZ -= amount;
|
||||
m_iLowerX += iAmount;
|
||||
m_iLowerY += iAmount;
|
||||
m_iLowerZ += iAmount;
|
||||
|
||||
m_iUpperX += amount;
|
||||
m_iUpperY += amount;
|
||||
m_iUpperZ += amount;
|
||||
m_iUpperX -= iAmount;
|
||||
m_iUpperY -= iAmount;
|
||||
m_iUpperZ -= iAmount;
|
||||
}
|
||||
|
||||
void Region::erode(int32_t amount)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The erosion can be specified seperatly for each direction. Negative erosions
|
||||
/// are possible but you should prefer the dilate() function for clarity.
|
||||
/// \param iAmountX The amount to erode by in 'x'.
|
||||
/// \param iAmountY The amount to erode by in 'y'.
|
||||
/// \param iAmountZ The amount to erode by in 'z'.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::erode(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ)
|
||||
{
|
||||
m_iLowerX += amount;
|
||||
m_iLowerY += amount;
|
||||
m_iLowerZ += amount;
|
||||
m_iLowerX += iAmountX;
|
||||
m_iLowerY += iAmountY;
|
||||
m_iLowerZ += iAmountZ;
|
||||
|
||||
m_iUpperX -= amount;
|
||||
m_iUpperY -= amount;
|
||||
m_iUpperZ -= amount;
|
||||
m_iUpperX -= iAmountX;
|
||||
m_iUpperY -= iAmountY;
|
||||
m_iUpperZ -= iAmountZ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The erosion can be specified seperatly for each direction. Negative erosions
|
||||
/// are possible but you should prefer the dilate() function for clarity.
|
||||
/// \param v3dAmount The amount to erode by (one components for each direction).
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::erode(const Vector3DInt32& v3dAmount)
|
||||
{
|
||||
erode(v3dAmount.getX(), v3dAmount.getY(), v3dAmount.getZ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Region::isValid(void) const
|
||||
{
|
||||
return (m_iUpperX >= m_iLowerX) && (m_iUpperY >= m_iLowerY) && (m_iUpperZ >= m_iLowerZ);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iAmountX The amount to move the Region by in 'x'.
|
||||
/// \param iAmountY The amount to move the Region by in 'y'.
|
||||
/// \param iAmountZ The amount to move the Region by in 'z'.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::shift(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ)
|
||||
{
|
||||
shiftLowerCorner(iAmountX, iAmountY, iAmountZ);
|
||||
shiftUpperCorner(iAmountX, iAmountY, iAmountZ);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dAmount The amount to move the Region by.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::shift(const Vector3DInt32& v3dAmount)
|
||||
{
|
||||
shiftLowerCorner(v3dAmount);
|
||||
shiftUpperCorner(v3dAmount);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iAmountX The amount to move the lower corner by in 'x'.
|
||||
/// \param iAmountY The amount to move the lower corner by in 'y'.
|
||||
/// \param iAmountZ The amount to move the lower corner by in 'z'.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::shiftLowerCorner(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ)
|
||||
{
|
||||
m_iLowerX += iAmountX;
|
||||
m_iLowerY += iAmountY;
|
||||
m_iLowerZ += iAmountZ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dAmount The amount to move the lower corner by.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::shiftLowerCorner(const Vector3DInt32& v3dAmount)
|
||||
{
|
||||
shiftLowerCorner(v3dAmount.getX(), v3dAmount.getY(), v3dAmount.getZ());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param iAmountX The amount to move the upper corner by in 'x'.
|
||||
/// \param iAmountY The amount to move the upper corner by in 'y'.
|
||||
/// \param iAmountZ The amount to move the upper corner by in 'z'.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::shiftUpperCorner(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ)
|
||||
{
|
||||
m_iUpperX += iAmountX;
|
||||
m_iUpperY += iAmountY;
|
||||
m_iUpperZ += iAmountZ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \param v3dAmount The amount to move the upper corner by.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Region::shiftUpperCorner(const Vector3DInt32& v3dAmount)
|
||||
{
|
||||
shiftUpperCorner(v3dAmount.getX(), v3dAmount.getY(), v3dAmount.getZ());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user