mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-09 05:00:42 -06:00
Merge remote-tracking branch 'origin/master' into issue/2029
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user