mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-07 21:08:33 -06:00
More cleanup/restructuring
This commit is contained in:
@@ -25,7 +25,6 @@
|
||||
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
|
||||
set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/atnodenavigator.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/autonavigationhandler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/autonavigationmodule.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/helperfunctions.h
|
||||
@@ -40,7 +39,6 @@ set(HEADER_FILES
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/atnodenavigator.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/autonavigationhandler.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/autonavigationmodule.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/autonavigationmodule_lua.inl
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/autonavigation/atnodenavigator.h>
|
||||
|
||||
#include <modules/autonavigation/helperfunctions.h>
|
||||
#include <modules/autonavigation/waypoint.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/rotate_vector.hpp>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "AtNodeNavigator";
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo OrbitSpeedFactorInfo = {
|
||||
"OrbitSpeedFactor",
|
||||
"Orbit Speed Factor",
|
||||
"Controls the speed of the orbiting around an anchor."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace::autonavigation {
|
||||
|
||||
AtNodeNavigator::AtNodeNavigator()
|
||||
: properties::PropertyOwner({ "AtNodeNavigator" })
|
||||
, _orbitSpeedFactor(OrbitSpeedFactorInfo, 0.5, 0.0, 20.0)
|
||||
{
|
||||
addProperty(_orbitSpeedFactor);
|
||||
_behavior = Behavior::None;
|
||||
}
|
||||
|
||||
AtNodeNavigator::~AtNodeNavigator() {} // NOLINT
|
||||
|
||||
AtNodeNavigator::Behavior AtNodeNavigator::behavior() const {
|
||||
return _behavior;
|
||||
}
|
||||
|
||||
void AtNodeNavigator::setBehavior(Behavior behavior) {
|
||||
_behavior = behavior;
|
||||
}
|
||||
|
||||
void AtNodeNavigator::updateCamera(double deltaTime) {
|
||||
switch (_behavior)
|
||||
{
|
||||
case Behavior::Orbit:
|
||||
orbitNode(deltaTime);
|
||||
break;
|
||||
case Behavior::None:
|
||||
// Do nothing
|
||||
break;
|
||||
default:
|
||||
LERROR("Behavior type not implemented.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Camera* AtNodeNavigator::camera() const {
|
||||
return global::navigationHandler->camera();
|
||||
}
|
||||
|
||||
const SceneGraphNode* AtNodeNavigator::anchor() const {
|
||||
return global::navigationHandler->anchorNode();
|
||||
}
|
||||
|
||||
// Move along the right vector for the camera, while looking at the center of the node
|
||||
void AtNodeNavigator::orbitNode(double deltaTime) {
|
||||
ghoul_assert(anchor() != nullptr, "Node to orbit must be set!")
|
||||
const glm::dvec3 prevPosition = camera()->positionVec3();
|
||||
const glm::dquat prevRotation = camera()->rotationQuaternion();
|
||||
|
||||
const glm::dvec3 up = camera()->lookUpVectorWorldSpace();
|
||||
const double speedFactor = 0.1 * _orbitSpeedFactor;
|
||||
|
||||
glm::dvec3 nodeCenter = anchor()->worldPosition();
|
||||
double orbitRadius = glm::distance(prevPosition, nodeCenter);
|
||||
double distanceToSurface = orbitRadius - anchor()->boundingSphere();
|
||||
double orbitSpeed = distanceToSurface * speedFactor;
|
||||
|
||||
// compute a new position along the orbit
|
||||
const glm::dquat lookAtNodeRotation = helpers::lookAtQuaternion(
|
||||
prevPosition,
|
||||
nodeCenter,
|
||||
up
|
||||
);
|
||||
const glm::dvec3 targetForward = lookAtNodeRotation * glm::dvec3(0.0, 0.0, -1.0);
|
||||
const glm::dvec3 rightOrbitTangent = glm::normalize(glm::cross(targetForward, up));
|
||||
|
||||
glm::dvec3 newPosition = prevPosition + orbitSpeed * deltaTime * rightOrbitTangent;
|
||||
|
||||
// adjust for numerical error
|
||||
const glm::dvec3 nodeToNewPos = newPosition - nodeCenter;
|
||||
const double nodeToPrevPosDistance = glm::distance(prevPosition, nodeCenter);
|
||||
const double distanceDiff = glm::length(nodeToNewPos) - nodeToPrevPosDistance;
|
||||
newPosition -= distanceDiff * glm::normalize(nodeToNewPos);
|
||||
|
||||
// rotate with the orbit, but keep the relative orientation with regards to the anchor
|
||||
const glm::dquat localRotation = glm::inverse(lookAtNodeRotation) * prevRotation;
|
||||
const glm::dquat newLookAtRotation =
|
||||
helpers::lookAtQuaternion(newPosition, nodeCenter, up);
|
||||
|
||||
const glm::dquat newRotation = newLookAtRotation * localRotation;
|
||||
|
||||
camera()->setPositionVec3(newPosition);
|
||||
camera()->setRotation(newRotation);
|
||||
}
|
||||
|
||||
} // namespace openspace::autonavigation
|
||||
@@ -1,66 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE___ATNODENAVIGATOR___H__
|
||||
#define __OPENSPACE_MODULE___ATNODENAVIGATOR___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/properties/scalar/doubleproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
class Camera;
|
||||
class SceneGraphNode;
|
||||
} // namespace openspace
|
||||
|
||||
namespace openspace::autonavigation {
|
||||
|
||||
class AtNodeNavigator : public properties::PropertyOwner {
|
||||
public:
|
||||
enum Behavior {
|
||||
None = 0,
|
||||
Orbit,
|
||||
};
|
||||
|
||||
AtNodeNavigator();
|
||||
~AtNodeNavigator();
|
||||
|
||||
Behavior behavior() const;
|
||||
void setBehavior(Behavior behavior);
|
||||
|
||||
void updateCamera(double deltaTime);
|
||||
|
||||
private:
|
||||
Camera* camera() const;
|
||||
const SceneGraphNode* anchor() const;
|
||||
|
||||
//Behaviors
|
||||
void orbitNode(double deltaTime);
|
||||
|
||||
Behavior _behavior;
|
||||
properties::DoubleProperty _orbitSpeedFactor;
|
||||
};
|
||||
|
||||
} // namespace openspace::autonavigation
|
||||
|
||||
#endif // __OPENSPACE_MODULE___ATNODENAVIGATOR___H__
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <modules/autonavigation/helperfunctions.h>
|
||||
#include <modules/autonavigation/pathinstruction.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
@@ -45,27 +44,28 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo DefaultCurveOptionInfo = {
|
||||
"DefaultCurveOption",
|
||||
"Default Curve Option",
|
||||
"The defualt curve type chosen when generating a path, if none is specified."
|
||||
"The defualt curve type chosen when generating a path, if none is specified"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo IncludeRollInfo = {
|
||||
"IncludeRoll",
|
||||
"Include Roll",
|
||||
"If disabled, roll is removed from the interpolation of camera orientation."
|
||||
"If disabled, roll is removed from the interpolation of camera orientation"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DefaultStopBehaviorInfo = {
|
||||
"DefaultStopBehavior",
|
||||
"Default Stop Behavior",
|
||||
"The default camera behavior that is applied when the camera reaches and stops "
|
||||
"at a target."
|
||||
constexpr openspace::properties::Property::PropertyInfo StopBehaviorInfo = {
|
||||
"StopBehavior",
|
||||
"Stop Behavior",
|
||||
"A camera motion behavior that is applied when no path is being played"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ApplyStopBehaviorWhenIdleInfo = {
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
ApplyStopBehaviorWhenIdleInfo =
|
||||
{
|
||||
"ApplyStopBehaviorWhenIdle",
|
||||
"Apply Stop Behavior When Idle",
|
||||
"If enabled, the camera is controlled using the default stop behavior even when"
|
||||
"no path is playing."
|
||||
"If enabled, the camera is controlled using the set stop behavior when"
|
||||
"no path is playing"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SpeedScaleInfo = {
|
||||
@@ -74,6 +74,11 @@ namespace {
|
||||
"Scale factor that affects the default speed for a camera path."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OrbitSpeedFactorInfo = {
|
||||
"OrbitSpeedFactor",
|
||||
"Orbit Speed Factor",
|
||||
"Controls the speed of the orbiting around an anchor."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace::autonavigation {
|
||||
@@ -86,14 +91,13 @@ AutoNavigationHandler::AutoNavigationHandler()
|
||||
)
|
||||
, _includeRoll(IncludeRollInfo, false)
|
||||
, _stopBehavior(
|
||||
DefaultStopBehaviorInfo,
|
||||
StopBehaviorInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _applyStopBehaviorWhenIdle(ApplyStopBehaviorWhenIdleInfo, false)
|
||||
, _speedScale(SpeedScaleInfo, 1.f, 0.01f, 2.f)
|
||||
, _orbitSpeedFactor(OrbitSpeedFactorInfo, 0.5, 0.0, 20.0)
|
||||
{
|
||||
addPropertySubOwner(_atNodeNavigator);
|
||||
|
||||
_defaultCurveOption.addOptions({
|
||||
{ CurveType::AvoidCollision, "AvoidCollision" },
|
||||
{ CurveType::Linear, "Linear" },
|
||||
@@ -108,16 +112,13 @@ AutoNavigationHandler::AutoNavigationHandler()
|
||||
|
||||
// Must be listed in the same order as in enum definition
|
||||
_stopBehavior.addOptions({
|
||||
{ AtNodeNavigator::Behavior::None, "None" },
|
||||
{ AtNodeNavigator::Behavior::Orbit, "Orbit" }
|
||||
});
|
||||
_stopBehavior = AtNodeNavigator::Behavior::None;
|
||||
_stopBehavior.onChange([this]() {
|
||||
_atNodeNavigator.setBehavior(
|
||||
AtNodeNavigator::Behavior(_stopBehavior.value())
|
||||
);
|
||||
{ StopBehavior::None, "None" },
|
||||
{ StopBehavior::Orbit, "Orbit" }
|
||||
});
|
||||
_stopBehavior = StopBehavior::None;
|
||||
addProperty(_stopBehavior);
|
||||
|
||||
addProperty(_orbitSpeedFactor);
|
||||
}
|
||||
|
||||
AutoNavigationHandler::~AutoNavigationHandler() {} // NOLINT
|
||||
@@ -150,10 +151,9 @@ void AutoNavigationHandler::updateCamera(double deltaTime) {
|
||||
ghoul_assert(camera() != nullptr, "Camera must not be nullptr");
|
||||
|
||||
if (!_isPlaying) {
|
||||
// For testing, apply at node behavior when idle
|
||||
// @TODO: Determine how this should work instead
|
||||
// TODO: Determine how this should work
|
||||
if (_applyStopBehaviorWhenIdle) {
|
||||
_atNodeNavigator.updateCamera(deltaTime);
|
||||
applyStopBehavior(deltaTime);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -199,7 +199,7 @@ void AutoNavigationHandler::createPath(PathInstruction& instruction) {
|
||||
// TODO: Improve how curve types are handled
|
||||
const int curveType = _defaultCurveOption;
|
||||
|
||||
std::vector<Waypoint> waypoints = instruction.waypoints;
|
||||
std::vector<Waypoint> waypoints = instruction.waypoints();
|
||||
Waypoint waypointToAdd;
|
||||
|
||||
if (waypoints.empty()) {
|
||||
@@ -212,10 +212,10 @@ void AutoNavigationHandler::createPath(PathInstruction& instruction) {
|
||||
}
|
||||
|
||||
_currentPath = std::make_unique<Path>(
|
||||
instruction.startPoint,
|
||||
instruction.startPoint(),
|
||||
waypointToAdd,
|
||||
CurveType(curveType),
|
||||
instruction.duration
|
||||
instruction.duration()
|
||||
);
|
||||
|
||||
LINFO("Successfully generated camera path");
|
||||
@@ -367,4 +367,59 @@ void AutoNavigationHandler::removeRollRotation(CameraPose& pose, double deltaTim
|
||||
pose.rotation = rollFreeRotation;
|
||||
}
|
||||
|
||||
void AutoNavigationHandler::applyStopBehavior(double deltaTime) {
|
||||
switch (_stopBehavior) {
|
||||
case StopBehavior::None:
|
||||
// Do nothing
|
||||
break;
|
||||
case StopBehavior::Orbit:
|
||||
orbitAnchorNode(deltaTime);
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
void AutoNavigationHandler::orbitAnchorNode(double deltaTime) {
|
||||
ghoul_assert(anchor() != nullptr, "Node to orbit must be set!");
|
||||
|
||||
const glm::dvec3 prevPosition = camera()->positionVec3();
|
||||
const glm::dquat prevRotation = camera()->rotationQuaternion();
|
||||
|
||||
const glm::dvec3 up = camera()->lookUpVectorWorldSpace();
|
||||
const double speedFactor = 0.1 * _orbitSpeedFactor;
|
||||
|
||||
glm::dvec3 nodeCenter = anchor()->worldPosition();
|
||||
double orbitRadius = glm::distance(prevPosition, nodeCenter);
|
||||
double distanceToSurface = orbitRadius - anchor()->boundingSphere();
|
||||
double orbitSpeed = distanceToSurface * speedFactor;
|
||||
|
||||
// compute a new position along the orbit
|
||||
const glm::dquat lookAtNodeRotation = helpers::lookAtQuaternion(
|
||||
prevPosition,
|
||||
nodeCenter,
|
||||
up
|
||||
);
|
||||
const glm::dvec3 targetForward = lookAtNodeRotation * glm::dvec3(0.0, 0.0, -1.0);
|
||||
const glm::dvec3 rightOrbitTangent = glm::normalize(glm::cross(targetForward, up));
|
||||
|
||||
glm::dvec3 newPosition = prevPosition + orbitSpeed * deltaTime * rightOrbitTangent;
|
||||
|
||||
// adjust for numerical error
|
||||
const glm::dvec3 nodeToNewPos = newPosition - nodeCenter;
|
||||
const double nodeToPrevPosDistance = glm::distance(prevPosition, nodeCenter);
|
||||
const double distanceDiff = glm::length(nodeToNewPos) - nodeToPrevPosDistance;
|
||||
newPosition -= distanceDiff * glm::normalize(nodeToNewPos);
|
||||
|
||||
// rotate with the orbit, but keep relative orientation with regards to the anchor
|
||||
const glm::dquat localRotation = glm::inverse(lookAtNodeRotation) * prevRotation;
|
||||
const glm::dquat newLookAtRotation =
|
||||
helpers::lookAtQuaternion(newPosition, nodeCenter, up);
|
||||
|
||||
const glm::dquat newRotation = newLookAtRotation * localRotation;
|
||||
|
||||
camera()->setPositionVec3(newPosition);
|
||||
camera()->setRotation(newRotation);
|
||||
}
|
||||
|
||||
} // namespace openspace::autonavigation
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#ifndef __OPENSPACE_MODULE___AUTONAVIGATIONHANDLER___H__
|
||||
#define __OPENSPACE_MODULE___AUTONAVIGATIONHANDLER___H__
|
||||
|
||||
#include <modules/autonavigation/atnodenavigator.h>
|
||||
#include <modules/autonavigation/path.h>
|
||||
#include <openspace/properties/list/stringlistproperty.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
@@ -43,6 +42,11 @@ struct PathInstruction;
|
||||
|
||||
class AutoNavigationHandler : public properties::PropertyOwner {
|
||||
public:
|
||||
enum StopBehavior {
|
||||
None = 0,
|
||||
Orbit
|
||||
};
|
||||
|
||||
AutoNavigationHandler();
|
||||
~AutoNavigationHandler();
|
||||
|
||||
@@ -71,15 +75,17 @@ public:
|
||||
|
||||
private:
|
||||
void removeRollRotation(CameraPose& pose, double deltaTime);
|
||||
void applyStopBehavior(double deltaTime);
|
||||
|
||||
void orbitAnchorNode(double deltaTime);
|
||||
|
||||
std::unique_ptr<Path> _currentPath = nullptr;
|
||||
|
||||
AtNodeNavigator _atNodeNavigator;
|
||||
bool _isPlaying = false;
|
||||
|
||||
properties::OptionProperty _defaultCurveOption;
|
||||
properties::BoolProperty _includeRoll;
|
||||
properties::FloatProperty _speedScale;
|
||||
properties::FloatProperty _orbitSpeedFactor;
|
||||
|
||||
// for testing pause behaviors.
|
||||
// TODO: remove later, if it causes problems with regular navigation
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace {
|
||||
constexpr const char* _loggerCat = "PathInstruction";
|
||||
constexpr const float Epsilon = 1e-5f;
|
||||
|
||||
|
||||
struct [[codegen::Dictionary(Instruction)]] Parameters {
|
||||
enum class Type {
|
||||
Node,
|
||||
@@ -85,31 +84,27 @@ documentation::Documentation PathInstruction::Documentation() {
|
||||
PathInstruction::PathInstruction(const ghoul::Dictionary& dictionary) {
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
duration = p.duration;
|
||||
_duration = p.duration;
|
||||
|
||||
bool hasStart = p.startState.has_value();
|
||||
startPoint = hasStart ? Waypoint(p.startState.value()) : waypointFromCamera();
|
||||
_startPoint = hasStart ? Waypoint(p.startState.value()) : waypointFromCamera();
|
||||
|
||||
switch (p.type) {
|
||||
case Parameters::Type::NavigationState: {
|
||||
type = Type::NavigationState;
|
||||
|
||||
if (!p.navigationState.has_value()) {
|
||||
throw ghoul::RuntimeError("A navigation state is required");
|
||||
}
|
||||
|
||||
navigationState = NavigationState(p.navigationState.value());
|
||||
waypoints = { Waypoint(navigationState) };
|
||||
NavigationState navigationState = NavigationState(p.navigationState.value());
|
||||
_waypoints = { Waypoint(navigationState) };
|
||||
break;
|
||||
}
|
||||
case Parameters::Type::Node: {
|
||||
type = Type::Node;
|
||||
|
||||
if (!p.target.has_value()) {
|
||||
throw ghoul::RuntimeError("A target node is required");
|
||||
}
|
||||
|
||||
nodeIdentifier = p.target.value();
|
||||
std::string nodeIdentifier = p.target.value();
|
||||
const SceneGraphNode* targetNode = sceneGraphNode(nodeIdentifier);
|
||||
|
||||
if (!targetNode) {
|
||||
@@ -118,10 +113,14 @@ PathInstruction::PathInstruction(const ghoul::Dictionary& dictionary) {
|
||||
));
|
||||
}
|
||||
|
||||
position = p.position;
|
||||
height = p.height;
|
||||
useTargetUpDirection = p.useTargetUpDirection.value_or(false);
|
||||
waypoints = { computeDefaultWaypoint() };
|
||||
NodeInfo info {
|
||||
nodeIdentifier,
|
||||
p.position,
|
||||
p.height,
|
||||
p.useTargetUpDirection.value_or(false)
|
||||
};
|
||||
|
||||
_waypoints = { computeDefaultWaypoint(info) };
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -132,6 +131,18 @@ PathInstruction::PathInstruction(const ghoul::Dictionary& dictionary) {
|
||||
}
|
||||
}
|
||||
|
||||
Waypoint PathInstruction::startPoint() const {
|
||||
return _startPoint;
|
||||
}
|
||||
|
||||
std::vector<Waypoint> PathInstruction::waypoints() const {
|
||||
return _waypoints;
|
||||
}
|
||||
|
||||
std::optional<double> PathInstruction::duration() const {
|
||||
return _duration;
|
||||
}
|
||||
|
||||
Waypoint PathInstruction::waypointFromCamera() const {
|
||||
Camera* camera = global::navigationHandler->camera();
|
||||
const glm::dvec3 pos = camera->positionVec3();
|
||||
@@ -142,19 +153,19 @@ Waypoint PathInstruction::waypointFromCamera() const {
|
||||
|
||||
// OBS! The desired default waypoint may vary between curve types.
|
||||
// TODO: let the curves update the default position if no exact position is required
|
||||
Waypoint PathInstruction::computeDefaultWaypoint() const {
|
||||
const SceneGraphNode* targetNode = sceneGraphNode(nodeIdentifier);
|
||||
Waypoint PathInstruction::computeDefaultWaypoint(const NodeInfo& info) const {
|
||||
const SceneGraphNode* targetNode = sceneGraphNode(info.identifier);
|
||||
if (!targetNode) {
|
||||
LERROR(fmt::format("Could not find target node '{}'", nodeIdentifier));
|
||||
LERROR(fmt::format("Could not find target node '{}'", info.identifier));
|
||||
return Waypoint();
|
||||
}
|
||||
|
||||
glm::dvec3 targetPos;
|
||||
if (position.has_value()) {
|
||||
if (info.position.has_value()) {
|
||||
// Note that the anchor and reference frame is our targetnode.
|
||||
// The position in instruction is given is relative coordinates
|
||||
targetPos = targetNode->worldPosition() +
|
||||
targetNode->worldRotationMatrix() * position.value();
|
||||
targetNode->worldRotationMatrix() * info.position.value();
|
||||
}
|
||||
else {
|
||||
const glm::dvec3 nodePos = targetNode->worldPosition();
|
||||
@@ -175,7 +186,7 @@ Waypoint PathInstruction::computeDefaultWaypoint() const {
|
||||
else {
|
||||
// Go to a point that is being lit up by the sun, slightly offsetted from sun
|
||||
// direction
|
||||
const glm::dvec3 prevPos = startPoint.position();
|
||||
const glm::dvec3 prevPos = _startPoint.position();
|
||||
const glm::dvec3 targetToPrev = prevPos - nodePos;
|
||||
const glm::dvec3 targetToSun = sunPos - nodePos;
|
||||
|
||||
@@ -189,25 +200,23 @@ Waypoint PathInstruction::computeDefaultWaypoint() const {
|
||||
|
||||
const double radius = Waypoint::findValidBoundingSphere(targetNode);
|
||||
const double defaultHeight = 2.0 * radius;
|
||||
const double targetHeight = height.value_or(defaultHeight);
|
||||
const double height = info.height.value_or(defaultHeight);
|
||||
|
||||
targetPos = nodePos + stepDirection * (radius + targetHeight);
|
||||
targetPos = nodePos + stepDirection * (radius + height);
|
||||
}
|
||||
|
||||
// Up direction
|
||||
glm::dvec3 up = global::navigationHandler->camera()->lookUpVectorWorldSpace();
|
||||
if (useTargetUpDirection) {
|
||||
if (info.useTargetUpDirection) {
|
||||
// @TODO (emmbr 2020-11-17) For now, this is hardcoded to look good for Earth,
|
||||
// which is where it matters the most. A better solution would be to make each
|
||||
// sgn aware of its own 'up' and query
|
||||
up = targetNode->worldRotationMatrix() * glm::dvec3(0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// Rotation
|
||||
const glm::dvec3 lookAtPos = targetNode->worldPosition();
|
||||
const glm::dquat targetRot = helpers::lookAtQuaternion(targetPos, lookAtPos, up);
|
||||
|
||||
return Waypoint(targetPos, targetRot, nodeIdentifier);
|
||||
return Waypoint(targetPos, targetRot, info.identifier);
|
||||
}
|
||||
|
||||
// Test if the node lies within a given proximity radius of any relevant node in the scene
|
||||
|
||||
@@ -31,36 +31,33 @@
|
||||
|
||||
namespace openspace::autonavigation {
|
||||
|
||||
struct PathInstruction {
|
||||
class PathInstruction {
|
||||
public:
|
||||
using NavigationState = interaction::NavigationHandler::NavigationState;
|
||||
|
||||
enum class Type {
|
||||
Node,
|
||||
NavigationState
|
||||
};
|
||||
|
||||
PathInstruction(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Waypoint startPoint() const;
|
||||
std::vector<Waypoint> waypoints() const;
|
||||
std::optional<double> duration() const;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
struct NodeInfo {
|
||||
std::string identifier;
|
||||
std::optional<glm::dvec3> position;
|
||||
std::optional<double> height;
|
||||
bool useTargetUpDirection;
|
||||
};
|
||||
|
||||
Waypoint waypointFromCamera() const;
|
||||
Waypoint computeDefaultWaypoint() const;
|
||||
Waypoint computeDefaultWaypoint(const NodeInfo& info) const;
|
||||
SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node) const;
|
||||
|
||||
Type type;
|
||||
|
||||
// Node details
|
||||
std::string nodeIdentifier;
|
||||
std::optional<glm::dvec3> position;
|
||||
std::optional<double> height;
|
||||
bool useTargetUpDirection;
|
||||
|
||||
// Navigation state details
|
||||
NavigationState navigationState;
|
||||
|
||||
std::optional<double> duration;
|
||||
Waypoint startPoint;
|
||||
std::vector<Waypoint> waypoints;
|
||||
Waypoint _startPoint;
|
||||
std::vector<Waypoint> _waypoints;
|
||||
std::optional<double> _duration;
|
||||
};
|
||||
|
||||
} // namespace openspace::autonavigation
|
||||
|
||||
Reference in New Issue
Block a user