run format
This commit is contained in:
parent
e7a97a8395
commit
9cb5852ea3
|
|
@ -57,7 +57,8 @@ public:
|
|||
* including skewed perspective and orthographic projections.
|
||||
*
|
||||
* @param viewMatrix The view's view matrix i.e., the inverse of its pose
|
||||
* @param projectionMatrix The view's Vulkan style reversed Z projection matrix
|
||||
* @param projectionMatrix The view's Vulkan style reversed Z projection
|
||||
* matrix
|
||||
* @param viewportSize The size of the viewport, in pixels.
|
||||
* @param ellipsoid The ellipsoid that will be used to compute the
|
||||
* {@link ViewState#getPositionCartographic cartographic position}
|
||||
|
|
|
|||
|
|
@ -55,15 +55,16 @@ glm::dvec3 positionFromView(const glm::dmat4& viewMatrix) {
|
|||
}
|
||||
|
||||
glm::dvec3 directionFromView(const glm::dmat4& viewMatrix) {
|
||||
return glm::dvec3(viewMatrix[0][2], viewMatrix[1][2], viewMatrix[2][2]) * -1.0;
|
||||
}
|
||||
return glm::dvec3(viewMatrix[0][2], viewMatrix[1][2], viewMatrix[2][2]) *
|
||||
-1.0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/* static */ ViewState ViewState::create(
|
||||
const glm::dmat4& viewMatrix,
|
||||
const glm::dmat4& projectionMatrix,
|
||||
const glm::dvec2& viewportSize,
|
||||
const CesiumGeospatial::Ellipsoid& ellipsoid) {
|
||||
const glm::dmat4& viewMatrix,
|
||||
const glm::dmat4& projectionMatrix,
|
||||
const glm::dvec2& viewportSize,
|
||||
const CesiumGeospatial::Ellipsoid& ellipsoid) {
|
||||
return ViewState(
|
||||
viewMatrix,
|
||||
projectionMatrix,
|
||||
|
|
@ -254,15 +255,16 @@ double ViewState::computeScreenSpaceError(
|
|||
distance = glm::max(distance, 1e-7);
|
||||
if (this->_projectionMatrix) {
|
||||
// This is a simplified version of the projection transform and homogeneous
|
||||
// division. We transform the coordinate (0.0, geometric error, -distance, 1)
|
||||
// and use the resulting NDC to find the screen space error. That's not
|
||||
// division. We transform the coordinate (0.0, geometric error, -distance,
|
||||
// 1) and use the resulting NDC to find the screen space error. That's not
|
||||
// quite right: the distance is actually the slant distance, and the real
|
||||
// transform contains a term for an offset due to a skewed projection which
|
||||
// is ignored here.
|
||||
const glm::dmat4& projMat = *this->_projectionMatrix;
|
||||
glm::dvec4 centerNdc = projMat * glm::dvec4(0.0, 0.0, -distance, 1.0);
|
||||
centerNdc /= centerNdc.w;
|
||||
glm::dvec4 errorOffsetNdc = projMat * glm::dvec4(0.0, geometricError, -distance, 1.0);
|
||||
glm::dvec4 errorOffsetNdc =
|
||||
projMat * glm::dvec4(0.0, geometricError, -distance, 1.0);
|
||||
errorOffsetNdc /= errorOffsetNdc.w;
|
||||
|
||||
double ndcError = (errorOffsetNdc - centerNdc).y;
|
||||
|
|
@ -271,7 +273,8 @@ double ViewState::computeScreenSpaceError(
|
|||
return -ndcError * this->_viewportSize.y / 2.0;
|
||||
} else {
|
||||
const double sseDenominator = this->_sseDenominator;
|
||||
return (geometricError * this->_viewportSize.y) / (distance * sseDenominator);
|
||||
return (geometricError * this->_viewportSize.y) /
|
||||
(distance * sseDenominator);
|
||||
}
|
||||
}
|
||||
} // namespace Cesium3DTilesSelection
|
||||
|
|
|
|||
|
|
@ -122,21 +122,20 @@ struct CESIUMGEOMETRY_API Transforms final {
|
|||
*/
|
||||
|
||||
/**
|
||||
* @brief Compute a Vulkan-style perspective projection matrix with reversed Z.
|
||||
* @brief Compute a Vulkan-style perspective projection matrix with reversed
|
||||
* Z.
|
||||
*
|
||||
* @param fovx horizontal field of view in radians
|
||||
* @param fovy horizontal field of view in radians
|
||||
* @param zNear distance to near plane
|
||||
* @param zFar distance to far plane
|
||||
*/
|
||||
static glm::dmat4 createPerspectiveMatrix(
|
||||
double fovx,
|
||||
double fovy,
|
||||
double zNear,
|
||||
double zFar);
|
||||
static glm::dmat4
|
||||
createPerspectiveMatrix(double fovx, double fovy, double zNear, double zFar);
|
||||
|
||||
/**
|
||||
* @brief Compute a Vulkan-style perspective projection matrix with reversed Z.
|
||||
* @brief Compute a Vulkan-style perspective projection matrix with reversed
|
||||
* Z.
|
||||
*
|
||||
* @param left left distance of near plane edge from center
|
||||
* @param right right distance of near plane edge
|
||||
|
|
@ -154,7 +153,8 @@ struct CESIUMGEOMETRY_API Transforms final {
|
|||
double zFar);
|
||||
|
||||
/**
|
||||
* @brief Compute a Vulkan-style orthographic projection matrix with reversed Z.
|
||||
* @brief Compute a Vulkan-style orthographic projection matrix with reversed
|
||||
* Z.
|
||||
*
|
||||
* X maps from -1 to 1, Y maps from 1 to -1, Z maps from 1 to 0.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -75,14 +75,14 @@ CullingVolume createCullingVolume(
|
|||
|
||||
const CesiumGeometry::Plane topPlane(normal, -glm::dot(normal, position));
|
||||
|
||||
return {leftPlane, rightPlane, topPlane , bottomPlane};
|
||||
return {leftPlane, rightPlane, topPlane, bottomPlane};
|
||||
}
|
||||
|
||||
CullingVolume createCullingVolume(const glm::dmat4& clipMatrix) {
|
||||
// Gribb / Hartmann method.
|
||||
// See https://www.gamedevs.org/uploads/fast-extraction-viewing-frustum-planes-from-world-view-projection-matrix.pdf
|
||||
auto normalizePlane = [](double a, double b, double c, double d)
|
||||
{
|
||||
// See
|
||||
// https://www.gamedevs.org/uploads/fast-extraction-viewing-frustum-planes-from-world-view-projection-matrix.pdf
|
||||
auto normalizePlane = [](double a, double b, double c, double d) {
|
||||
double len = sqrt(a * a + b * b + c * c);
|
||||
return Plane(glm::dvec3(a / len, b / len, c / len), d / len);
|
||||
};
|
||||
|
|
@ -117,8 +117,7 @@ CullingVolume createCullingVolume(
|
|||
double r,
|
||||
double b,
|
||||
double t,
|
||||
double n) noexcept
|
||||
{
|
||||
double n) noexcept {
|
||||
glm::dmat4 projMatrix = Transforms::createPerspectiveMatrix(
|
||||
l,
|
||||
r,
|
||||
|
|
|
|||
|
|
@ -185,17 +185,16 @@ glm::dmat4 Transforms::createViewMatrix(
|
|||
}
|
||||
|
||||
glm::dmat4 Transforms::createPerspectiveMatrix(
|
||||
double fovx,
|
||||
double fovy,
|
||||
double zNear,
|
||||
double zFar) {
|
||||
double fovx,
|
||||
double fovy,
|
||||
double zNear,
|
||||
double zFar) {
|
||||
double m22;
|
||||
double m32;
|
||||
if (zFar == std::numeric_limits<double>::infinity()) {
|
||||
m22 = 0.0;
|
||||
m32 = zNear;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
m22 = zNear / (zFar - zNear);
|
||||
m32 = zNear * zFar / (zFar - zNear);
|
||||
}
|
||||
|
|
@ -207,45 +206,45 @@ glm::dmat4 Transforms::createPerspectiveMatrix(
|
|||
}
|
||||
|
||||
glm::dmat4 Transforms::createPerspectiveMatrix(
|
||||
double left,
|
||||
double right,
|
||||
double bottom,
|
||||
double top,
|
||||
double zNear,
|
||||
double zFar)
|
||||
{
|
||||
double left,
|
||||
double right,
|
||||
double bottom,
|
||||
double top,
|
||||
double zNear,
|
||||
double zFar) {
|
||||
double m22;
|
||||
double m32;
|
||||
if (zFar == std::numeric_limits<double>::infinity()) {
|
||||
m22 = 0.0;
|
||||
m32 = zNear;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
m22 = zNear / (zFar - zNear);
|
||||
m32 = zNear * zFar / (zFar - zNear);
|
||||
}
|
||||
return glm::dmat4(
|
||||
glm::dvec4(2.0 * zNear / (right - left), 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 2.0 * zNear / (bottom - top), 0.0, 0.0),
|
||||
glm::dvec4((right + left) / (right - left), (bottom + top) / (bottom - top), m22, -1.0),
|
||||
glm::dvec4(
|
||||
(right + left) / (right - left),
|
||||
(bottom + top) / (bottom - top),
|
||||
m22,
|
||||
-1.0),
|
||||
glm::dvec4(0.0, 0.0, m32, 0.0));
|
||||
}
|
||||
|
||||
glm::dmat4 Transforms::createOrthographicMatrix(
|
||||
double left,
|
||||
double right,
|
||||
double bottom,
|
||||
double top,
|
||||
double zNear,
|
||||
double zFar)
|
||||
{
|
||||
double left,
|
||||
double right,
|
||||
double bottom,
|
||||
double top,
|
||||
double zNear,
|
||||
double zFar) {
|
||||
double m22;
|
||||
double m32;
|
||||
if (zFar == std::numeric_limits<double>::infinity()) {
|
||||
m22 = 0.0;
|
||||
m32 = 1.0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
m22 = 1.0 / (zFar - zNear);
|
||||
m32 = zFar / (zFar - zNear);
|
||||
}
|
||||
|
|
@ -253,7 +252,11 @@ glm::dmat4 Transforms::createOrthographicMatrix(
|
|||
glm::dvec4(2.0 * zNear / (right - left), 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 2.0 * zNear / (bottom - top), 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, m22, 0.0),
|
||||
glm::dvec4(-(right + left) / (right - left), -(bottom + top) / (bottom - top), m32, 1.0));
|
||||
glm::dvec4(
|
||||
-(right + left) / (right - left),
|
||||
-(bottom + top) / (bottom - top),
|
||||
m32,
|
||||
1.0));
|
||||
}
|
||||
|
||||
} // namespace CesiumGeometry
|
||||
|
|
|
|||
|
|
@ -15,29 +15,27 @@ using namespace CesiumGeometry;
|
|||
using namespace CesiumUtility;
|
||||
|
||||
namespace {
|
||||
constexpr bool equalsEpsilon(
|
||||
const Plane& left,
|
||||
const Plane& right,
|
||||
double relativeEpsilon) {
|
||||
constexpr bool
|
||||
equalsEpsilon(const Plane& left, const Plane& right, double relativeEpsilon) {
|
||||
return Math::equalsEpsilon(
|
||||
left.getNormal(),
|
||||
right.getNormal(),
|
||||
relativeEpsilon)
|
||||
&& Math::equalsEpsilon(
|
||||
left.getDistance(),
|
||||
right.getDistance(),
|
||||
relativeEpsilon);
|
||||
}
|
||||
left.getNormal(),
|
||||
right.getNormal(),
|
||||
relativeEpsilon) &&
|
||||
Math::equalsEpsilon(
|
||||
left.getDistance(),
|
||||
right.getDistance(),
|
||||
relativeEpsilon);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
constexpr bool equalsEpsilon(
|
||||
const CullingVolume& left,
|
||||
const CullingVolume& right,
|
||||
double relativeEpsilon) {
|
||||
return equalsEpsilon(left.leftPlane, right.leftPlane, relativeEpsilon)
|
||||
&& equalsEpsilon(left.rightPlane, right.rightPlane, relativeEpsilon)
|
||||
&& equalsEpsilon(left.topPlane, right.topPlane, relativeEpsilon)
|
||||
&& equalsEpsilon(left.bottomPlane, right.bottomPlane, relativeEpsilon);
|
||||
return equalsEpsilon(left.leftPlane, right.leftPlane, relativeEpsilon) &&
|
||||
equalsEpsilon(left.rightPlane, right.rightPlane, relativeEpsilon) &&
|
||||
equalsEpsilon(left.topPlane, right.topPlane, relativeEpsilon) &&
|
||||
equalsEpsilon(left.bottomPlane, right.bottomPlane, relativeEpsilon);
|
||||
}
|
||||
|
||||
TEST_CASE("CullingVolume::createCullingVolume") {
|
||||
|
|
@ -71,15 +69,13 @@ TEST_CASE("CullingVolume construction") {
|
|||
up,
|
||||
Math::PiOverTwo,
|
||||
Math::PiOverTwo);
|
||||
CullingVolume rad = createCullingVolume(Transforms::createPerspectiveMatrix(
|
||||
Math::PiOverTwo,
|
||||
Math::PiOverTwo,
|
||||
10,
|
||||
200000)
|
||||
* Transforms::createViewMatrix(
|
||||
position,
|
||||
direction,
|
||||
up));
|
||||
CullingVolume rad = createCullingVolume(
|
||||
Transforms::createPerspectiveMatrix(
|
||||
Math::PiOverTwo,
|
||||
Math::PiOverTwo,
|
||||
10,
|
||||
200000) *
|
||||
Transforms::createViewMatrix(position, direction, up));
|
||||
CHECK(equalsEpsilon(traditional, rad, 1e-10));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,17 +107,15 @@ TEST_CASE("Gets up axis transform") {
|
|||
namespace {
|
||||
bool pointInClipVolume(const glm::dvec4& point) {
|
||||
const double w = point.w;
|
||||
return -w < point.x
|
||||
&& point.x < w
|
||||
&& -w < point.y
|
||||
&& point.y < w
|
||||
&& 0.0 < point.z
|
||||
&& point.z < w;
|
||||
}
|
||||
return -w < point.x && point.x < w && -w < point.y && point.y < w &&
|
||||
0.0 < point.z && point.z < w;
|
||||
}
|
||||
} // namespace
|
||||
TEST_CASE("Test perspective projection matrices") {
|
||||
const double horizontalFieldOfView = CesiumUtility::Math::degreesToRadians(60.0);
|
||||
const double verticalFieldOfView = CesiumUtility::Math::degreesToRadians(45.0);
|
||||
const double horizontalFieldOfView =
|
||||
CesiumUtility::Math::degreesToRadians(60.0);
|
||||
const double verticalFieldOfView =
|
||||
CesiumUtility::Math::degreesToRadians(45.0);
|
||||
const double zNear = 1.0;
|
||||
const double zFar = 20000.0;
|
||||
const glm::dmat4 projMat = Transforms::createPerspectiveMatrix(
|
||||
|
|
@ -128,34 +126,35 @@ TEST_CASE("Test perspective projection matrices") {
|
|||
std::vector<glm::dvec4> testPoints;
|
||||
testPoints.reserve(1000);
|
||||
for (int i = 0; i < 11; ++i) {
|
||||
double hRad = -horizontalFieldOfView / 2.0 + i * horizontalFieldOfView / 10.0;
|
||||
double hRad =
|
||||
-horizontalFieldOfView / 2.0 + i * horizontalFieldOfView / 10.0;
|
||||
hRad = CesiumUtility::Math::clamp(
|
||||
hRad,
|
||||
-horizontalFieldOfView + 0.1,
|
||||
horizontalFieldOfView - 0.1);
|
||||
double sinH = std::sin(hRad);
|
||||
for (int j = 0; j < 10; ++j) {
|
||||
double vRad = -verticalFieldOfView / 2.0 + j * verticalFieldOfView / 10.0;
|
||||
vRad = CesiumUtility::Math::clamp(
|
||||
vRad,
|
||||
-verticalFieldOfView + 0.1,
|
||||
verticalFieldOfView - 0.1);
|
||||
double sinV = std::sin(vRad);
|
||||
for (int k = 0; k < 10; ++k) {
|
||||
double z = zNear + k * (zFar - zNear) / 10.0;
|
||||
z = CesiumUtility::Math::clamp(z, zNear + .1, zFar - .1);
|
||||
testPoints.emplace_back(sinH * z, sinV * z, -z, 1.0);
|
||||
}
|
||||
for (int j = 0; j < 10; ++j) {
|
||||
double vRad = -verticalFieldOfView / 2.0 + j * verticalFieldOfView / 10.0;
|
||||
vRad = CesiumUtility::Math::clamp(
|
||||
vRad,
|
||||
-verticalFieldOfView + 0.1,
|
||||
verticalFieldOfView - 0.1);
|
||||
double sinV = std::sin(vRad);
|
||||
for (int k = 0; k < 10; ++k) {
|
||||
double z = zNear + k * (zFar - zNear) / 10.0;
|
||||
z = CesiumUtility::Math::clamp(z, zNear + .1, zFar - .1);
|
||||
testPoints.emplace_back(sinH * z, sinV * z, -z, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
SUBCASE("Check that points lie in clipping volume") {
|
||||
CHECK(std::all_of(
|
||||
testPoints.begin(),
|
||||
testPoints.end(),
|
||||
[&projMat](const glm::dvec4& p) {
|
||||
glm::dvec4 projected = projMat * p;
|
||||
return pointInClipVolume(projected);
|
||||
}));
|
||||
testPoints.begin(),
|
||||
testPoints.end(),
|
||||
[&projMat](const glm::dvec4& p) {
|
||||
glm::dvec4 projected = projMat * p;
|
||||
return pointInClipVolume(projected);
|
||||
}));
|
||||
}
|
||||
double hDim = std::tan(horizontalFieldOfView / 2.0) * zNear;
|
||||
double vDim = std::tan(verticalFieldOfView / 2.0) * zNear;
|
||||
|
|
@ -171,22 +170,26 @@ TEST_CASE("Test perspective projection matrices") {
|
|||
}
|
||||
|
||||
SUBCASE("Check skewed projection") {
|
||||
glm::dmat4 skewed = Transforms::createPerspectiveMatrix(
|
||||
0.0,
|
||||
hDim,
|
||||
0.0,
|
||||
vDim,
|
||||
zNear,
|
||||
zFar);
|
||||
glm::dmat4 skewed =
|
||||
Transforms::createPerspectiveMatrix(0.0, hDim, 0.0, vDim, zNear, zFar);
|
||||
for (auto& point : testPoints) {
|
||||
glm::dvec4 skewProjected = skewed * point;
|
||||
if (pointInClipVolume(skewProjected)) {
|
||||
glm::dvec4 symProjected = corners * point;
|
||||
skewProjected /= skewProjected.w;
|
||||
symProjected /= symProjected.w;
|
||||
CHECK(CesiumUtility::Math::equalsEpsilon(skewProjected.x / 2.0 + .5, symProjected.x, 1e-14));
|
||||
CHECK(CesiumUtility::Math::equalsEpsilon(skewProjected.y / 2.0 - .5, symProjected.y, 1e-14));
|
||||
CHECK(CesiumUtility::Math::equalsEpsilon(skewProjected.z, symProjected.z, 1e-14));
|
||||
CHECK(CesiumUtility::Math::equalsEpsilon(
|
||||
skewProjected.x / 2.0 + .5,
|
||||
symProjected.x,
|
||||
1e-14));
|
||||
CHECK(CesiumUtility::Math::equalsEpsilon(
|
||||
skewProjected.y / 2.0 - .5,
|
||||
symProjected.y,
|
||||
1e-14));
|
||||
CHECK(CesiumUtility::Math::equalsEpsilon(
|
||||
skewProjected.z,
|
||||
symProjected.z,
|
||||
1e-14));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -202,11 +205,11 @@ TEST_CASE("Test perspective projection matrices") {
|
|||
zNear,
|
||||
zFar);
|
||||
CHECK(std::all_of(
|
||||
testPoints.begin(),
|
||||
testPoints.end(),
|
||||
[&ortho](const glm::dvec4& p) {
|
||||
glm::dvec4 projected = ortho * p;
|
||||
return pointInClipVolume(projected);
|
||||
}));
|
||||
testPoints.begin(),
|
||||
testPoints.end(),
|
||||
[&ortho](const glm::dvec4& p) {
|
||||
glm::dvec4 projected = ortho * p;
|
||||
return pointInClipVolume(projected);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ public:
|
|||
glm::vec<L, bool, Q>(true);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Determines if two values are equal using an absolute or relative
|
||||
* tolerance test.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue