mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-04 09:59:44 -05:00
Prevent floating point over- and underflows; specifically when interpolating the camera position (closes #575)
This commit is contained in:
@@ -173,7 +173,7 @@ private:
|
||||
// Cached transform data
|
||||
glm::dvec3 _worldPositionCached;
|
||||
glm::dmat3 _worldRotationCached;
|
||||
double _worldScaleCached;
|
||||
double _worldScaleCached = 1.0;
|
||||
|
||||
glm::dmat4 _modelTransformCached;
|
||||
glm::dmat4 _inverseModelTransformCached;
|
||||
|
||||
@@ -292,7 +292,13 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData,
|
||||
}
|
||||
|
||||
// Sun Position in Object Space
|
||||
program.setUniform(_uniformCache2.sunDirectionObj, glm::normalize(glm::dvec3(sunPosObj)));
|
||||
const double l = glm::length(glm::dvec3(sunPosObj));
|
||||
program.setUniform(
|
||||
_uniformCache2.sunDirectionObj,
|
||||
l > 0.0 ?
|
||||
glm::normalize(glm::dvec3(sunPosObj)) :
|
||||
glm::dvec3(0.0)
|
||||
);
|
||||
|
||||
// Shadow calculations..
|
||||
if (!_shadowConfArray.empty()) {
|
||||
|
||||
@@ -85,13 +85,21 @@ bool HorizonCuller::isCullable(const glm::dvec3& cameraPosition,
|
||||
double objectBoundingSphereRadius,
|
||||
double minimumGlobeRadius)
|
||||
{
|
||||
double distanceToHorizon =
|
||||
sqrt(pow(length(cameraPosition - globePosition), 2) -
|
||||
pow(minimumGlobeRadius, 2));
|
||||
const double objectP = pow(length(objectPosition - globePosition), 2);
|
||||
const double horizonP = pow(minimumGlobeRadius - objectBoundingSphereRadius, 2);
|
||||
if (objectP < horizonP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double minimumAllowedDistanceToObjectFromHorizon = sqrt(
|
||||
pow(length(objectPosition - globePosition), 2) -
|
||||
pow(minimumGlobeRadius - objectBoundingSphereRadius, 2));
|
||||
const double cameraP = pow(length(cameraPosition - globePosition), 2);
|
||||
const double minR = pow(minimumGlobeRadius, 2);
|
||||
if (cameraP < minR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
double minimumAllowedDistanceToObjectFromHorizon = sqrt(objectP - horizonP);
|
||||
double distanceToHorizon = sqrt(cameraP - minR);
|
||||
|
||||
// Minimum allowed for the object to be occluded
|
||||
double minimumAllowedDistanceToObjectSquared =
|
||||
|
||||
@@ -271,8 +271,11 @@ void ChunkRenderer::setCommonUniforms(ghoul::opengl::ProgramObject& programObjec
|
||||
chunk.owner().generalProperties().atmosphereEnabled ||
|
||||
chunk.owner().generalProperties().performShading)
|
||||
{
|
||||
glm::vec3 directionToSunWorldSpace =
|
||||
glm::normalize(-data.modelTransform.translation);
|
||||
glm::dvec3 directionToSunWorldSpace =
|
||||
length(data.modelTransform.translation) > 0.0 ?
|
||||
glm::normalize(-data.modelTransform.translation) :
|
||||
glm::dvec3(0.0);
|
||||
|
||||
glm::vec3 directionToSunCameraSpace =
|
||||
glm::vec3(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
|
||||
programObject.setUniform(
|
||||
|
||||
@@ -641,15 +641,22 @@ void LuaConsole::update() {
|
||||
_fullHeight = (bbox.boundingBox.y + EntryFontSize + SeparatorSpace);
|
||||
_targetHeight = _isVisible ? _fullHeight : 0;
|
||||
|
||||
const float frametime = static_cast<float>(OsEng.windowWrapper().deltaTime());
|
||||
// The first frame is going to be finished in approx 10 us, which causes a floating
|
||||
// point overflow when computing dHeight
|
||||
const double frametime = std::max(
|
||||
OsEng.windowWrapper().deltaTime(),
|
||||
1e-4
|
||||
);
|
||||
|
||||
// Update the current height.
|
||||
// The current height is the offset that is used to slide
|
||||
// the console in from the top.
|
||||
const glm::ivec2 res = OsEng.windowWrapper().currentWindowResolution();
|
||||
const glm::vec2 dpiScaling = OsEng.windowWrapper().dpiScaling();
|
||||
_currentHeight += (_targetHeight - _currentHeight) *
|
||||
std::pow(0.98f, 1.f / (ConsoleOpenSpeed / dpiScaling.y * frametime));
|
||||
const double dHeight = (_targetHeight - _currentHeight) *
|
||||
std::pow(0.98, 1.0 / (ConsoleOpenSpeed / dpiScaling.y * frametime));
|
||||
|
||||
_currentHeight += static_cast<float>(dHeight);
|
||||
|
||||
_currentHeight = std::max(0.0f, _currentHeight);
|
||||
_currentHeight = std::min(static_cast<float>(res.y), _currentHeight);
|
||||
|
||||
@@ -377,7 +377,11 @@ glm::dquat OrbitalNavigator::interpolateLocalRotation(double deltaTime,
|
||||
localCameraRotation,
|
||||
glm::dquat(glm::dvec3(0.0)),
|
||||
glm::min(t * _rotateToFocusNodeInterpolator.deltaTimeScaled(), 1.0));
|
||||
if (angle(result) < 0.01) {
|
||||
|
||||
// Retrieving the angle of a quaternion uses acos on the w component, which can
|
||||
// have numerical instability for values close to 1.0
|
||||
constexpr double Epsilon = 1.0e-13;
|
||||
if (abs((abs(result.w) - 1.0)) < Epsilon || angle(result) < 0.01) {
|
||||
_rotateToFocusNodeInterpolator.end();
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -107,6 +107,7 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary)
|
||||
, _enabled(EnabledInfo, true)
|
||||
, _opacity(OpacityInfo, 1.f, 0.f, 1.f)
|
||||
, _renderBin(RenderBin::Opaque)
|
||||
, _boundingSphere(0.f)
|
||||
, _startTime("")
|
||||
, _endTime("")
|
||||
, _hasTimeInterval(false)
|
||||
|
||||
@@ -585,11 +585,12 @@ bool SceneGraphNode::hasGuiHintHidden() const {
|
||||
glm::dvec3 SceneGraphNode::calculateWorldPosition() const {
|
||||
// recursive up the hierarchy if there are parents available
|
||||
if (_parent) {
|
||||
return
|
||||
_parent->calculateWorldPosition() +
|
||||
_parent->worldRotationMatrix() *
|
||||
_parent->worldScale() *
|
||||
position();
|
||||
const glm::dvec3 wp = _parent->calculateWorldPosition();
|
||||
const glm::dmat3 wrot = _parent->worldRotationMatrix();
|
||||
const double ws = _parent->worldScale();
|
||||
const glm::dvec3 p = position();
|
||||
|
||||
return wp + wrot * ws * p;
|
||||
}
|
||||
else {
|
||||
return position();
|
||||
|
||||
Reference in New Issue
Block a user