mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-23 05:19:18 -06:00
Merge branch 'feature/camera-path-fixes' into project/spaceship-installation
This commit is contained in:
Submodule apps/OpenSpace/ext/sgct updated: 606a5ba8d6...4301011f99
Submodule ext/ghoul updated: b9013de0cb...692af309c6
@@ -37,6 +37,7 @@
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/util/collisionhelper.h>
|
||||
#include <openspace/util/universalhelpers.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/interpolator.h>
|
||||
|
||||
@@ -235,51 +236,70 @@ glm::dquat Path::lookAtTargetsRotation(double t) const {
|
||||
double Path::speedAlongPath(double traveledDistance) const {
|
||||
const glm::dvec3 endNodePos = _end.node()->worldPosition();
|
||||
const glm::dvec3 startNodePos = _start.node()->worldPosition();
|
||||
|
||||
const CameraPose prevPose = interpolatedPose(traveledDistance);
|
||||
const double distanceToEndNode = glm::distance(prevPose.position, endNodePos);
|
||||
const double distanceToStartNode = glm::distance(prevPose.position, startNodePos);
|
||||
|
||||
// Decide which is the closest node
|
||||
SceneGraphNode* closestNode = _start.node();
|
||||
glm::dvec3 closestPos = startNodePos;
|
||||
|
||||
if (distanceToEndNode < distanceToStartNode) {
|
||||
closestPos = endNodePos;
|
||||
closestNode = _end.node();
|
||||
bool endNodeIsClosest = (distanceToEndNode < distanceToStartNode);
|
||||
if (_start.nodeIdentifier() == _end.nodeIdentifier()) {
|
||||
endNodeIsClosest = traveledDistance > (0.5 * pathLength());
|
||||
}
|
||||
|
||||
const SceneGraphNode* closestNode = endNodeIsClosest ? _end.node() : _start.node();
|
||||
const glm::dvec3 closestPos = closestNode->worldPosition();
|
||||
const glm::dvec3 closestEdgePos =
|
||||
endNodeIsClosest ? _end.position() : _start.position();
|
||||
|
||||
// Distance to the surface at the target position
|
||||
const glm::dvec3 edgePosModelSpace = glm::dvec3(
|
||||
glm::inverse(closestNode->modelTransform()) * glm::dvec4(closestEdgePos, 1.0)
|
||||
);
|
||||
const SurfacePositionHandle posHandle =
|
||||
closestNode->calculateSurfacePositionHandle(edgePosModelSpace);
|
||||
|
||||
const glm::dvec3 centerToActualSurfaceModelSpace =
|
||||
posHandle.centerToReferenceSurface +
|
||||
posHandle.referenceSurfaceOutDirection * posHandle.heightToSurface;
|
||||
|
||||
const glm::dvec3 centerToActualSurface =
|
||||
glm::dmat3(closestNode->modelTransform()) * centerToActualSurfaceModelSpace;
|
||||
|
||||
// Compute speed based on distance to object surface
|
||||
const double distanceToClosestNode = glm::distance(closestPos, prevPose.position);
|
||||
double speed = distanceToClosestNode;
|
||||
double distanceToSurface = distanceToClosestNode - glm::length(centerToActualSurface);
|
||||
double speed = distanceToSurface;
|
||||
|
||||
// Dampen speed in beginning of path
|
||||
double startUpDistance = 2.0 * _start.node()->boundingSphere();
|
||||
if (startUpDistance < Epsilon) { // zero bounding sphere
|
||||
startUpDistance = glm::distance(_start.position(), startNodePos);
|
||||
const double edgePosToSurfaceDistance =
|
||||
glm::distance(closestEdgePos, closestPos) - glm::length(centerToActualSurface);
|
||||
|
||||
// Dampen speed in beginning and end of path
|
||||
double dampeningDistance = 2.0 * edgePosToSurfaceDistance;
|
||||
|
||||
// If the path is short, use another dampening approach, based on the boudningsphere
|
||||
if (pathLength() < dampeningDistance) {
|
||||
dampeningDistance = closestNode->boundingSphere();
|
||||
}
|
||||
|
||||
if (traveledDistance < startUpDistance) {
|
||||
speed *= traveledDistance / startUpDistance + 0.01;
|
||||
}
|
||||
// Buffer to prevent zero speed
|
||||
constexpr const double buffer = 0.04;
|
||||
|
||||
// Dampen speed in end of path
|
||||
// Note: this leads to problems when the full length of the path is really big
|
||||
double closeUpDistance = 2.0 * _end.node()->boundingSphere();
|
||||
if (closeUpDistance < Epsilon) { // zero bounding sphere
|
||||
closeUpDistance = glm::distance(_end.position(), endNodePos);
|
||||
if (traveledDistance < dampeningDistance) {
|
||||
speed *= ghoul::sineEaseOut(traveledDistance / dampeningDistance) + buffer;
|
||||
}
|
||||
|
||||
if (traveledDistance > (pathLength() - closeUpDistance)) {
|
||||
const double remainingDistance = pathLength() - traveledDistance;
|
||||
speed *= remainingDistance / closeUpDistance + 0.01;
|
||||
else if (traveledDistance > (pathLength() - dampeningDistance)) {
|
||||
double remainingDistance = pathLength() - traveledDistance;
|
||||
// If the path length estimate is not completely correct, the remaining distance
|
||||
// might be negative. Prevent that from causing problems with the speed.
|
||||
if (remainingDistance < 0.0) {
|
||||
remainingDistance = 0.1;
|
||||
}
|
||||
speed *= ghoul::sineEaseOut(remainingDistance / dampeningDistance) + buffer;
|
||||
}
|
||||
|
||||
// TODO: also dampen speed based on curvature, or make sure the curve has a rounder
|
||||
// shape
|
||||
|
||||
// TODO: check for when path is shorter than the starUpDistance or closeUpDistance
|
||||
// variables
|
||||
|
||||
return _speedFactorFromDuration * speed;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ TEST_CASE("StringListProperty: Get Lua Value", "[stringlistproperty]") {
|
||||
p.getLuaValue(L);
|
||||
|
||||
REQUIRE(ghoul::lua::luaValueToString(L, 1) ==
|
||||
"{ 1.000000 = a, 2.000000 = b, 3.000000 = c }"
|
||||
"{ [1] = \"a\", [2] = \"b\", [3] = \"c\" }"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ TEST_CASE("IntListProperty: Get Lua Value", "[intlistproperty]") {
|
||||
p.getLuaValue(L);
|
||||
|
||||
REQUIRE(ghoul::lua::luaValueToString(L, 1) ==
|
||||
"{ 1.000000 = 1.000000, 2.000000 = 2.000000, 3.000000 = 3.000000 }"
|
||||
"{ [1] = 1.000000, [2] = 2.000000, [3] = 3.000000 }"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ TEST_CASE("DoubleListProperty: Get Lua Value", "[doublelistproperty]") {
|
||||
p.getLuaValue(L);
|
||||
|
||||
REQUIRE(ghoul::lua::luaValueToString(L, 1) ==
|
||||
"{ 1.000000 = 1.000000, 2.000000 = 2.000000, 3.000000 = 3.000000 }"
|
||||
"{ [1] = 1.000000, [2] = 2.000000, [3] = 3.000000 }"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,9 @@ TEST_CASE("CreateSingleColorImage: Faulty 1st input type", "[createsinglecolorim
|
||||
|
||||
CHECK_THROWS_WITH(
|
||||
openspace::luascriptfunctions::createSingleColorImage(L),
|
||||
Catch::Matchers::Contains("parameter 1 was not the expected type")
|
||||
Catch::Matchers::Contains(
|
||||
"Expected type 'String' for parameter 1 but got wrong type 'Table'"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -71,7 +73,9 @@ TEST_CASE("CreateSingleColorImage: Faulty 2nd input type", "[createsinglecolorim
|
||||
|
||||
CHECK_THROWS_WITH(
|
||||
openspace::luascriptfunctions::createSingleColorImage(L),
|
||||
Catch::Matchers::Contains("parameter 2 was not the expected type")
|
||||
Catch::Matchers::Contains(
|
||||
"Expected type 'Table' for parameter 2 but got wrong type 'String'"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user