Merge remote-tracking branch 'origin/master' into issue/2029

This commit is contained in:
Ylva Selling
2022-10-07 15:04:49 -04:00
5 changed files with 99 additions and 53 deletions

View File

@@ -75,6 +75,12 @@ public:
*/
CameraPose traversePath(double dt, float speedScale = 1.f);
/**
* Function that can be used to permaturely quit a path ,for example when skipping
* to the end
*/
void quitPath();
/**
* Return the identifer of the node that is the current appropriate anchor node, of
* the start and end waypoint's reference node. Dtermined based on how far along the

View File

@@ -72,6 +72,7 @@ public:
void abortPath();
void pausePath();
void continuePath();
void skipToEnd();
Path::Type defaultPathType() const;
double minValidBoundingSphere() const;
@@ -79,6 +80,13 @@ public:
const std::vector<SceneGraphNode*>& relevantNodes();
/**
* Find a node close to the given node. Closeness is determined by a factor times
* the bounding sphere of the object
* \return pointer to the SGN if one was found, nullptr otherwise
*/
static SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node);
/**
* \return The Lua library that contains all Lua functions available to affect the
* path navigation
@@ -99,6 +107,8 @@ private:
bool _isPlaying = false;
bool _startSimulationTimeOnFinish = false;
bool _setCameraToEndNextFrame = false;
properties::OptionProperty _defaultPathType;
properties::BoolProperty _includeRoll;
properties::FloatProperty _speedScale;

View File

@@ -36,7 +36,6 @@
#include <openspace/rendering/renderable.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/query/query.h>
#include <openspace/util/collisionhelper.h>
#include <openspace/util/universalhelpers.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/interpolator.h>
@@ -178,6 +177,11 @@ CameraPose Path::traversePath(double dt, float speedScale) {
return newPose;
}
void Path::quitPath() {
_traveledDistance = pathLength();
_shouldQuit = true;
}
std::string Path::currentAnchor() const {
bool pastHalfway = (_traveledDistance / pathLength()) > 0.5;
return (pastHalfway) ? _end.nodeIdentifier() : _start.nodeIdentifier();
@@ -440,50 +444,14 @@ Waypoint waypointFromCamera() {
return Waypoint{ pos, rot, node };
}
SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node) {
const std::vector<SceneGraphNode*>& relevantNodes =
global::navigationHandler->pathNavigator().relevantNodes();
for (SceneGraphNode* n : relevantNodes) {
bool isSame = (n->identifier() == node->identifier());
// If the nodes are in the very same position, they are probably representing
// the same object
isSame |=
glm::distance(n->worldPosition(), node->worldPosition()) < LengthEpsilon;
if (isSame) {
continue;
}
constexpr float proximityRadiusFactor = 3.f;
const float bs = static_cast<float>(n->boundingSphere());
const float proximityRadius = proximityRadiusFactor * bs;
const glm::dvec3 posInModelCoords =
glm::inverse(n->modelTransform()) * glm::dvec4(node->worldPosition(), 1.0);
bool isClose = collision::isPointInsideSphere(
posInModelCoords,
glm::dvec3(0.0, 0.0, 0.0),
proximityRadius
);
if (isClose) {
return n;
}
}
return nullptr;
}
// Compute a target position close to the specified target node, using knowledge of
// the start point and a desired distance from the node's center
glm::dvec3 computeGoodStepDirection(const SceneGraphNode* targetNode,
const Waypoint& startPoint)
{
const glm::dvec3 nodePos = targetNode->worldPosition();
const SceneGraphNode* closeNode = findNodeNearTarget(targetNode);
const SceneGraphNode* sun = sceneGraphNode(SunIdentifier);
const SceneGraphNode* closeNode = PathNavigator::findNodeNearTarget(targetNode);
// @TODO (2021-07-09, emmbr): Not nice to depend on a specific scene graph node,
// as it might not exist. Ideally, each SGN could know about their preferred

View File

@@ -38,6 +38,7 @@
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scripting/lualibrary.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/collisionhelper.h>
#include <openspace/util/timemanager.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/filesystem/file.h>
@@ -214,6 +215,19 @@ void PathNavigator::updateCamera(double deltaTime) {
return;
}
if (_setCameraToEndNextFrame) {
LDEBUG("Skipped to end of camera path");
_currentPath->quitPath();
camera()->setPose(_currentPath->endPoint().pose());
global::navigationHandler->orbitalNavigator().setFocusNode(
_currentPath->endPoint().nodeIdentifier(),
false
);
handlePathEnd();
_setCameraToEndNextFrame = false;
return;
}
// Prevent long delta times due to e.g. computations from other actions to cause
// really big jumps in the motion along the path
// OBS! Causes problems if the general FPS is lower than 10, but then the user should
@@ -241,19 +255,6 @@ void PathNavigator::updateCamera(double deltaTime) {
if (_currentPath->hasReachedEnd()) {
LINFO("Reached target");
handlePathEnd();
if (_applyIdleBehaviorOnFinish) {
constexpr const char ApplyIdleBehaviorScript[] =
"openspace.setPropertyValueSingle("
"'NavigationHandler.OrbitalNavigator.IdleBehavior.ApplyIdleBehavior',"
"true"
");";
global::scriptEngine->queueScript(
ApplyIdleBehaviorScript,
openspace::scripting::ScriptEngine::RemoteScripting::Yes
);
}
return;
}
}
@@ -368,6 +369,14 @@ void PathNavigator::continuePath() {
_isPlaying = true;
}
void PathNavigator::skipToEnd() {
if (!openspace::global::navigationHandler->pathNavigator().isPlayingPath()) {
LWARNING("No camera path is currently active");
}
_setCameraToEndNextFrame = true;
}
Path::Type PathNavigator::defaultPathType() const {
return static_cast<Path::Type>(_defaultPathType.value());
}
@@ -430,15 +439,25 @@ const std::vector<SceneGraphNode*>& PathNavigator::relevantNodes() {
void PathNavigator::handlePathEnd() {
_isPlaying = false;
global::openSpaceEngine->resetMode();
if (_startSimulationTimeOnFinish) {
openspace::global::scriptEngine->queueScript(
"openspace.time.setPause(false)",
scripting::ScriptEngine::RemoteScripting::Yes
);
_startSimulationTimeOnFinish = false;
}
if (_applyIdleBehaviorOnFinish) {
global::scriptEngine->queueScript(
"openspace.setPropertyValueSingle("
"'NavigationHandler.OrbitalNavigator.IdleBehavior.ApplyIdleBehavior',"
"true"
");",
openspace::scripting::ScriptEngine::RemoteScripting::Yes
);
}
_startSimulationTimeOnFinish = false;
global::openSpaceEngine->resetMode();
}
void PathNavigator::findRelevantNodes() {
@@ -480,6 +499,43 @@ void PathNavigator::findRelevantNodes() {
_relevantNodes = resultingNodes;
}
SceneGraphNode* PathNavigator::findNodeNearTarget(const SceneGraphNode* node) {
constexpr float LengthEpsilon = 1e-5f;
const std::vector<SceneGraphNode*>& relNodes =
global::navigationHandler->pathNavigator().relevantNodes();
for (SceneGraphNode* n : relNodes) {
bool isSame = (n->identifier() == node->identifier());
// If the nodes are in the very same position, they are probably representing
// the same object
isSame |=
glm::distance(n->worldPosition(), node->worldPosition()) < LengthEpsilon;
if (isSame) {
continue;
}
constexpr float proximityRadiusFactor = 3.f;
const float bs = static_cast<float>(n->boundingSphere());
const float proximityRadius = proximityRadiusFactor * bs;
const glm::dvec3 posInModelCoords =
glm::inverse(n->modelTransform()) * glm::dvec4(node->worldPosition(), 1.0);
bool isClose = collision::isPointInsideSphere(
posInModelCoords,
glm::dvec3(0.0, 0.0, 0.0),
proximityRadius
);
if (isClose) {
return n;
}
}
return nullptr;
}
void PathNavigator::removeRollRotation(CameraPose& pose, double deltaTime) {
const glm::dvec3 anchorPos = anchor()->worldPosition();
const glm::dvec3 cameraDir = glm::normalize(
@@ -504,6 +560,7 @@ scripting::LuaLibrary PathNavigator::luaLibrary() {
codegen::lua::ContinuePath,
codegen::lua::PausePath,
codegen::lua::StopPath,
codegen::lua::SkipToEnd,
codegen::lua::FlyTo,
codegen::lua::FlyToHeight,
codegen::lua::FlyToNavigationState,

View File

@@ -46,6 +46,11 @@ namespace {
openspace::global::navigationHandler->pathNavigator().abortPath();
}
// Immediately skips to the end of the current camera path, if one is being played.
[[codegen::luawrap]] void skipToEnd() {
openspace::global::navigationHandler->pathNavigator().skipToEnd();
}
/**
* Move the camera to the node with the specified identifier. The optional double
* specifies the duration of the motion, in seconds. If the optional bool is set to true