BoundingRegion docs.

This commit is contained in:
Kevin Ring 2020-08-18 12:13:18 +10:00
parent edcd37ae5b
commit c216d57289
6 changed files with 112 additions and 89 deletions

View File

@ -25,7 +25,7 @@ namespace Cesium3DTiles {
json::const_iterator regionIt = bvIt->find("region");
if (regionIt != bvIt->end() && regionIt->is_array() && regionIt->size() >= 6) {
const json& a = *regionIt;
return BoundingRegion(a[0], a[1], a[2], a[3], a[4], a[5]);
return BoundingRegion(Rectangle(a[0], a[1], a[2], a[3]), a[4], a[5]);
}
json::const_iterator sphereIt = bvIt->find("sphere");

View File

@ -17,19 +17,6 @@ namespace CesiumGeometry {
*/
class CESIUMGEOMETRY_API OrientedBoundingBox {
public:
static OrientedBoundingBox fromPlaneExtents(
const glm::dvec3& planeOrigin,
const glm::dvec3& planeXAxis,
const glm::dvec3& planeYAxis,
const glm::dvec3& planeZAxis,
double minimumX,
double maximumX,
double minimumY,
double maximumY,
double minimumZ,
double maximumZ
);
/**
* @brief Constructs a new instance.
*

View File

@ -6,44 +6,6 @@
#include "CesiumUtility/Math.h"
namespace CesiumGeometry {
/*static*/ OrientedBoundingBox OrientedBoundingBox::fromPlaneExtents(
const glm::dvec3& planeOrigin,
const glm::dvec3& planeXAxis,
const glm::dvec3& planeYAxis,
const glm::dvec3& planeZAxis,
double minimumX,
double maximumX,
double minimumY,
double maximumY,
double minimumZ,
double maximumZ
) {
glm::dmat3 halfAxes(planeXAxis, planeYAxis, planeZAxis);
glm::dvec3 centerOffset(
(minimumX + maximumX) / 2.0,
(minimumY + maximumY) / 2.0,
(minimumZ + maximumZ) / 2.0
);
glm::dvec3 scale(
(maximumX - minimumX) / 2.0,
(maximumY - minimumY) / 2.0,
(maximumZ - minimumZ) / 2.0
);
glm::dmat3 scaledHalfAxes(
halfAxes[0] * scale.x,
halfAxes[1] * scale.y,
halfAxes[2] * scale.z
);
return OrientedBoundingBox(
planeOrigin + (halfAxes * centerOffset),
scaledHalfAxes
);
}
CullingResult OrientedBoundingBox::intersectPlane(const Plane& plane) const {
glm::dvec3 normal = plane.getNormal();

View File

@ -13,18 +13,19 @@ namespace CesiumGeometry {
namespace CesiumGeospatial {
class Cartographic;
/**
* @brief A bounding volume specified as a longitude/latitude bounding box and a minimum and maximum height.
*/
class CESIUMGEOSPATIAL_API BoundingRegion {
public:
BoundingRegion(
double west,
double south,
double east,
double north,
double minimumHeight,
double maximumHeight,
const Ellipsoid& ellipsoid = Ellipsoid::WGS84
);
/**
* @brief Constructs a new bounding region.
*
* @param rectangle The bounding rectangle of the region.
* @param minimumHeight The minimum height in meters.
* @param maximumHeight The maximum height in meters.
* @param ellipsoid The ellipsoid on which this region is defined.
*/
BoundingRegion(
const Rectangle& rectangle,
double minimumHeight,
@ -32,18 +33,64 @@ namespace CesiumGeospatial {
const Ellipsoid& ellipsoid = Ellipsoid::WGS84
);
/**
* @brief Gets the bounding rectangle of the region.
*/
const Rectangle& getRectangle() const { return this->_rectangle; }
double getWest() const { return this->_rectangle.getWest(); }
double getSouth() const { return this->_rectangle.getSouth(); }
double getEast() const { return this->_rectangle.getEast(); }
double getNorth() const { return this->_rectangle.getNorth(); }
/**
* @brief Gets the minimum height of the region.
*/
double getMinimumHeight() const { return this->_minimumHeight; }
/**
* @brief Gets the maximum height of the region.
*/
double getMaximumHeight() const { return this->_maximumHeight; }
/**
* @brief Gets an oriented bounding box containing this region.
*/
const CesiumGeometry::OrientedBoundingBox& getBoundingBox() const { return this->_boundingBox; }
/**
* @brief Determines on which side of a plane the bounding region is located.
*
* @param plane The plane to test against.
* @return
* * {@link CullingResult::Inside} if the entire region is on the side of the plane the normal is pointing.
* * {@link CullingResult::Outside} if the entire region is on the opposite side.
* * {@link CullingResult::Intersecting} if the region intersects the plane.
*/
CesiumGeometry::CullingResult intersectPlane(const CesiumGeometry::Plane& plane) const;
/**
* @brief Computes the distance-squared from a position in ellipsoid-centered Cartesian coordinates
* to the closest point in this bounding region.
*
* @param position The position.
* @param ellipsoid The ellipsoid on which this region is defined.
* @return The distance-squared from the position to the closest point in the bounding region.
*/
double computeDistanceSquaredToPosition(const glm::dvec3& position, const Ellipsoid& ellipsoid = Ellipsoid::WGS84) const;
/**
* @brief Computes the distance-squared from a longitude-latitude-height position to the closest point in this bounding region.
*
* @param position The position.
* @param ellipsoid The ellipsoid on which this region is defined.
* @return The distance-squared from the position to the closest point in the bounding region.
*/
double computeDistanceSquaredToPosition(const Cartographic& position, const Ellipsoid& ellipsoid = Ellipsoid::WGS84) const;
/**
* @brief Computes the distance-squared from a position to the closest point in this bounding region, when the longitude-latitude-height
* and ellipsoid-centered Cartesian coordinates of the position are both already known.
*
* @param cartographicPosition The position as a longitude-latitude-height.
* @param cartesianPosition The position as ellipsoid-centered Cartesian coordinates.
* @return The distance-squared from the position to the closest point in the bounding region.
*/
double computeDistanceSquaredToPosition(const Cartographic& cartographicPosition, const glm::dvec3& cartesianPosition) const;
private:

View File

@ -10,19 +10,6 @@ using namespace CesiumUtility;
using namespace CesiumGeometry;
namespace CesiumGeospatial {
BoundingRegion::BoundingRegion(
double west,
double south,
double east,
double north,
double minimumHeight,
double maximumHeight,
const Ellipsoid& ellipsoid
) :
BoundingRegion(Rectangle(west, south, east, north), minimumHeight, maximumHeight, ellipsoid)
{
}
BoundingRegion::BoundingRegion(
const Rectangle& rectangle,
double minimumHeight,
@ -185,6 +172,44 @@ namespace CesiumGeospatial {
return result;
}
static OrientedBoundingBox fromPlaneExtents(
const glm::dvec3& planeOrigin,
const glm::dvec3& planeXAxis,
const glm::dvec3& planeYAxis,
const glm::dvec3& planeZAxis,
double minimumX,
double maximumX,
double minimumY,
double maximumY,
double minimumZ,
double maximumZ
) {
glm::dmat3 halfAxes(planeXAxis, planeYAxis, planeZAxis);
glm::dvec3 centerOffset(
(minimumX + maximumX) / 2.0,
(minimumY + maximumY) / 2.0,
(minimumZ + maximumZ) / 2.0
);
glm::dvec3 scale(
(maximumX - minimumX) / 2.0,
(maximumY - minimumY) / 2.0,
(maximumZ - minimumZ) / 2.0
);
glm::dmat3 scaledHalfAxes(
halfAxes[0] * scale.x,
halfAxes[1] * scale.y,
halfAxes[2] * scale.z
);
return OrientedBoundingBox(
planeOrigin + (halfAxes * centerOffset),
scaledHalfAxes
);
}
/*static*/ OrientedBoundingBox BoundingRegion::_computeBoundingBox(
const Rectangle& rectangle,
double minimumHeight,
@ -257,7 +282,7 @@ namespace CesiumGeospatial {
);
maxZ = maximumHeight; // Since the tangent plane touches the surface at height = 0, this is okay
return OrientedBoundingBox::fromPlaneExtents(
return fromPlaneExtents(
tangentPlane.getOrigin(),
tangentPlane.getXAxis(),
tangentPlane.getYAxis(),
@ -315,7 +340,7 @@ namespace CesiumGeospatial {
maxZ = 0.0; // plane origin starts at maxZ already
// min and max are local to the plane axes
return OrientedBoundingBox::fromPlaneExtents(
return fromPlaneExtents(
planeOrigin,
planeXAxis,
planeYAxis,

View File

@ -33,29 +33,31 @@ TEST_CASE("BoundingRegion") {
10.0
);
const Rectangle& rectangle = region.getRectangle();
auto testCase = GENERATE_COPY(
// Inside bounding region
TestCase { region.getWest() + Math::EPSILON6, region.getSouth(), region.getMinimumHeight(), 0.0 },
TestCase { rectangle.getWest() + Math::EPSILON6, rectangle.getSouth(), region.getMinimumHeight(), 0.0 },
// Outside bounding region
TestCase { region.getWest(), region.getSouth(), region.getMaximumHeight() + 1.0, 1.0 },
TestCase { rectangle.getWest(), rectangle.getSouth(), region.getMaximumHeight() + 1.0, 1.0 },
// Inside rectangle, above height
TestCase { 0.0, 0.0, 20.0, 10.0 },
// Inside rectangle, below height
TestCase { 0.0, 0.0, 5.0, 0.0 },
// From southwest
updateDistance(TestCase {
region.getEast() + offset,
region.getNorth() + offset,
rectangle.getEast() + offset,
rectangle.getNorth() + offset,
0.0,
0.0
}, region.getEast(), region.getNorth(), 0.0),
}, rectangle.getEast(), rectangle.getNorth(), 0.0),
// From northeast
updateDistance(TestCase {
region.getWest() - offset,
region.getSouth() - offset,
rectangle.getWest() - offset,
rectangle.getSouth() - offset,
0.0,
0.0
}, region.getWest(), region.getSouth(), 0.0)
}, rectangle.getWest(), rectangle.getSouth(), 0.0)
);
glm::dvec3 position = Ellipsoid::WGS84.cartographicToCartesian(