mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-07 21:08:33 -06:00
Remove possiblity to add stops in between segments
This commit is contained in:
@@ -120,10 +120,16 @@ namespace openspace::autonavigation {
|
||||
|
||||
AutoNavigationHandler::AutoNavigationHandler()
|
||||
: properties::PropertyOwner({ "AutoNavigationHandler" })
|
||||
, _defaultCurveOption(DefaultCurveOptionInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _defaultCurveOption(
|
||||
DefaultCurveOptionInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _includeRoll(IncludeRollInfo, false)
|
||||
, _stopAtTargetsPerDefault(StopAtTargetsPerDefaultInfo, false)
|
||||
, _defaultStopBehavior(DefaultStopBehaviorInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _defaultStopBehavior(
|
||||
DefaultStopBehaviorInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _applyStopBehaviorWhenIdle(ApplyStopBehaviorWhenIdleInfo, false)
|
||||
, _relevantNodeTags(RelevantNodeTagsInfo)
|
||||
, _defaultPositionOffsetAngle(DefaultPositionOffsetAngleInfo, 30.f, -90.f, 90.f)
|
||||
@@ -149,6 +155,11 @@ AutoNavigationHandler::AutoNavigationHandler()
|
||||
{ AtNodeNavigator::Behavior::Orbit, "Orbit" }
|
||||
});
|
||||
_defaultStopBehavior = AtNodeNavigator::Behavior::None;
|
||||
_defaultStopBehavior.onChange([this]() {
|
||||
_atNodeNavigator.setBehavior(
|
||||
AtNodeNavigator::Behavior(_defaultStopBehavior.value())
|
||||
);
|
||||
});
|
||||
addProperty(_defaultStopBehavior);
|
||||
|
||||
addProperty(_applyStopBehaviorWhenIdle);
|
||||
@@ -210,23 +221,14 @@ void AutoNavigationHandler::updateCamera(double deltaTime) {
|
||||
ghoul_assert(camera() != nullptr, "Camera must not be nullptr");
|
||||
|
||||
if (!_isPlaying || _currentPath.segments.empty()) {
|
||||
// for testing, apply at node behavior when idle
|
||||
// For testing, apply at node behavior when idle
|
||||
// @TODO: Determine how this should work instead
|
||||
if (_applyStopBehaviorWhenIdle) {
|
||||
if (_atNodeNavigator.behavior() != _defaultStopBehavior.value()) {
|
||||
_atNodeNavigator.setBehavior(
|
||||
AtNodeNavigator::Behavior(_defaultStopBehavior.value())
|
||||
);
|
||||
}
|
||||
_atNodeNavigator.updateCamera(deltaTime);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_activeStop) {
|
||||
applyStopBehaviour(deltaTime);
|
||||
return;
|
||||
}
|
||||
|
||||
// If for some reason the time is no longer paused, pause it again
|
||||
if (!global::timeManager->isPaused()) {
|
||||
global::timeManager->setPause(true);
|
||||
@@ -262,11 +264,6 @@ void AutoNavigationHandler::updateCamera(double deltaTime) {
|
||||
_isPlaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentPath.stops[index].shouldStop) {
|
||||
pauseAtTarget(index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,22 +273,12 @@ void AutoNavigationHandler::createPath(PathSpecification& spec) {
|
||||
// TODO: do this in some initialize function instead
|
||||
_relevantNodes = findRelevantNodes();
|
||||
|
||||
if (spec.stopAtTargets.has_value()) {
|
||||
_stopAtTargetsPerDefault = spec.stopAtTargets.value();
|
||||
LINFO("Property for stop at targets per default was overridden by path specification.");
|
||||
}
|
||||
|
||||
const std::vector<Instruction>& instructions = spec.instructions;
|
||||
const int nInstructions = static_cast<int>(instructions.size());
|
||||
|
||||
for (int i = 0; i < nInstructions; i++) {
|
||||
const Instruction& instruction = instructions[i];
|
||||
addSegment(instruction, i);
|
||||
|
||||
// Add info about stops between segments
|
||||
if (i < nInstructions - 1) {
|
||||
addStopDetails(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
ghoul_assert(
|
||||
@@ -314,7 +301,6 @@ void AutoNavigationHandler::createPath(PathSpecification& spec) {
|
||||
void AutoNavigationHandler::clearPath() {
|
||||
LINFO("Clearing path...");
|
||||
_currentPath.segments.clear();
|
||||
_currentPath.stops.clear();
|
||||
_currentSegmentIndex = 0;
|
||||
}
|
||||
|
||||
@@ -332,7 +318,6 @@ void AutoNavigationHandler::startPath() {
|
||||
|
||||
LINFO("Starting path...");
|
||||
_isPlaying = true;
|
||||
_activeStop = nullptr;
|
||||
}
|
||||
|
||||
void AutoNavigationHandler::continuePath() {
|
||||
@@ -341,7 +326,7 @@ void AutoNavigationHandler::continuePath() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isPlaying && !_activeStop) {
|
||||
if (_isPlaying) {
|
||||
LERROR("Cannot resume a path that is already playing");
|
||||
return;
|
||||
}
|
||||
@@ -350,7 +335,6 @@ void AutoNavigationHandler::continuePath() {
|
||||
|
||||
// recompute start camera state for the upcoming path segment,
|
||||
_currentPath.segments[_currentSegmentIndex].setStartPoint(wayPointFromCamera());
|
||||
_activeStop = nullptr;
|
||||
}
|
||||
|
||||
void AutoNavigationHandler::abortPath() {
|
||||
@@ -487,48 +471,6 @@ void AutoNavigationHandler::removeRollRotation(CameraPose& pose, double deltaTim
|
||||
pose.rotation = rollFreeRotation;
|
||||
}
|
||||
|
||||
void AutoNavigationHandler::pauseAtTarget(int i) {
|
||||
if (!_isPlaying || _activeStop) {
|
||||
LERROR("Cannot pause a path that isn't playing");
|
||||
return;
|
||||
}
|
||||
|
||||
if (i < 0 || i > _currentPath.stops.size() - 1) {
|
||||
LERROR("Invalid target number: " + std::to_string(i));
|
||||
return;
|
||||
}
|
||||
|
||||
_activeStop = &_currentPath.stops[i];
|
||||
|
||||
if (!_activeStop) return;
|
||||
|
||||
_atNodeNavigator.setBehavior(_activeStop->behavior);
|
||||
|
||||
bool hasDuration = _activeStop->duration.has_value();
|
||||
|
||||
std::string infoString = hasDuration ?
|
||||
fmt::format("{} seconds", _activeStop->duration.value()) : "until continued";
|
||||
|
||||
LINFO(fmt::format("Paused path at target {} / {} ({})",
|
||||
_currentSegmentIndex,
|
||||
_currentPath.segments.size(),
|
||||
infoString
|
||||
));
|
||||
|
||||
_progressedTimeInStop = 0.0;
|
||||
}
|
||||
|
||||
void AutoNavigationHandler::applyStopBehaviour(double deltaTime) {
|
||||
_progressedTimeInStop += deltaTime;
|
||||
_atNodeNavigator.updateCamera(deltaTime);
|
||||
|
||||
if (!_activeStop->duration.has_value()) return;
|
||||
|
||||
if (_progressedTimeInStop >= _activeStop->duration.value()) {
|
||||
continuePath();
|
||||
}
|
||||
}
|
||||
|
||||
void AutoNavigationHandler::addSegment(const Instruction& ins, int index) {
|
||||
// TODO: Improve how curve types are handled
|
||||
const int curveType = _defaultCurveOption;
|
||||
@@ -562,50 +504,6 @@ void AutoNavigationHandler::addSegment(const Instruction& ins, int index) {
|
||||
));
|
||||
}
|
||||
|
||||
void AutoNavigationHandler::addStopDetails(const Instruction& ins) {
|
||||
StopDetails stopEntry;
|
||||
stopEntry.shouldStop = _stopAtTargetsPerDefault.value();
|
||||
|
||||
if (ins.stopAtTarget.has_value()) {
|
||||
stopEntry.shouldStop = ins.stopAtTarget.value();
|
||||
}
|
||||
|
||||
if (stopEntry.shouldStop) {
|
||||
stopEntry.duration = ins.stopDuration;
|
||||
|
||||
std::string anchorIdentifier = lastWayPoint().nodeDetails.identifier;
|
||||
stopEntry.behavior = AtNodeNavigator::Behavior(_defaultStopBehavior.value());
|
||||
|
||||
if (ins.stopBehavior.has_value()) {
|
||||
std::string behaviorString = ins.stopBehavior.value();
|
||||
|
||||
// This is a bit ugly, since it relies on the OptionProperty::Option and
|
||||
// AtNodeNavigator::Behavior being implicitly converted to the same int value.
|
||||
// TODO: Come up with a nicer solution (this get to work for now...)
|
||||
|
||||
using Option = properties::OptionProperty::Option;
|
||||
std::vector<Option> options = _defaultStopBehavior.options();
|
||||
std::vector<Option>::iterator foundIt = std::find_if(
|
||||
options.begin(),
|
||||
options.end(),
|
||||
[&](Option& o) { return o.description == behaviorString; }
|
||||
);
|
||||
|
||||
if (foundIt != options.end()) {
|
||||
stopEntry.behavior = AtNodeNavigator::Behavior((*foundIt).value);
|
||||
}
|
||||
else {
|
||||
LERROR(fmt::format(
|
||||
"Stop behaviour '{}' is not a valid option. Using default behaviour.",
|
||||
behaviorString
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_currentPath.stops.push_back(stopEntry);
|
||||
}
|
||||
|
||||
// Test if the node lies within a given proximity radius of any relevant node in the scene
|
||||
SceneGraphNode* AutoNavigationHandler::findNodeNearTarget(const SceneGraphNode* node) {
|
||||
glm::dvec3 nodePos = node->worldPosition();
|
||||
|
||||
@@ -76,33 +76,21 @@ private:
|
||||
Waypoint wayPointFromCamera();
|
||||
Waypoint lastWayPoint();
|
||||
void removeRollRotation(CameraPose& pose, double deltaTime);
|
||||
void pauseAtTarget(int i);
|
||||
|
||||
void applyStopBehaviour(double deltaTime);
|
||||
|
||||
void addSegment(const Instruction& ins, int index);
|
||||
void addStopDetails(const Instruction& ins);
|
||||
|
||||
SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node);
|
||||
Waypoint computeDefaultWaypoint(const Instruction& ins);
|
||||
|
||||
std::vector<SceneGraphNode*> findRelevantNodes();
|
||||
|
||||
struct StopDetails {
|
||||
bool shouldStop;
|
||||
std::optional<double> duration;
|
||||
AtNodeNavigator::Behavior behavior;
|
||||
};
|
||||
|
||||
struct Path {
|
||||
std::vector<PathSegment> segments;
|
||||
std::vector<StopDetails> stops; // 1 between every segment
|
||||
};
|
||||
|
||||
Path _currentPath;
|
||||
|
||||
AtNodeNavigator _atNodeNavigator; // responsible for navigation during stops
|
||||
StopDetails* _activeStop = nullptr;
|
||||
double _progressedTimeInStop = 0.0;
|
||||
|
||||
bool _isPlaying = false;
|
||||
|
||||
@@ -64,18 +64,6 @@ namespace {
|
||||
// of this path segment.
|
||||
std::optional<ghoul::Dictionary> navigationState
|
||||
[[codegen::reference("core_navigation_state")]];
|
||||
|
||||
// If true, a pause will be added after the path segment that this instruction
|
||||
// translates into.
|
||||
std::optional<bool> stopAtTarget;
|
||||
|
||||
struct StopDetails {
|
||||
std::optional<float> duration;
|
||||
std::optional<std::string> behavior;
|
||||
};
|
||||
// Furter details on any stop in the path that will happen after this path
|
||||
// segment. Can specify the duration and pause behavior.
|
||||
std::optional<StopDetails> stopDetails;
|
||||
};
|
||||
#include "instruction_codegen.cpp"
|
||||
} // namespace
|
||||
@@ -90,12 +78,6 @@ Instruction::Instruction(const ghoul::Dictionary& dictionary) {
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
duration = p.duration;
|
||||
stopAtTarget = p.stopAtTarget;
|
||||
|
||||
if (p.stopDetails.has_value()) {
|
||||
stopDuration = p.stopDetails.value().duration;
|
||||
stopBehavior = p.stopDetails.value().behavior;
|
||||
}
|
||||
|
||||
switch (p.type) {
|
||||
case Parameters::Type::NavigationState: {
|
||||
|
||||
@@ -46,11 +46,6 @@ struct Instruction {
|
||||
Type type;
|
||||
|
||||
std::optional<double> duration;
|
||||
std::optional<bool> stopAtTarget;
|
||||
|
||||
// Only relevant is stopAtTarget true
|
||||
std::optional<double> stopDuration;
|
||||
std::optional<std::string> stopBehavior;
|
||||
|
||||
// Node details
|
||||
std::string nodeIdentifier;
|
||||
|
||||
@@ -36,9 +36,6 @@ namespace {
|
||||
std::vector<ghoul::Dictionary> instructions
|
||||
[[codegen::reference("autonavigation_pathinstruction")]];
|
||||
|
||||
// Decides whether the path should be paused when reaching an intermediate target
|
||||
std::optional<bool> stopAtTargets;
|
||||
|
||||
// A navigation state that determines the start state for the camera path
|
||||
std::optional<ghoul::Dictionary> startState
|
||||
[[codegen::reference("core_navigation_state")]];
|
||||
@@ -67,8 +64,6 @@ PathSpecification::PathSpecification(const ghoul::Dictionary& dictionary) {
|
||||
counter++;
|
||||
}
|
||||
|
||||
stopAtTargets = p.stopAtTargets;
|
||||
|
||||
if (p.startState.has_value()) {
|
||||
startState = NavigationState(p.startState.value());
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ struct PathSpecification {
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
std::vector<Instruction> instructions;
|
||||
std::optional<bool> stopAtTargets;
|
||||
std::optional<NavigationState> startState;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user