mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-04 10:40:09 -06:00
Move camera path code into core and refactor navigation code a bit
This commit is contained in:
@@ -28,16 +28,18 @@
|
||||
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <QComboBox>
|
||||
#include <QFile>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QStandardItemModel>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
using namespace openspace;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "profile/line.h"
|
||||
#include <openspace/scene/profile.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "profile/line.h"
|
||||
#include <openspace/scene/profile.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDoubleValidator>
|
||||
#include <QEvent>
|
||||
|
||||
173
include/openspace/camera/camera.h
Normal file
173
include/openspace/camera/camera.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___CAMERA___H__
|
||||
#define __OPENSPACE_CORE___CAMERA___H__
|
||||
|
||||
#include <openspace/util/syncdata.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <mutex>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class SceneGraphNode;
|
||||
|
||||
/**
|
||||
* This class still needs some more love. Suggested improvements:
|
||||
* - Accessors should return constant references to double precision class members.
|
||||
* - Remove the scaling variable (What is it used for?)
|
||||
* - Remove the maxFov and sinMaxfov variables. Redundant since the fov is embedded
|
||||
* within the perspective projection matrix.
|
||||
* - Remove focusposition, part of the integration with the scale graph. The
|
||||
* "focus position" should not be needed since we assume the camera is always
|
||||
* positioned relative to its origin. When orbiting another object (not in origin),
|
||||
* the focus position should probably be handled outside the camera class
|
||||
* (interaction handler) since it does not affect the state of the camera
|
||||
* (only how it interacts).
|
||||
* - The class might need some more reasonable accessors depending on use cases.
|
||||
* (up vector world space?)
|
||||
* - Make clear which function returns a combined view matrix (things that are
|
||||
* dependent on the separate sgct nodes).
|
||||
*/
|
||||
class Camera {
|
||||
public:
|
||||
/**
|
||||
* Used to explicitly show which variables within the Camera class that are used
|
||||
* for caching.
|
||||
*/
|
||||
template<typename T>
|
||||
struct Cached {
|
||||
T datum = T(0);
|
||||
bool isDirty = true;
|
||||
};
|
||||
|
||||
Camera() = default;
|
||||
Camera(const Camera& o);
|
||||
~Camera() = default;
|
||||
|
||||
// Mutators
|
||||
void setPositionVec3(glm::dvec3 pos);
|
||||
void setRotation(glm::dquat rotation);
|
||||
void setScaling(float scaling);
|
||||
void setMaxFov(float fov);
|
||||
void setParent(SceneGraphNode* parent);
|
||||
|
||||
// Relative mutators
|
||||
void rotate(glm::dquat rotation);
|
||||
|
||||
// Accessors
|
||||
// Remove Vec3 from the name when psc is gone
|
||||
const glm::dvec3& positionVec3() const;
|
||||
glm::dvec3 eyePositionVec3() const;
|
||||
const glm::dvec3& unsynchedPositionVec3() const;
|
||||
const glm::dvec3& viewDirectionWorldSpace() const;
|
||||
const glm::dvec3& lookUpVectorCameraSpace() const;
|
||||
const glm::dvec3& lookUpVectorWorldSpace() const;
|
||||
const glm::dmat4& viewRotationMatrix() const;
|
||||
const glm::dmat4& viewScaleMatrix() const;
|
||||
const glm::dquat& rotationQuaternion() const;
|
||||
float maxFov() const;
|
||||
float sinMaxFov() const;
|
||||
SceneGraphNode* parent() const;
|
||||
float scaling() const;
|
||||
|
||||
// @TODO this should simply be called viewMatrix!
|
||||
// Or it needs to be changed so that it actually is combined. Right now it is
|
||||
// only the view matrix that is the same for all SGCT cameras.
|
||||
// Right now this function returns the actual combined matrix which makes some
|
||||
// of the old calls to the function wrong..
|
||||
const glm::dmat4& combinedViewMatrix() const;
|
||||
|
||||
void invalidateCache();
|
||||
|
||||
void serialize(std::ostream& os) const;
|
||||
void deserialize(std::istream& is);
|
||||
|
||||
/**
|
||||
* Handles SGCT's internal matrices. Also caches a calculated viewProjection
|
||||
* matrix. This is the data that is different for different cameras within SGCT.
|
||||
*/
|
||||
class SgctInternal {
|
||||
friend class Camera;
|
||||
public:
|
||||
void setSceneMatrix(glm::mat4 sceneMatrix);
|
||||
void setViewMatrix(glm::mat4 viewMatrix);
|
||||
void setProjectionMatrix(glm::mat4 projectionMatrix);
|
||||
|
||||
const glm::mat4& sceneMatrix() const;
|
||||
const glm::mat4& viewMatrix() const;
|
||||
const glm::mat4& projectionMatrix() const;
|
||||
const glm::mat4& viewProjectionMatrix() const;
|
||||
|
||||
private:
|
||||
SgctInternal() = default;
|
||||
SgctInternal(const SgctInternal& o);
|
||||
|
||||
glm::mat4 _sceneMatrix = glm::mat4(1.f);
|
||||
glm::mat4 _viewMatrix = glm::mat4(1.f);
|
||||
glm::mat4 _projectionMatrix = glm::mat4(1.f);
|
||||
|
||||
mutable Cached<glm::mat4> _cachedViewProjectionMatrix;
|
||||
mutable std::mutex _mutex;
|
||||
} sgctInternal;
|
||||
|
||||
// @TODO use Camera::SgctInternal interface instead
|
||||
// [[deprecated("Replaced by Camera::SgctInternal::viewMatrix()")]]
|
||||
const glm::mat4& viewMatrix() const;
|
||||
// [[deprecated("Replaced by Camera::SgctInternal::projectionMatrix()")]]
|
||||
const glm::mat4& projectionMatrix() const;
|
||||
// [[deprecated("Replaced by Camera::SgctInternal::viewProjectionMatrix()")]]
|
||||
const glm::mat4& viewProjectionMatrix() const;
|
||||
|
||||
std::vector<Syncable*> getSyncables();
|
||||
|
||||
// Static constants
|
||||
static const glm::dvec3 ViewDirectionCameraSpace;
|
||||
static const glm::dvec3 UpDirectionCameraSpace;
|
||||
|
||||
private:
|
||||
|
||||
SyncData<glm::dvec3> _position = glm::dvec3(1.0, 1.0, 1.0);
|
||||
SyncData<glm::dquat> _rotation = glm::dquat(glm::dvec3(1.0, 1.0, 1.0));
|
||||
SyncData<float> _scaling = 1.f;
|
||||
SceneGraphNode* _parent = nullptr;
|
||||
|
||||
// _focusPosition to be removed
|
||||
glm::dvec3 _focusPosition = glm::dvec3(0.0);
|
||||
float _maxFov = 0.f;
|
||||
|
||||
// Cached data
|
||||
mutable Cached<glm::dvec3> _cachedViewDirection;
|
||||
mutable Cached<glm::dvec3> _cachedLookupVector;
|
||||
mutable Cached<glm::dmat4> _cachedViewRotationMatrix;
|
||||
mutable Cached<glm::dmat4> _cachedViewScaleMatrix;
|
||||
mutable Cached<glm::dmat4> _cachedCombinedViewMatrix;
|
||||
mutable Cached<float> _cachedSinMaxFov;
|
||||
|
||||
mutable std::mutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___CAMERA___H__
|
||||
39
include/openspace/camera/camerapose.h
Normal file
39
include/openspace/camera/camerapose.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___CAMERAPOSE___H__
|
||||
#define __OPENSPACE_CORE___CAMERAPOSE___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct CameraPose {
|
||||
glm::dvec3 position = glm::dvec3(0.0);
|
||||
glm::dquat rotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___CAMERAPOSE___H__
|
||||
@@ -26,7 +26,7 @@
|
||||
#define __OPENSPACE_CORE___SESSIONRECORDING___H__
|
||||
|
||||
#include <openspace/interaction/externinteraction.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <vector>
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef __OPENSPACE_CORE___KEYFRAMENAVIGATOR___H__
|
||||
#define __OPENSPACE_CORE___KEYFRAMENAVIGATOR___H__
|
||||
|
||||
#include <openspace/util/timeline.h>
|
||||
#include <openspace/network/messagestructures.h>
|
||||
#include <openspace/util/timeline.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/misc/boolean.h>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
@@ -28,10 +28,12 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/joystickcamerastates.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/interaction/websocketcamerastates.h>
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/util/mouse.h>
|
||||
@@ -48,31 +50,14 @@ namespace openspace::scripting { struct LuaLibrary; }
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct JoystickInputStates;
|
||||
struct NavigationState;
|
||||
struct WebsocketInputStates;
|
||||
class KeyframeNavigator;
|
||||
class OrbitalNavigator;
|
||||
class PathNavigator;
|
||||
|
||||
class NavigationHandler : public properties::PropertyOwner {
|
||||
public:
|
||||
struct NavigationState {
|
||||
NavigationState() = default;
|
||||
NavigationState(const ghoul::Dictionary& dictionary);
|
||||
NavigationState(std::string anchor, std::string aim, std::string referenceFrame,
|
||||
glm::dvec3 position, std::optional<glm::dvec3> up = std::nullopt,
|
||||
double yaw = 0.0, double pitch = 0.0);
|
||||
|
||||
ghoul::Dictionary dictionary() const;
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
std::string anchor;
|
||||
std::string aim;
|
||||
std::string referenceFrame;
|
||||
glm::dvec3 position = glm::dvec3(0.0);
|
||||
std::optional<glm::dvec3> up;
|
||||
double yaw = 0.0;
|
||||
double pitch = 0.0;
|
||||
};
|
||||
|
||||
NavigationHandler();
|
||||
~NavigationHandler();
|
||||
|
||||
@@ -80,11 +65,9 @@ public:
|
||||
void deinitialize();
|
||||
|
||||
// Mutators
|
||||
|
||||
void setFocusNode(SceneGraphNode* node);
|
||||
void resetCameraDirection();
|
||||
|
||||
void setNavigationStateNextFame(NavigationState state);
|
||||
void setCamera(Camera* camera);
|
||||
void setInterpolationTime(float durationInSeconds);
|
||||
|
||||
@@ -101,6 +84,7 @@ public:
|
||||
const OrbitalNavigator& orbitalNavigator() const;
|
||||
OrbitalNavigator& orbitalNavigator();
|
||||
KeyframeNavigator& keyframeNavigator();
|
||||
PathNavigator& pathNavigator();
|
||||
bool isKeyFrameInteractionEnabled() const;
|
||||
float interpolationTime() const;
|
||||
|
||||
@@ -154,7 +138,7 @@ public:
|
||||
static scripting::LuaLibrary luaLibrary();
|
||||
|
||||
private:
|
||||
void applyNavigationState(const NavigationHandler::NavigationState& ns);
|
||||
void applyNavigationState(const NavigationState& ns);
|
||||
|
||||
bool _playbackModeEnabled = false;
|
||||
|
||||
@@ -164,6 +148,7 @@ private:
|
||||
|
||||
OrbitalNavigator _orbitalNavigator;
|
||||
KeyframeNavigator _keyframeNavigator;
|
||||
PathNavigator _pathNavigator;
|
||||
|
||||
std::optional<NavigationState> _pendingNavigationState;
|
||||
|
||||
59
include/openspace/navigation/navigationstate.h
Normal file
59
include/openspace/navigation/navigationstate.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___NAVIGATIONSTATE___H__
|
||||
#define __OPENSPACE_CORE___NAVIGATIONSTATE___H__
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <optional>
|
||||
|
||||
namespace openspace {
|
||||
struct CameraPose;
|
||||
} // namespace openspace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct NavigationState {
|
||||
NavigationState() = default;
|
||||
NavigationState(const ghoul::Dictionary& dictionary);
|
||||
NavigationState(std::string anchor, std::string aim, std::string referenceFrame,
|
||||
glm::dvec3 position, std::optional<glm::dvec3> up = std::nullopt,
|
||||
double yaw = 0.0, double pitch = 0.0);
|
||||
|
||||
CameraPose cameraPose() const;
|
||||
ghoul::Dictionary dictionary() const;
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
std::string anchor;
|
||||
std::string aim;
|
||||
std::string referenceFrame;
|
||||
glm::dvec3 position = glm::dvec3(0.0);
|
||||
std::optional<glm::dvec3> up;
|
||||
double yaw = 0.0;
|
||||
double pitch = 0.0;
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___NAVIGATIONSTATE___H__
|
||||
@@ -46,6 +46,7 @@
|
||||
namespace openspace {
|
||||
class SceneGraphNode;
|
||||
class Camera;
|
||||
struct CameraPose;
|
||||
struct SurfacePositionHandle;
|
||||
} // namespace
|
||||
|
||||
@@ -104,11 +105,6 @@ private:
|
||||
glm::dquat globalRotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
|
||||
};
|
||||
|
||||
struct CameraPose {
|
||||
glm::dvec3 position = glm::dvec3(0.0);
|
||||
glm::dquat rotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
|
||||
};
|
||||
|
||||
using Displacement = std::pair<glm::dvec3, glm::dvec3>;
|
||||
|
||||
struct Friction : public properties::PropertyOwner {
|
||||
83
include/openspace/navigation/path.h
Normal file
83
include/openspace/navigation/path.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___PATH___H__
|
||||
#define __OPENSPACE_CORE___PATH___H__
|
||||
|
||||
#include <openspace/navigation/pathcurve.h>
|
||||
#include <openspace/navigation/waypoint.h>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
struct CameraPose;
|
||||
} // namespace openspace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
class Path {
|
||||
public:
|
||||
enum CurveType {
|
||||
AvoidCollision,
|
||||
Linear,
|
||||
ZoomOutOverview
|
||||
};
|
||||
|
||||
Path(Waypoint start, Waypoint end, CurveType type,
|
||||
std::optional<double> duration = std::nullopt);
|
||||
|
||||
Waypoint startPoint() const;
|
||||
Waypoint endPoint() const;
|
||||
double duration() const;
|
||||
double pathLength() const;
|
||||
|
||||
std::vector<glm::dvec3> controlPoints() const;
|
||||
|
||||
CameraPose traversePath(double dt);
|
||||
std::string currentAnchor() const;
|
||||
bool hasReachedEnd() const;
|
||||
|
||||
CameraPose interpolatedPose(double distance) const;
|
||||
|
||||
private:
|
||||
glm::dquat interpolateRotation(double u) const;
|
||||
double speedAlongPath(double traveledDistance);
|
||||
|
||||
Waypoint _start;
|
||||
Waypoint _end;
|
||||
double _duration;
|
||||
CurveType _curveType;
|
||||
|
||||
std::unique_ptr<PathCurve> _curve;
|
||||
|
||||
double _speedFactorFromDuration = 1.0;
|
||||
|
||||
// Playback variables
|
||||
double _traveledDistance = 0.0;
|
||||
double _progressedTime = 0.0; // Time since playback started
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___PATH___H__
|
||||
63
include/openspace/navigation/pathcreator.h
Normal file
63
include/openspace/navigation/pathcreator.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___PATHCREATOR___H__
|
||||
#define __OPENSPACE_CORE___PATHCREATOR___H__
|
||||
|
||||
#include <openspace/navigation/path.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
namespace openspace { class SceneGraphNode; }
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct Waypoint;
|
||||
|
||||
class PathCreator {
|
||||
public:
|
||||
// Create a path from a dictionary containing the instruction
|
||||
static Path createPath(const ghoul::Dictionary& dictionary,
|
||||
Path::CurveType curveType);
|
||||
|
||||
private:
|
||||
struct NodeInfo {
|
||||
std::string identifier;
|
||||
std::optional<glm::dvec3> position;
|
||||
std::optional<double> height;
|
||||
bool useTargetUpDirection;
|
||||
};
|
||||
|
||||
static Waypoint waypointFromCamera();
|
||||
static Waypoint computeDefaultWaypoint(const NodeInfo& info,
|
||||
const Waypoint& startPoint);
|
||||
|
||||
// Test if the node lies within a given proximity radius of any relevant node
|
||||
// in the scene
|
||||
static SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node);
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___PATHCREATOR___H__
|
||||
81
include/openspace/navigation/pathcurve.h
Normal file
81
include/openspace/navigation/pathcurve.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___PATHCURVE___H__
|
||||
#define __OPENSPACE_CORE___PATHCURVE___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct Waypoint;
|
||||
|
||||
class PathCurve {
|
||||
public:
|
||||
virtual ~PathCurve() = 0;
|
||||
|
||||
const double length() const;
|
||||
glm::dvec3 positionAt(double relativeDistance);
|
||||
|
||||
// Compute curve parameter u that matches the input arc length s
|
||||
double curveParameter(double s);
|
||||
|
||||
virtual glm::dvec3 interpolate(double u);
|
||||
|
||||
std::vector<glm::dvec3> points();
|
||||
|
||||
protected:
|
||||
// Precompute information related to the pspline parameters, that are
|
||||
// needed for arc length reparameterization. Must be called after
|
||||
// control point creation
|
||||
void initializeParameterData();
|
||||
|
||||
double approximatedDerivative(double u, double h = 0.0001);
|
||||
double arcLength(double limit = 1.0);
|
||||
double arcLength(double lowerLimit, double upperLimit);
|
||||
|
||||
std::vector<glm::dvec3> _points;
|
||||
unsigned int _nSegments;
|
||||
|
||||
std::vector<double> _curveParameterSteps; // per segment
|
||||
std::vector<double> _lengthSums; // per segment
|
||||
double _totalLength;
|
||||
|
||||
struct ParameterPair {
|
||||
double u; // curve parameter
|
||||
double s; // arc length parameter
|
||||
};
|
||||
|
||||
std::vector<ParameterPair> _parameterSamples;
|
||||
};
|
||||
|
||||
class LinearCurve : public PathCurve {
|
||||
public:
|
||||
LinearCurve(const Waypoint& start, const Waypoint& end);
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___PATHCURVE___H__
|
||||
@@ -0,0 +1,48 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___AVOIDCOLLISIONCURVE___H__
|
||||
#define __OPENSPACE_CORE___AVOIDCOLLISIONCURVE___H__
|
||||
|
||||
#include <openspace/navigation/pathcurve.h>
|
||||
|
||||
namespace openspace { class SceneGraphNode; }
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct WayPoint;
|
||||
|
||||
class AvoidCollisionCurve : public PathCurve {
|
||||
public:
|
||||
AvoidCollisionCurve(const Waypoint& start, const Waypoint& end);
|
||||
|
||||
private:
|
||||
void removeCollisions(int step = 0);
|
||||
|
||||
std::vector<SceneGraphNode*> _relevantNodes;
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_MODULE_AUTONAVIGATION___AVOIDCOLLISIONCURVE___H__
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___ZOOMOUTOVERVIEWCURVE___H__
|
||||
#define __OPENSPACE_CORE___ZOOMOUTOVERVIEWCURVE___H__
|
||||
|
||||
#include <openspace/navigation/pathcurve.h>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct WayPoint;
|
||||
|
||||
class ZoomOutOverviewCurve : public PathCurve {
|
||||
public:
|
||||
ZoomOutOverviewCurve(const Waypoint& start, const Waypoint& end);
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___ZOOMOUTOVERVIEWCURVE___H__
|
||||
83
include/openspace/navigation/pathhelperfunctions.h
Normal file
83
include/openspace/navigation/pathhelperfunctions.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___PATHHELPERFUNCTIONS___H__
|
||||
#define __OPENSPACE_CORE___PATHHELPERFUNCTIONS___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::interaction::helpers {
|
||||
|
||||
// Make interpolator parameter t [0,1] progress only inside a subinterval
|
||||
double shiftAndScale(double t, double newStart, double newEnd);
|
||||
|
||||
glm::dquat lookAtQuaternion(glm::dvec3 eye, glm::dvec3 center, glm::dvec3 up);
|
||||
|
||||
glm::dvec3 viewDirection(const glm::dquat& q);
|
||||
|
||||
bool lineSphereIntersection(glm::dvec3 linePoint1, glm::dvec3 linePoint2,
|
||||
glm::dvec3 sphereCenter, double spehereRadius, glm::dvec3& intersectionPoint);
|
||||
|
||||
bool isPointInsideSphere(const glm::dvec3& p, const glm::dvec3& c, double r);
|
||||
|
||||
double simpsonsRule(double t0, double t1, int n, std::function<double(double)> f);
|
||||
|
||||
double fivePointGaussianQuadrature(double t0, double t1,
|
||||
std::function<double(double)> f);
|
||||
} // namespace openspace::interaction::helpers
|
||||
|
||||
namespace openspace::interaction::interpolation {
|
||||
|
||||
glm::dquat easedSlerp(const glm::dquat q1, const glm::dquat q2, double t);
|
||||
|
||||
// TODO: make all these into template functions.
|
||||
// Alternatively, add cubicBezier interpolation in ghoul and only use
|
||||
// ghoul's interpolator methods
|
||||
|
||||
// Centripetal version alpha = 0, uniform for alpha = 0.5 and chordal for alpha = 1
|
||||
glm::dvec3 catmullRom(double t, const glm::dvec3& p0, const glm::dvec3& p1,
|
||||
const glm::dvec3& p2, const glm::dvec3& p3, double alpha = 0.5);
|
||||
|
||||
glm::dvec3 cubicBezier(double t, const glm::dvec3& cp1, const glm::dvec3& cp2,
|
||||
const glm::dvec3& cp3, const glm::dvec3& cp4);
|
||||
|
||||
glm::dvec3 linear(double t, const glm::dvec3& cp1, const glm::dvec3& cp2);
|
||||
|
||||
glm::dvec3 hermite(double t, const glm::dvec3 &cp1, const glm::dvec3 &cp2,
|
||||
const glm::dvec3 &tangent1, const glm::dvec3 &tangent2);
|
||||
|
||||
glm::dvec3 piecewiseCubicBezier(double t, const std::vector<glm::dvec3>& points,
|
||||
const std::vector<double>& tKnots);
|
||||
|
||||
glm::dvec3 piecewiseLinear(double t, const std::vector<glm::dvec3>& points,
|
||||
const std::vector<double>& tKnots);
|
||||
|
||||
} // namespace openspace::interaction::interpolation
|
||||
#endif // __OPENSPACE_CORE___PATHHELPERFUNCTIONS___H__
|
||||
121
include/openspace/navigation/pathnavigator.h
Normal file
121
include/openspace/navigation/pathnavigator.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___PATHNAVIGATOR___H__
|
||||
#define __OPENSPACE_CORE___PATHNAVIGATOR___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/navigation/path.h>
|
||||
#include <openspace/properties/list/stringlistproperty.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/doubleproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <memory>
|
||||
|
||||
namespace openspace {
|
||||
class Camera;
|
||||
struct CameraPose;
|
||||
class SceneGraphNode;
|
||||
} // namespace openspace
|
||||
|
||||
namespace openspace::scripting { struct LuaLibrary; }
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
class Path;
|
||||
|
||||
class PathNavigator : public properties::PropertyOwner {
|
||||
public:
|
||||
enum StopBehavior {
|
||||
None = 0,
|
||||
Orbit
|
||||
};
|
||||
|
||||
PathNavigator();
|
||||
~PathNavigator();
|
||||
|
||||
// Accessors
|
||||
Camera* camera() const;
|
||||
const SceneGraphNode* anchor() const;
|
||||
double speedScale() const;
|
||||
|
||||
bool hasCurrentPath() const;
|
||||
bool hasFinished() const;
|
||||
bool isPlayingPath() const;
|
||||
|
||||
void updateCamera(double deltaTime);
|
||||
void createPath(const ghoul::Dictionary& dictionary);
|
||||
void clearPath();
|
||||
void startPath();
|
||||
void abortPath();
|
||||
void pausePath();
|
||||
void continuePath();
|
||||
|
||||
// TODO: remove functions for debugging
|
||||
std::vector<glm::dvec3> curvePositions(int nSteps) const;
|
||||
std::vector<glm::dquat> curveOrientations(int nSteps) const;
|
||||
std::vector<glm::dvec3> curveViewDirections(int nSteps) const;
|
||||
std::vector<glm::dvec3> controlPoints() const;
|
||||
|
||||
double minValidBoundingSphere() const;
|
||||
const std::vector<SceneGraphNode*>& relevantNodes();
|
||||
|
||||
/**
|
||||
* \return The Lua library that contains all Lua functions available to affect the
|
||||
* path navigation
|
||||
*/
|
||||
static scripting::LuaLibrary luaLibrary();
|
||||
|
||||
private:
|
||||
void findRelevantNodes();
|
||||
|
||||
void removeRollRotation(CameraPose& pose, double deltaTime);
|
||||
void applyStopBehavior(double deltaTime);
|
||||
|
||||
void orbitAnchorNode(double deltaTime);
|
||||
|
||||
std::unique_ptr<Path> _currentPath = nullptr;
|
||||
bool _isPlaying = false;
|
||||
|
||||
properties::OptionProperty _defaultCurveOption;
|
||||
properties::BoolProperty _includeRoll;
|
||||
properties::FloatProperty _speedScale;
|
||||
properties::FloatProperty _orbitSpeedFactor;
|
||||
|
||||
properties::BoolProperty _applyStopBehaviorWhenIdle;
|
||||
properties::OptionProperty _stopBehavior;
|
||||
|
||||
properties::DoubleProperty _minValidBoundingSphere;
|
||||
properties::StringListProperty _relevantNodeTags;
|
||||
|
||||
std::vector<SceneGraphNode*> _relevantNodes;
|
||||
bool _hasInitializedRelevantNodes = false;
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___PATHNAVIGATOR___H__
|
||||
55
include/openspace/navigation/waypoint.h
Normal file
55
include/openspace/navigation/waypoint.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___WAYPOINT___H__
|
||||
#define __OPENSPACE_CORE___WAYPOINT___H__
|
||||
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace { class SceneGraphNode; }
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct NavigationState;
|
||||
|
||||
struct Waypoint {
|
||||
Waypoint() = default;
|
||||
Waypoint(const glm::dvec3& pos, const glm::dquat& rot, const std::string& ref);
|
||||
Waypoint(const NavigationState& ns);
|
||||
|
||||
static double findValidBoundingSphere(const SceneGraphNode* node);
|
||||
|
||||
glm::dvec3 position() const;
|
||||
glm::dquat rotation() const;
|
||||
SceneGraphNode* node() const;
|
||||
|
||||
CameraPose pose;
|
||||
std::string nodeIdentifier;
|
||||
double validBoundingSphere = 0.0; // to be able to handle nodes with faulty bounding spheres
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___WAYPOINT___H__
|
||||
@@ -26,9 +26,9 @@
|
||||
#define __OPENSPACE_CORE___PROFILE___H__
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/util/keys.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace interaction { struct NavigationState; }
|
||||
|
||||
namespace scripting { struct LuaLibrary; }
|
||||
|
||||
class Profile {
|
||||
@@ -127,8 +129,7 @@ public:
|
||||
* and all of the property & asset changes that were made since startup.
|
||||
*/
|
||||
void saveCurrentSettingsToProfile(const properties::PropertyOwner& rootOwner,
|
||||
std::string currentTime,
|
||||
interaction::NavigationHandler::NavigationState navState);
|
||||
std::string currentTime, interaction::NavigationState navState);
|
||||
|
||||
/// If the value passed to this function is 'true', the addAsset and removeAsset
|
||||
/// functions will be no-ops instead
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#ifndef __OPENSPACE_CORE___SCRIPTSCHEDULER___H__
|
||||
#define __OPENSPACE_CORE___SCRIPTSCHEDULER___H__
|
||||
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef __OPENSPACE_CORE___UPDATESTRUCTURES___H__
|
||||
#define __OPENSPACE_CORE___UPDATESTRUCTURES___H__
|
||||
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/camera.h>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <modules/autonavigation/waypoint.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/util/camera.h>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <modules/autonavigation/helperfunctions.h>
|
||||
#include <modules/autonavigation/pathcreator.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef __OPENSPACE_MODULE_AUTONAVIGATION___WAYPOINT___H__
|
||||
#define __OPENSPACE_MODULE_AUTONAVIGATION___WAYPOINT___H__
|
||||
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace::pathnavigation {
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
|
||||
#include <modules/base/dashboard/dashboarditemangle.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <ghoul/font/font.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
|
||||
#include <modules/base/dashboard/dashboarditemdistance.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/distanceconversion.h>
|
||||
#include <ghoul/font/font.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
|
||||
@@ -24,15 +24,14 @@
|
||||
|
||||
#include <modules/base/dashboard/dashboarditemvelocity.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/distanceconversion.h>
|
||||
#include <ghoul/font/font.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#include <modules/base/basemodule.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/translation.h>
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <modules/exoplanets/tasks/exoplanetsdatapreparationtask.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
@@ -37,8 +37,9 @@
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -597,7 +598,7 @@ void GlobeBrowsingModule::goToGeodetic3(const globebrowsing::RenderableGlobe& gl
|
||||
Geodetic2{ geo3.geodetic2.lat + 0.001, geo3.geodetic2.lon }
|
||||
);
|
||||
|
||||
interaction::NavigationHandler::NavigationState state;
|
||||
interaction::NavigationState state;
|
||||
state.anchor = globe.owner()->identifier();
|
||||
state.referenceFrame = globe.owner()->identifier();
|
||||
state.position = positionModelSpace;
|
||||
|
||||
@@ -27,15 +27,15 @@
|
||||
#include <modules/globebrowsing/src/layer.h>
|
||||
#include <modules/globebrowsing/src/layergroup.h>
|
||||
#include <modules/globebrowsing/src/layermanager.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace openspace::globebrowsing::luascriptfunctions {
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/distanceconversion.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
@@ -26,17 +26,14 @@
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/triggerproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
@@ -34,7 +35,6 @@
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/vector/vec2property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#include <openspace/engine/virtualpropertymanager.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/rendering/dashboard.h>
|
||||
#include <openspace/rendering/luaconsole.h>
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#include <modules/imgui/include/imgui_include.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <modules/imgui/include/imgui_include.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/joystickinputstate.h>
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
|
||||
#include <modules/imgui/include/imgui_include.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/network/messagestructures.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
|
||||
#include <ghoul/fmt.h>
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
#include <modules/imgui/include/imgui_include.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/websocketcamerastates.h>
|
||||
#include <openspace/interaction/websocketinputstate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/virtualpropertymanager.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/luaconsole.h>
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/interactionmonitor.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/set_openspace_compile_settings.cmake)
|
||||
|
||||
set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/openspace.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/camera/camera.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/documentation/core_registration.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/documentation/documentation.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/documentation/documentationengine.cpp
|
||||
@@ -49,11 +50,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/joystickcamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/keybindingmanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/keybindingmanager_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/keyframenavigator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/navigationhandler.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/navigationhandler_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/mousecamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/orbitalnavigator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/scriptcamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/externinteraction.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/sessionrecording.cpp
|
||||
@@ -67,6 +64,20 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/mission/mission.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/mission/missionmanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/mission/missionmanager_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathcurves/avoidcollisioncurve.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathcurves/zoomoutoverviewcurve.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/keyframenavigator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/navigationhandler.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/navigationhandler_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/navigationstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/orbitalnavigator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/path.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathcreator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathcurve.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathhelperfunctions.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathnavigator.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/pathnavigator_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/navigation/waypoint.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/network/parallelconnection.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/network/parallelpeer.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/network/parallelpeer_lua.inl
|
||||
@@ -151,7 +162,6 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/scripting/systemcapabilitiesbinding.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/blockplaneintersectiongeometry.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/boxgeometry.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/camera.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/coordinateconversion.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/distanceconversion.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/factorymanager.cpp
|
||||
@@ -195,6 +205,8 @@ if (APPLE)
|
||||
endif ()
|
||||
set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/json.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/camera/camera.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/camera/camerapose.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/documentation/core_registration.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/documentation/documentation.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/documentation/documentationengine.h
|
||||
@@ -222,10 +234,7 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/joystickinputstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/joystickcamerastates.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/keybindingmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/keyframenavigator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/mousecamerastates.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/navigationhandler.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/orbitalnavigator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/externinteraction.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/scriptcamerastates.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/sessionrecording.h
|
||||
@@ -237,6 +246,18 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/tasks/convertrecformattask.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/mission/mission.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/mission/missionmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathcurves/avoidcollisioncurve.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathcurves/zoomoutoverviewcurve.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/keyframenavigator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/navigationhandler.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/navigationstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/orbitalnavigator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/path.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathcreator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathcurve.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathhelperfunctions.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/pathnavigator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/navigation/waypoint.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/parallelpeer.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/parallelserver.h
|
||||
@@ -325,7 +346,6 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scripting/systemcapabilitiesbinding.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/blockplaneintersectiongeometry.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/boxgeometry.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/camera.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentjobmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentjobmanager.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/concurrentqueue.h
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@@ -28,12 +28,13 @@
|
||||
#include <openspace/engine/logfactory.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/keybindingmanager.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/interaction/shortcutmanager.h>
|
||||
#include <openspace/mission/mission.h>
|
||||
#include <openspace/mission/missionmanager.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/rendering/dashboard.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
@@ -59,9 +60,7 @@ namespace openspace {
|
||||
void registerCoreClasses(documentation::DocumentationEngine& engine) {
|
||||
engine.addDocumentation(LogFactoryDocumentation());
|
||||
engine.addDocumentation(Mission::Documentation());
|
||||
engine.addDocumentation(
|
||||
interaction::NavigationHandler::NavigationState::Documentation()
|
||||
);
|
||||
engine.addDocumentation(interaction::NavigationState::Documentation());
|
||||
engine.addDocumentation(Renderable::Documentation());
|
||||
engine.addDocumentation(Rotation::Documentation());
|
||||
engine.addDocumentation(Scale::Documentation());
|
||||
@@ -89,6 +88,7 @@ void registerCoreClasses(scripting::ScriptEngine& engine) {
|
||||
engine.addLibrary(Time::luaLibrary());
|
||||
engine.addLibrary(interaction::KeybindingManager::luaLibrary());
|
||||
engine.addLibrary(interaction::NavigationHandler::luaLibrary());
|
||||
engine.addLibrary(interaction::PathNavigator::luaLibrary());
|
||||
engine.addLibrary(interaction::SessionRecording::luaLibrary());
|
||||
engine.addLibrary(interaction::ShortcutManager::luaLibrary());
|
||||
engine.addLibrary(scripting::ScriptScheduler::luaLibrary());
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
#include <openspace/interaction/keybindingmanager.h>
|
||||
#include <openspace/interaction/joystickinputstate.h>
|
||||
#include <openspace/interaction/websocketinputstate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/interaction/shortcutmanager.h>
|
||||
#include <openspace/mission/missionmanager.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/rendering/dashboard.h>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
#include <openspace/openspace.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/core_registration.h>
|
||||
#include <openspace/documentation/documentationengine.h>
|
||||
#include <openspace/engine/configuration.h>
|
||||
@@ -38,8 +39,8 @@
|
||||
#include <openspace/interaction/interactionmonitor.h>
|
||||
#include <openspace/interaction/keybindingmanager.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/rendering/dashboard.h>
|
||||
#include <openspace/rendering/dashboarditem.h>
|
||||
@@ -60,7 +61,6 @@
|
||||
#include <openspace/scene/scenelicensewriter.h>
|
||||
#include <openspace/scripting/scriptscheduler.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/memorymanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
#include <openspace/interaction/externinteraction.h>
|
||||
|
||||
#include <openspace/openspace.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
|
||||
|
||||
@@ -24,20 +24,20 @@
|
||||
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/interaction/tasks/convertrecfileversiontask.h>
|
||||
#include <openspace/interaction/tasks/convertrecformattask.h>
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/rendering/luaconsole.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/scripting/scriptscheduler.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
@@ -22,16 +22,16 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -66,102 +66,12 @@ namespace {
|
||||
"If this is set to 'true' the entire interaction is based off key frames rather "
|
||||
"than using the mouse interaction."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(NavigationHandler)]] Parameters {
|
||||
// The identifier of the anchor node
|
||||
std::string anchor;
|
||||
|
||||
// The identifier of the aim node, if used
|
||||
std::optional<std::string> aim;
|
||||
|
||||
// The identifier of the scene graph node to use as reference frame. If not
|
||||
// specified, this will be the same as the anchor
|
||||
std::optional<std::string> referenceFrame;
|
||||
|
||||
// The position of the camera relative to the anchor node, expressed in meters in
|
||||
// the specified reference frame
|
||||
glm::dvec3 position;
|
||||
|
||||
// The up vector expressed in the coordinate system of the reference frame
|
||||
std::optional<glm::dvec3> up;
|
||||
|
||||
// The yaw angle in radians. Positive angle means yawing camera to the right
|
||||
std::optional<double> yaw;
|
||||
|
||||
// The pitch angle in radians. Positive angle means pitching camera upwards
|
||||
std::optional<double> pitch;
|
||||
};
|
||||
#include "navigationhandler_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
#include "navigationhandler_lua.inl"
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
ghoul::Dictionary NavigationHandler::NavigationState::dictionary() const {
|
||||
constexpr const char* KeyAnchor = "Anchor";
|
||||
constexpr const char* KeyAim = "Aim";
|
||||
constexpr const char* KeyPosition = "Position";
|
||||
constexpr const char* KeyUp = "Up";
|
||||
constexpr const char* KeyYaw = "Yaw";
|
||||
constexpr const char* KeyPitch = "Pitch";
|
||||
constexpr const char* KeyReferenceFrame = "ReferenceFrame";
|
||||
|
||||
ghoul::Dictionary cameraDict;
|
||||
cameraDict.setValue(KeyPosition, position);
|
||||
cameraDict.setValue(KeyAnchor, anchor);
|
||||
|
||||
if (anchor != referenceFrame) {
|
||||
cameraDict.setValue(KeyReferenceFrame, referenceFrame);
|
||||
}
|
||||
if (!aim.empty()) {
|
||||
cameraDict.setValue(KeyAim, aim);
|
||||
}
|
||||
if (up.has_value()) {
|
||||
cameraDict.setValue(KeyUp, *up);
|
||||
|
||||
if (std::abs(yaw) > Epsilon) {
|
||||
cameraDict.setValue(KeyYaw, yaw);
|
||||
}
|
||||
if (std::abs(pitch) > Epsilon) {
|
||||
cameraDict.setValue(KeyPitch, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
return cameraDict;
|
||||
}
|
||||
|
||||
NavigationHandler::NavigationState::NavigationState(const ghoul::Dictionary& dictionary) {
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
anchor = p.anchor;
|
||||
position = p.position;
|
||||
|
||||
referenceFrame = p.referenceFrame.value_or(anchor);
|
||||
aim = p.aim.value_or(aim);
|
||||
|
||||
if (p.up.has_value()) {
|
||||
up = *p.up;
|
||||
|
||||
yaw = p.yaw.value_or(yaw);
|
||||
pitch = p.pitch.value_or(pitch);
|
||||
}
|
||||
}
|
||||
|
||||
NavigationHandler::NavigationState::NavigationState(std::string anchor_, std::string aim_,
|
||||
std::string referenceFrame_,
|
||||
glm::dvec3 position_,
|
||||
std::optional<glm::dvec3> up_,
|
||||
double yaw_, double pitch_)
|
||||
: anchor(std::move(anchor_))
|
||||
, aim(std::move(aim_))
|
||||
, referenceFrame(std::move(referenceFrame_))
|
||||
, position(std::move(position_))
|
||||
, up(std::move(up_))
|
||||
, yaw(yaw_)
|
||||
, pitch(pitch_)
|
||||
{}
|
||||
|
||||
NavigationHandler::NavigationHandler()
|
||||
: properties::PropertyOwner({ "NavigationHandler" })
|
||||
, _disableMouseInputs(KeyDisableMouseInputInfo, false)
|
||||
@@ -169,6 +79,7 @@ NavigationHandler::NavigationHandler()
|
||||
, _useKeyFrameInteraction(KeyFrameInfo, false)
|
||||
{
|
||||
addPropertySubOwner(_orbitalNavigator);
|
||||
addPropertySubOwner(_pathNavigator);
|
||||
|
||||
addProperty(_disableMouseInputs);
|
||||
addProperty(_disableJoystickInputs);
|
||||
@@ -210,8 +121,7 @@ void NavigationHandler::setCamera(Camera* camera) {
|
||||
_orbitalNavigator.setCamera(camera);
|
||||
}
|
||||
|
||||
void NavigationHandler::setNavigationStateNextFrame(
|
||||
NavigationHandler::NavigationState state)
|
||||
void NavigationHandler::setNavigationStateNextFrame(NavigationState state)
|
||||
{
|
||||
_pendingNavigationState = std::move(state);
|
||||
}
|
||||
@@ -228,6 +138,10 @@ KeyframeNavigator& NavigationHandler::keyframeNavigator() {
|
||||
return _keyframeNavigator;
|
||||
}
|
||||
|
||||
PathNavigator& NavigationHandler::pathNavigator() {
|
||||
return _pathNavigator;
|
||||
}
|
||||
|
||||
bool NavigationHandler::isKeyFrameInteractionEnabled() const {
|
||||
return _useKeyFrameInteraction;
|
||||
}
|
||||
@@ -252,6 +166,9 @@ void NavigationHandler::updateCamera(double deltaTime) {
|
||||
if (_useKeyFrameInteraction) {
|
||||
_keyframeNavigator.updateCamera(*_camera, _playbackModeEnabled);
|
||||
}
|
||||
else if (_pathNavigator.isPlayingPath()) {
|
||||
_pathNavigator.updateCamera(deltaTime);
|
||||
}
|
||||
else {
|
||||
if (_disableJoystickInputs) {
|
||||
std::fill(
|
||||
@@ -264,67 +181,21 @@ void NavigationHandler::updateCamera(double deltaTime) {
|
||||
_orbitalNavigator.updateCameraStateFromStates(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
// If session recording (playback mode) was started in the midst of a camera path,
|
||||
// abort the path
|
||||
if (_playbackModeEnabled && _pathNavigator.isPlayingPath()) {
|
||||
_pathNavigator.abortPath();
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationHandler::applyNavigationState(const NavigationHandler::NavigationState& ns)
|
||||
{
|
||||
const SceneGraphNode* referenceFrame = sceneGraphNode(ns.referenceFrame);
|
||||
const SceneGraphNode* anchor = sceneGraphNode(ns.anchor);
|
||||
|
||||
if (!anchor) {
|
||||
LERROR(fmt::format(
|
||||
"Could not find scene graph node '{}' used as anchor.", ns.referenceFrame
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (!ns.aim.empty() && !sceneGraphNode(ns.aim)) {
|
||||
LERROR(fmt::format(
|
||||
"Could not find scene graph node '{}' used as aim.", ns.referenceFrame
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (!referenceFrame) {
|
||||
LERROR(fmt::format(
|
||||
"Could not find scene graph node '{}' used as reference frame.",
|
||||
ns.referenceFrame)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const glm::dvec3 anchorWorldPosition = anchor->worldPosition();
|
||||
const glm::dmat3 referenceFrameTransform = referenceFrame->worldRotationMatrix();
|
||||
|
||||
void NavigationHandler::applyNavigationState(const NavigationState& ns) {
|
||||
_orbitalNavigator.setAnchorNode(ns.anchor);
|
||||
_orbitalNavigator.setAimNode(ns.aim);
|
||||
|
||||
const SceneGraphNode* anchorNode = _orbitalNavigator.anchorNode();
|
||||
const SceneGraphNode* aimNode = _orbitalNavigator.aimNode();
|
||||
if (!aimNode) {
|
||||
aimNode = anchorNode;
|
||||
}
|
||||
|
||||
const glm::dvec3 cameraPositionWorld = anchorWorldPosition +
|
||||
referenceFrameTransform * glm::dvec4(ns.position, 1.0);
|
||||
|
||||
glm::dvec3 up = ns.up.has_value() ?
|
||||
glm::normalize(referenceFrameTransform * *ns.up) :
|
||||
glm::dvec3(0.0, 1.0, 0.0);
|
||||
|
||||
// Construct vectors of a "neutral" view, i.e. when the aim is centered in view.
|
||||
glm::dvec3 neutralView =
|
||||
glm::normalize(aimNode->worldPosition() - cameraPositionWorld);
|
||||
|
||||
glm::dquat neutralCameraRotation = glm::inverse(glm::quat_cast(glm::lookAt(
|
||||
glm::dvec3(0.0),
|
||||
neutralView,
|
||||
up
|
||||
)));
|
||||
|
||||
glm::dquat pitchRotation = glm::angleAxis(ns.pitch, glm::dvec3(1.0, 0.0, 0.0));
|
||||
glm::dquat yawRotation = glm::angleAxis(ns.yaw, glm::dvec3(0.0, -1.0, 0.0));
|
||||
|
||||
_camera->setPositionVec3(cameraPositionWorld);
|
||||
_camera->setRotation(neutralCameraRotation * yawRotation * pitchRotation);
|
||||
CameraPose pose = ns.cameraPose();
|
||||
_camera->setPositionVec3(pose.position);
|
||||
_camera->setRotation(pose.rotation);
|
||||
_orbitalNavigator.clearPreviousState();
|
||||
}
|
||||
|
||||
@@ -383,7 +254,7 @@ void NavigationHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActio
|
||||
_inputState.keyboardCallback(key, modifier, action);
|
||||
}
|
||||
|
||||
NavigationHandler::NavigationState NavigationHandler::navigationState() const {
|
||||
NavigationState NavigationHandler::navigationState() const {
|
||||
const SceneGraphNode* referenceFrame = _orbitalNavigator.followingAnchorRotation() ?
|
||||
_orbitalNavigator.anchorNode() :
|
||||
sceneGraph()->root();
|
||||
@@ -395,7 +266,7 @@ NavigationHandler::NavigationState NavigationHandler::navigationState() const {
|
||||
return navigationState(*referenceFrame);
|
||||
}
|
||||
|
||||
NavigationHandler::NavigationState NavigationHandler::navigationState(
|
||||
NavigationState NavigationHandler::navigationState(
|
||||
const SceneGraphNode& referenceFrame) const
|
||||
{
|
||||
const SceneGraphNode* anchor = _orbitalNavigator.anchorNode();
|
||||
@@ -441,7 +312,7 @@ NavigationHandler::NavigationState NavigationHandler::navigationState(
|
||||
void NavigationHandler::saveNavigationState(const std::string& filepath,
|
||||
const std::string& referenceFrameIdentifier)
|
||||
{
|
||||
NavigationHandler::NavigationState state;
|
||||
NavigationState state;
|
||||
if (!referenceFrameIdentifier.empty()) {
|
||||
const SceneGraphNode* referenceFrame = sceneGraphNode(referenceFrameIdentifier);
|
||||
if (!referenceFrame) {
|
||||
@@ -560,10 +431,6 @@ std::vector<std::string> NavigationHandler::joystickButtonCommand(int button) co
|
||||
return _orbitalNavigator.joystickStates().buttonCommand(button);
|
||||
}
|
||||
|
||||
documentation::Documentation NavigationHandler::NavigationState::Documentation() {
|
||||
return codegen::doc<Parameters>("core_navigation_state");
|
||||
}
|
||||
|
||||
scripting::LuaLibrary NavigationHandler::luaLibrary() {
|
||||
return {
|
||||
"navigation",
|
||||
@@ -22,8 +22,9 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <numeric>
|
||||
#include <openspace/interaction/scriptcamerastates.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <numeric>
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
@@ -53,7 +54,7 @@ int getNavigationState(lua_State* L) {
|
||||
"lua::getNavigationState"
|
||||
);
|
||||
|
||||
interaction::NavigationHandler::NavigationState state;
|
||||
interaction::NavigationState state;
|
||||
if (n == 1) {
|
||||
const std::string referenceFrameIdentifier = ghoul::lua::value<std::string>(L, 1);
|
||||
const SceneGraphNode* referenceFrame = sceneGraphNode(referenceFrameIdentifier);
|
||||
@@ -124,7 +125,7 @@ int setNavigationState(lua_State* L) {
|
||||
ghoul::lua::luaDictionaryFromState(L, navigationStateDictionary);
|
||||
|
||||
openspace::documentation::TestResult r = openspace::documentation::testSpecification(
|
||||
interaction::NavigationHandler::NavigationState::Documentation(),
|
||||
interaction::NavigationState::Documentation(),
|
||||
navigationStateDictionary
|
||||
);
|
||||
|
||||
186
src/navigation/navigationstate.cpp
Normal file
186
src/navigation/navigationstate.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/camera/camerapose.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "NavigationState";
|
||||
|
||||
const double Epsilon = 1E-7;
|
||||
|
||||
struct [[codegen::Dictionary(NavigationState)]] Parameters {
|
||||
// The identifier of the anchor node
|
||||
std::string anchor;
|
||||
|
||||
// The identifier of the aim node, if used
|
||||
std::optional<std::string> aim;
|
||||
|
||||
// The identifier of the scene graph node to use as reference frame. If not
|
||||
// specified, this will be the same as the anchor
|
||||
std::optional<std::string> referenceFrame;
|
||||
|
||||
// The position of the camera relative to the anchor node, expressed in meters in
|
||||
// the specified reference frame
|
||||
glm::dvec3 position;
|
||||
|
||||
// The up vector expressed in the coordinate system of the reference frame
|
||||
std::optional<glm::dvec3> up;
|
||||
|
||||
// The yaw angle in radians. Positive angle means yawing camera to the right
|
||||
std::optional<double> yaw;
|
||||
|
||||
// The pitch angle in radians. Positive angle means pitching camera upwards
|
||||
std::optional<double> pitch;
|
||||
};
|
||||
#include "navigationstate_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
NavigationState::NavigationState(const ghoul::Dictionary& dictionary) {
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
anchor = p.anchor;
|
||||
position = p.position;
|
||||
|
||||
referenceFrame = p.referenceFrame.value_or(anchor);
|
||||
aim = p.aim.value_or(aim);
|
||||
|
||||
if (p.up.has_value()) {
|
||||
up = *p.up;
|
||||
|
||||
yaw = p.yaw.value_or(yaw);
|
||||
pitch = p.pitch.value_or(pitch);
|
||||
}
|
||||
}
|
||||
|
||||
NavigationState::NavigationState(std::string anchor_, std::string aim_,
|
||||
std::string referenceFrame_, glm::dvec3 position_,
|
||||
std::optional<glm::dvec3> up_,
|
||||
double yaw_, double pitch_)
|
||||
: anchor(std::move(anchor_))
|
||||
, aim(std::move(aim_))
|
||||
, referenceFrame(std::move(referenceFrame_))
|
||||
, position(std::move(position_))
|
||||
, up(std::move(up_))
|
||||
, yaw(yaw_)
|
||||
, pitch(pitch_)
|
||||
{}
|
||||
|
||||
CameraPose NavigationState::cameraPose() const {
|
||||
const SceneGraphNode* referenceFrameNode = sceneGraphNode(referenceFrame);
|
||||
const SceneGraphNode* anchorNode = sceneGraphNode(anchor);
|
||||
|
||||
if (!anchorNode) {
|
||||
LERROR(fmt::format(
|
||||
"Could not find scene graph node '{}' used as anchor.", referenceFrame
|
||||
));
|
||||
return CameraPose();
|
||||
}
|
||||
if (!aim.empty() && !sceneGraphNode(aim)) {
|
||||
LERROR(fmt::format(
|
||||
"Could not find scene graph node '{}' used as aim.", referenceFrame
|
||||
));
|
||||
return CameraPose();
|
||||
}
|
||||
if (!referenceFrameNode) {
|
||||
LERROR(fmt::format(
|
||||
"Could not find scene graph node '{}' used as reference frame.",
|
||||
referenceFrame)
|
||||
);
|
||||
return CameraPose();
|
||||
}
|
||||
|
||||
CameraPose resultingPose;
|
||||
|
||||
const glm::dvec3 anchorWorldPosition = anchorNode->worldPosition();
|
||||
const glm::dmat3 referenceFrameTransform = referenceFrameNode->worldRotationMatrix();
|
||||
|
||||
resultingPose.position = anchorWorldPosition +
|
||||
glm::dvec3(referenceFrameTransform * glm::dvec4(position, 1.0));
|
||||
|
||||
glm::dvec3 upVector = up.has_value() ?
|
||||
glm::normalize(referenceFrameTransform * up.value()) :
|
||||
glm::dvec3(0.0, 1.0, 0.0);
|
||||
|
||||
// Construct vectors of a "neutral" view, i.e. when the aim is centered in view.
|
||||
glm::dvec3 neutralView =
|
||||
glm::normalize(anchorWorldPosition - resultingPose.position);
|
||||
|
||||
glm::dquat neutralCameraRotation = glm::inverse(glm::quat_cast(glm::lookAt(
|
||||
glm::dvec3(0.0),
|
||||
neutralView,
|
||||
upVector
|
||||
)));
|
||||
|
||||
glm::dquat pitchRotation = glm::angleAxis(pitch, glm::dvec3(1.f, 0.f, 0.f));
|
||||
glm::dquat yawRotation = glm::angleAxis(yaw, glm::dvec3(0.f, -1.f, 0.f));
|
||||
|
||||
resultingPose.rotation = neutralCameraRotation * yawRotation * pitchRotation;
|
||||
|
||||
return resultingPose;
|
||||
}
|
||||
|
||||
ghoul::Dictionary NavigationState::dictionary() const {
|
||||
constexpr const char* KeyAnchor = "Anchor";
|
||||
constexpr const char* KeyAim = "Aim";
|
||||
constexpr const char* KeyPosition = "Position";
|
||||
constexpr const char* KeyUp = "Up";
|
||||
constexpr const char* KeyYaw = "Yaw";
|
||||
constexpr const char* KeyPitch = "Pitch";
|
||||
constexpr const char* KeyReferenceFrame = "ReferenceFrame";
|
||||
|
||||
ghoul::Dictionary cameraDict;
|
||||
cameraDict.setValue(KeyPosition, position);
|
||||
cameraDict.setValue(KeyAnchor, anchor);
|
||||
|
||||
if (anchor != referenceFrame) {
|
||||
cameraDict.setValue(KeyReferenceFrame, referenceFrame);
|
||||
}
|
||||
if (!aim.empty()) {
|
||||
cameraDict.setValue(KeyAim, aim);
|
||||
}
|
||||
if (up.has_value()) {
|
||||
cameraDict.setValue(KeyUp, *up);
|
||||
|
||||
if (std::abs(yaw) > Epsilon) {
|
||||
cameraDict.setValue(KeyYaw, yaw);
|
||||
}
|
||||
if (std::abs(pitch) > Epsilon) {
|
||||
cameraDict.setValue(KeyPitch, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
return cameraDict;
|
||||
}
|
||||
|
||||
documentation::Documentation NavigationState::Documentation() {
|
||||
return codegen::doc<Parameters>("core_navigation_state");
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
@@ -22,7 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/query/query.h>
|
||||
@@ -643,8 +644,7 @@ glm::dquat OrbitalNavigator::composeCameraRotation(
|
||||
return decomposition.globalRotation * decomposition.localRotation;
|
||||
}
|
||||
|
||||
Camera* OrbitalNavigator::camera() const
|
||||
{
|
||||
Camera* OrbitalNavigator::camera() const {
|
||||
return _camera;
|
||||
}
|
||||
|
||||
@@ -909,9 +909,8 @@ OrbitalNavigator::CameraRotationDecomposition
|
||||
return { localCameraRotation, globalCameraRotation };
|
||||
}
|
||||
|
||||
OrbitalNavigator::CameraPose OrbitalNavigator::followAim(CameraPose pose,
|
||||
glm::dvec3 cameraToAnchor,
|
||||
Displacement anchorToAim)
|
||||
CameraPose OrbitalNavigator::followAim(CameraPose pose, glm::dvec3 cameraToAnchor,
|
||||
Displacement anchorToAim)
|
||||
{
|
||||
CameraRotationDecomposition anchorDecomp =
|
||||
decomposeCameraRotation(pose, pose.position + cameraToAnchor);
|
||||
224
src/navigation/path.cpp
Normal file
224
src/navigation/path.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/navigation/path.h>
|
||||
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/pathcurve.h>
|
||||
#include <openspace/navigation/pathcurves/avoidcollisioncurve.h>
|
||||
#include <openspace/navigation/pathcurves/zoomoutoverviewcurve.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/interpolator.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "Path";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
Path::Path(Waypoint start, Waypoint end, CurveType type,
|
||||
std::optional<double> duration)
|
||||
: _start(start), _end(end), _curveType(type)
|
||||
{
|
||||
switch (_curveType) {
|
||||
case CurveType::AvoidCollision:
|
||||
_curve = std::make_unique<AvoidCollisionCurve>(_start, _end);
|
||||
break;
|
||||
case CurveType::Linear:
|
||||
_curve = std::make_unique<LinearCurve>(_start, _end);
|
||||
break;
|
||||
case CurveType::ZoomOutOverview:
|
||||
_curve = std::make_unique<ZoomOutOverviewCurve>(_start, _end);
|
||||
break;
|
||||
default:
|
||||
LERROR("Could not create curve. Type does not exist!");
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
|
||||
const auto defaultDuration = [](double pathlength) {
|
||||
const double speedScale =
|
||||
global::navigationHandler->pathNavigator().speedScale();
|
||||
return std::log(pathlength) / speedScale;
|
||||
};
|
||||
|
||||
_duration = duration.value_or(defaultDuration(pathLength()));
|
||||
|
||||
// Compute speed factor to match the generated path length and duration, by
|
||||
// traversing the path and computing how much faster/slower it should be
|
||||
const int nSteps = 500;
|
||||
const double dt = (_duration / nSteps) > 0.01 ? (_duration / nSteps) : 0.01;
|
||||
|
||||
while (!hasReachedEnd()) {
|
||||
traversePath(dt);
|
||||
}
|
||||
|
||||
_speedFactorFromDuration = _progressedTime / _duration;
|
||||
|
||||
// Reset playback variables
|
||||
_traveledDistance = 0.0;
|
||||
_progressedTime = 0.0;
|
||||
}
|
||||
|
||||
Waypoint Path::startPoint() const { return _start; }
|
||||
|
||||
Waypoint Path::endPoint() const { return _end; }
|
||||
|
||||
double Path::duration() const { return _duration; }
|
||||
|
||||
double Path::pathLength() const { return _curve->length(); }
|
||||
|
||||
std::vector<glm::dvec3> Path::controlPoints() const {
|
||||
return _curve->points();
|
||||
}
|
||||
|
||||
CameraPose Path::traversePath(double dt) {
|
||||
const double speed = _speedFactorFromDuration * speedAlongPath(_traveledDistance);
|
||||
const double displacement = dt * speed;
|
||||
|
||||
_progressedTime += dt;
|
||||
_traveledDistance += displacement;
|
||||
|
||||
return interpolatedPose(_traveledDistance);
|
||||
}
|
||||
|
||||
std::string Path::currentAnchor() const {
|
||||
bool pastHalfway = (_traveledDistance / pathLength()) > 0.5;
|
||||
return (pastHalfway) ? _end.nodeIdentifier : _start.nodeIdentifier;
|
||||
}
|
||||
|
||||
bool Path::hasReachedEnd() const {
|
||||
return (_traveledDistance / pathLength()) >= 1.0;
|
||||
}
|
||||
|
||||
CameraPose Path::interpolatedPose(double distance) const {
|
||||
const double relativeDistance = distance / pathLength();
|
||||
CameraPose cs;
|
||||
cs.position = _curve->positionAt(relativeDistance);
|
||||
cs.rotation = interpolateRotation(relativeDistance);
|
||||
return cs;
|
||||
}
|
||||
|
||||
glm::dquat Path::interpolateRotation(double t) const {
|
||||
switch (_curveType) {
|
||||
case CurveType::AvoidCollision:
|
||||
case CurveType::Linear:
|
||||
return interpolation::easedSlerp(_start.rotation(), _end.rotation(), t);
|
||||
case CurveType::ZoomOutOverview:
|
||||
{
|
||||
const double t1 = 0.2;
|
||||
const double t2 = 0.8;
|
||||
|
||||
const glm::dvec3 startPos = _curve->positionAt(0.0);
|
||||
const glm::dvec3 endPos = _curve->positionAt(1.0);
|
||||
const glm::dvec3 startNodePos = _start.node()->worldPosition();
|
||||
const glm::dvec3 endNodePos = _end.node()->worldPosition();
|
||||
|
||||
glm::dvec3 lookAtPos;
|
||||
if (t < t1) {
|
||||
// Compute a position in front of the camera at the start orientation
|
||||
const double inFrontDistance = glm::distance(startPos, startNodePos);
|
||||
const glm::dvec3 viewDir = helpers::viewDirection(_start.rotation());
|
||||
const glm::dvec3 inFrontOfStart = startPos + inFrontDistance * viewDir;
|
||||
|
||||
const double tScaled = ghoul::cubicEaseInOut(t / t1);
|
||||
lookAtPos =
|
||||
ghoul::interpolateLinear(tScaled, inFrontOfStart, startNodePos);
|
||||
}
|
||||
else if (t <= t2) {
|
||||
const double tScaled = ghoul::cubicEaseInOut((t - t1) / (t2 - t1));
|
||||
lookAtPos = ghoul::interpolateLinear(tScaled, startNodePos, endNodePos);
|
||||
}
|
||||
else if (t > t2) {
|
||||
// Compute a position in front of the camera at the end orientation
|
||||
const double inFrontDistance = glm::distance(endPos, endNodePos);
|
||||
const glm::dvec3 viewDir = helpers::viewDirection(_end.rotation());
|
||||
const glm::dvec3 inFrontOfEnd = endPos + inFrontDistance * viewDir;
|
||||
|
||||
const double tScaled = ghoul::cubicEaseInOut((t - t2) / (1.0 - t2));
|
||||
lookAtPos = ghoul::interpolateLinear(tScaled, endNodePos, inFrontOfEnd);
|
||||
}
|
||||
|
||||
// Handle up vector separately
|
||||
glm::dvec3 startUp = _start.rotation() * glm::dvec3(0.0, 1.0, 0.0);
|
||||
glm::dvec3 endUp = _end.rotation() * glm::dvec3(0.0, 1.0, 0.0);
|
||||
|
||||
double tUp = helpers::shiftAndScale(t, t1, t2);
|
||||
tUp = ghoul::sineEaseInOut(tUp);
|
||||
glm::dvec3 up = ghoul::interpolateLinear(tUp, startUp, endUp);
|
||||
|
||||
return helpers::lookAtQuaternion(_curve->positionAt(t), lookAtPos, up);
|
||||
}
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
double Path::speedAlongPath(double traveledDistance) {
|
||||
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();
|
||||
}
|
||||
|
||||
const double distanceToClosestNode = glm::distance(closestPos, prevPose.position);
|
||||
double speed = distanceToClosestNode;
|
||||
|
||||
// Dampen speed in beginning of path
|
||||
const double startUpDistance = 2.0 * _start.node()->boundingSphere();
|
||||
if (traveledDistance < startUpDistance) {
|
||||
speed *= traveledDistance / startUpDistance + 0.01;
|
||||
}
|
||||
|
||||
// Dampen speed in end of path
|
||||
// Note: this leads to problems when the full length of the path is really big
|
||||
const double closeUpDistance = 2.0 * _end.node()->boundingSphere();
|
||||
if (traveledDistance > (pathLength() - closeUpDistance)) {
|
||||
const double remainingDistance = pathLength() - traveledDistance;
|
||||
speed *= remainingDistance / closeUpDistance + 0.01;
|
||||
}
|
||||
|
||||
// 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 speed;
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
249
src/navigation/pathcreator.cpp
Normal file
249
src/navigation/pathcreator.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/navigation/pathcreator.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/navigation/waypoint.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "PathCreator";
|
||||
constexpr const float Epsilon = 1e-5f;
|
||||
|
||||
// TODO: where should this documentation be?
|
||||
struct [[codegen::Dictionary(PathInstruction)]] Parameters {
|
||||
enum class Type {
|
||||
Node,
|
||||
NavigationState
|
||||
};
|
||||
Type type;
|
||||
|
||||
// The desired duration traversing the specified path segment should take
|
||||
std::optional<float> duration;
|
||||
|
||||
// (Node): The target node of the camera path. Not optional for 'Node' instructions
|
||||
std::optional<std::string> target;
|
||||
|
||||
// (Node): An optional position in relation to the target node, in model
|
||||
// coordinates (meters)
|
||||
std::optional<glm::dvec3> position;
|
||||
|
||||
// (Node): An optional height in relation to the target node, in meters
|
||||
std::optional<double> height;
|
||||
|
||||
// (Node): If true, the up direction of the node is taken into account when
|
||||
// computing the wayopoint for this instruction
|
||||
std::optional<bool> useTargetUpDirection;
|
||||
|
||||
// (NavigationState): A navigation state that will be the target
|
||||
// of this path segment
|
||||
std::optional<ghoul::Dictionary> navigationState
|
||||
[[codegen::reference("core_navigation_state")]];
|
||||
|
||||
// A navigation state that determines the start state for the camera path
|
||||
std::optional<ghoul::Dictionary> startState
|
||||
[[codegen::reference("core_navigation_state")]];
|
||||
};
|
||||
#include "pathcreator_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
Path PathCreator::createPath(const ghoul::Dictionary& dictionary,
|
||||
Path::CurveType curveType)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
std::optional<float> duration = p.duration;
|
||||
|
||||
bool hasStart = p.startState.has_value();
|
||||
Waypoint startPoint = hasStart ? Waypoint(p.startState.value()) : waypointFromCamera();
|
||||
|
||||
// TODO: also handle curve type here
|
||||
|
||||
std::vector<Waypoint> waypoints;
|
||||
switch (p.type) {
|
||||
case Parameters::Type::NavigationState: {
|
||||
if (!p.navigationState.has_value()) {
|
||||
throw ghoul::RuntimeError("A navigation state is required");
|
||||
}
|
||||
|
||||
const NavigationState navigationState =
|
||||
NavigationState(p.navigationState.value());
|
||||
|
||||
waypoints = { Waypoint(navigationState) };
|
||||
break;
|
||||
}
|
||||
case Parameters::Type::Node: {
|
||||
if (!p.target.has_value()) {
|
||||
throw ghoul::RuntimeError("A target node is required");
|
||||
}
|
||||
|
||||
const std::string nodeIdentifier = p.target.value();
|
||||
const SceneGraphNode* targetNode = sceneGraphNode(nodeIdentifier);
|
||||
|
||||
if (!targetNode) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Could not find target node '{}'", nodeIdentifier
|
||||
));
|
||||
}
|
||||
|
||||
NodeInfo info {
|
||||
nodeIdentifier,
|
||||
p.position,
|
||||
p.height,
|
||||
p.useTargetUpDirection.value_or(false)
|
||||
};
|
||||
|
||||
waypoints = { computeDefaultWaypoint(info, startPoint) };
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LERROR(fmt::format("Uknown instruciton type: {}", p.type));
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: allow for an instruction to represent a list of waypoints
|
||||
Waypoint waypointToAdd = waypoints[0];
|
||||
|
||||
return Path(startPoint, waypointToAdd, curveType, duration);
|
||||
}
|
||||
|
||||
Waypoint PathCreator::waypointFromCamera() {
|
||||
Camera* camera = global::navigationHandler->camera();
|
||||
const glm::dvec3 pos = camera->positionVec3();
|
||||
const glm::dquat rot = camera->rotationQuaternion();
|
||||
const std::string node = global::navigationHandler->anchorNode()->identifier();
|
||||
return Waypoint{ pos, rot, node };
|
||||
}
|
||||
|
||||
Waypoint PathCreator::computeDefaultWaypoint(const NodeInfo& info,
|
||||
const Waypoint& startPoint)
|
||||
{
|
||||
const SceneGraphNode* targetNode = sceneGraphNode(info.identifier);
|
||||
if (!targetNode) {
|
||||
LERROR(fmt::format("Could not find target node '{}'", info.identifier));
|
||||
return Waypoint();
|
||||
}
|
||||
|
||||
glm::dvec3 targetPos;
|
||||
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() * info.position.value();
|
||||
}
|
||||
else {
|
||||
const glm::dvec3 nodePos = targetNode->worldPosition();
|
||||
const glm::dvec3 sunPos = glm::dvec3(0.0, 0.0, 0.0);
|
||||
const SceneGraphNode* closeNode = findNodeNearTarget(targetNode);
|
||||
|
||||
glm::dvec3 stepDirection;
|
||||
if (closeNode) {
|
||||
// If the node is close to another node in the scene, make sure that the
|
||||
// position is set to minimize risk of collision
|
||||
stepDirection = glm::normalize(nodePos - closeNode->worldPosition());
|
||||
}
|
||||
else if (glm::length(sunPos - nodePos) < Epsilon) {
|
||||
// Special case for when the target is the Sun. Assumption: want an overview of
|
||||
// the solar system, and not stay in the orbital plane
|
||||
stepDirection = glm::dvec3(0.0, 0.0, 1.0);
|
||||
}
|
||||
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 targetToPrev = prevPos - nodePos;
|
||||
const glm::dvec3 targetToSun = sunPos - nodePos;
|
||||
|
||||
constexpr const float defaultPositionOffsetAngle = -30.f; // degrees
|
||||
constexpr const float angle = glm::radians(defaultPositionOffsetAngle);
|
||||
const glm::dvec3 axis = glm::normalize(glm::cross(targetToPrev, targetToSun));
|
||||
const glm::dquat offsetRotation = angleAxis(static_cast<double>(angle), axis);
|
||||
|
||||
stepDirection = glm::normalize(offsetRotation * targetToSun);
|
||||
}
|
||||
|
||||
const double radius = Waypoint::findValidBoundingSphere(targetNode);
|
||||
const double defaultHeight = 2.0 * radius;
|
||||
const double height = info.height.value_or(defaultHeight);
|
||||
|
||||
targetPos = nodePos + stepDirection * (radius + height);
|
||||
}
|
||||
|
||||
glm::dvec3 up = global::navigationHandler->camera()->lookUpVectorWorldSpace();
|
||||
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);
|
||||
}
|
||||
|
||||
const glm::dvec3 lookAtPos = targetNode->worldPosition();
|
||||
const glm::dquat targetRot = helpers::lookAtQuaternion(targetPos, lookAtPos, up);
|
||||
|
||||
return Waypoint(targetPos, targetRot, info.identifier);
|
||||
}
|
||||
|
||||
SceneGraphNode* PathCreator::findNodeNearTarget(const SceneGraphNode* node) {
|
||||
const std::vector<SceneGraphNode*>& relevantNodes =
|
||||
global::navigationHandler->pathNavigator().relevantNodes();
|
||||
|
||||
for (SceneGraphNode* n : relevantNodes) {
|
||||
if (n->identifier() == node->identifier()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
constexpr const 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 = helpers::isPointInsideSphere(
|
||||
posInModelCoords,
|
||||
glm::dvec3(0.0, 0.0, 0.0),
|
||||
proximityRadius
|
||||
);
|
||||
|
||||
if (isClose) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
236
src/navigation/pathcurve.cpp
Normal file
236
src/navigation/pathcurve.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/navigation/pathcurve.h>
|
||||
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/waypoint.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/projection.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "PathCurve";
|
||||
constexpr const int NrSamplesPerSegment = 100;
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
PathCurve::~PathCurve() {}
|
||||
|
||||
const double PathCurve::length() const {
|
||||
return _totalLength;
|
||||
}
|
||||
|
||||
glm::dvec3 PathCurve::positionAt(double relativeDistance) {
|
||||
const double u = curveParameter(relativeDistance * _totalLength);
|
||||
return interpolate(u);
|
||||
}
|
||||
|
||||
// Compute the curve parameter from an arc length value, using a combination of
|
||||
// Newton's method and bisection. Source:
|
||||
// https://www.geometrictools.com/Documentation/MovingAlongCurveSpecifiedSpeed.pdf
|
||||
// Input s is a length value, in the range [0, _totalLength]
|
||||
// Returns curve parameter in range [0, 1]
|
||||
double PathCurve::curveParameter(double s) {
|
||||
if (s <= 0.0) return 0.0;
|
||||
if (s >= _totalLength) return 1.0;
|
||||
|
||||
unsigned int segmentIndex = 1;
|
||||
while (s > _lengthSums[segmentIndex]) {
|
||||
segmentIndex++;
|
||||
}
|
||||
|
||||
const int startIndex = (segmentIndex - 1) * NrSamplesPerSegment;
|
||||
const int endIndex = segmentIndex * NrSamplesPerSegment + 1;
|
||||
|
||||
const double segmentS = s - _lengthSums[segmentIndex - 1];
|
||||
const double uMin = _curveParameterSteps[segmentIndex - 1];
|
||||
const double uMax = _curveParameterSteps[segmentIndex];
|
||||
|
||||
// Use samples to find an initial guess for Newton's method
|
||||
// Find first sample with s larger than input s
|
||||
auto sampleIterator = std::upper_bound(
|
||||
_parameterSamples.begin() + startIndex,
|
||||
_parameterSamples.begin() + endIndex,
|
||||
ParameterPair{ 0.0 , s }, // 0.0 is a dummy value for u
|
||||
[](ParameterPair lhs, ParameterPair rhs) {
|
||||
return lhs.s < rhs.s;
|
||||
}
|
||||
);
|
||||
|
||||
const ParameterPair& sample = *sampleIterator;
|
||||
const ParameterPair& prevSample = *(sampleIterator - 1);
|
||||
const double uPrev = prevSample.u;
|
||||
const double sPrev = prevSample.s;
|
||||
const double slope = (sample.u - uPrev) / (sample.s - sPrev);
|
||||
double u = uPrev + slope * (s - sPrev);
|
||||
|
||||
constexpr const int maxIterations = 50;
|
||||
|
||||
// Initialize root bounding limits for bisection
|
||||
double lower = uMin;
|
||||
double upper = uMax;
|
||||
|
||||
for (int i = 0; i < maxIterations; ++i) {
|
||||
double F = arcLength(uMin, u) - segmentS;
|
||||
|
||||
// The error we tolerate, in meters. Note that distances are very large
|
||||
constexpr const double tolerance = 0.005;
|
||||
if (std::abs(F) <= tolerance) {
|
||||
return u;
|
||||
}
|
||||
|
||||
// Generate a candidate for Newton's method
|
||||
double dfdu = approximatedDerivative(u); // > 0
|
||||
double uCandidate = u - F / dfdu;
|
||||
|
||||
// Update root-bounding interval and test candidate
|
||||
if (F > 0) { // => candidate < u <= upper
|
||||
upper = u;
|
||||
u = (uCandidate <= lower) ? (upper + lower) / 2.0 : uCandidate;
|
||||
}
|
||||
else { // F < 0 => lower <= u < candidate
|
||||
lower = u;
|
||||
u = (uCandidate >= upper) ? (upper + lower) / 2.0 : uCandidate;
|
||||
}
|
||||
}
|
||||
|
||||
// No root was found based on the number of iterations and tolerance. However, it is
|
||||
// safe to report the last computed u value, since it is within the segment interval
|
||||
return u;
|
||||
}
|
||||
|
||||
std::vector<glm::dvec3> PathCurve::points() {
|
||||
return _points;
|
||||
}
|
||||
|
||||
void PathCurve::initializeParameterData() {
|
||||
_nSegments = static_cast<int>(_points.size() - 3);
|
||||
|
||||
ghoul_assert(_nSegments > 0, "Cannot have a curve with zero segments!");
|
||||
|
||||
_curveParameterSteps.clear();
|
||||
_lengthSums.clear();
|
||||
_parameterSamples.clear();
|
||||
|
||||
// Evenly space out parameter intervals
|
||||
_curveParameterSteps.reserve(_nSegments + 1);
|
||||
const double dt = 1.0 / _nSegments;
|
||||
_curveParameterSteps.push_back(0.0);
|
||||
for (unsigned int i = 1; i < _nSegments; i++) {
|
||||
_curveParameterSteps.push_back(dt * i);
|
||||
}
|
||||
_curveParameterSteps.push_back(1.0);
|
||||
|
||||
// Arc lengths
|
||||
_lengthSums.reserve(_nSegments + 1);
|
||||
_lengthSums.push_back(0.0);
|
||||
for (unsigned int i = 1; i <= _nSegments; i++) {
|
||||
double u = _curveParameterSteps[i];
|
||||
double uPrev = _curveParameterSteps[i - 1];
|
||||
double length = arcLength(uPrev, u);
|
||||
_lengthSums.push_back(_lengthSums[i - 1] + length);
|
||||
}
|
||||
_totalLength = _lengthSums.back();
|
||||
|
||||
// Compute a map of arc lengths s and curve parameters u, for reparameterization
|
||||
_parameterSamples.reserve(NrSamplesPerSegment * _nSegments + 1);
|
||||
const double uStep = 1.0 / (_nSegments * NrSamplesPerSegment);
|
||||
for (unsigned int i = 0; i < _nSegments; i++) {
|
||||
double uStart = _curveParameterSteps[i];
|
||||
double sStart = _lengthSums[i];
|
||||
for (int j = 0; j < NrSamplesPerSegment; ++j) {
|
||||
double u = uStart + j * uStep;
|
||||
double s = sStart + arcLength(uStart, u);
|
||||
_parameterSamples.push_back({ u, s });
|
||||
}
|
||||
}
|
||||
_parameterSamples.push_back({ 1.0, _totalLength });
|
||||
}
|
||||
|
||||
double PathCurve::approximatedDerivative(double u, double h) {
|
||||
if (u <= h) {
|
||||
return (1.0 / h) * glm::length(interpolate(0.0 + h) - interpolate(0.0));
|
||||
}
|
||||
if (u >= 1.0 - h) {
|
||||
return (1.0 / h) * glm::length(interpolate(1.0) - interpolate(1.0 - h));
|
||||
}
|
||||
return (0.5 / h) * glm::length(interpolate(u + h) - interpolate(u - h));
|
||||
}
|
||||
|
||||
double PathCurve::arcLength(double limit) {
|
||||
return arcLength(0.0, limit);
|
||||
}
|
||||
|
||||
double PathCurve::arcLength(double lowerLimit, double upperLimit) {
|
||||
return helpers::fivePointGaussianQuadrature(
|
||||
lowerLimit,
|
||||
upperLimit,
|
||||
[this](double u) { return approximatedDerivative(u); }
|
||||
);
|
||||
}
|
||||
|
||||
glm::dvec3 PathCurve::interpolate(double u) {
|
||||
ghoul_assert(u >= 0 && u <= 1.0, "Interpolation variable out of range [0, 1]");
|
||||
|
||||
if (u < 0.0) {
|
||||
return _points[1];
|
||||
}
|
||||
if (u > 1.0) {
|
||||
return *(_points.end() - 2);
|
||||
}
|
||||
|
||||
std::vector<double>::iterator segmentEndIt =
|
||||
std::lower_bound(_curveParameterSteps.begin(), _curveParameterSteps.end(), u);
|
||||
|
||||
const int index =
|
||||
static_cast<int>((segmentEndIt - 1) - _curveParameterSteps.begin());
|
||||
|
||||
double segmentStart = _curveParameterSteps[index];
|
||||
double segmentDuration = (_curveParameterSteps[index + 1] - segmentStart);
|
||||
double uSegment = (u - segmentStart) / segmentDuration;
|
||||
|
||||
return interpolation::catmullRom(
|
||||
uSegment,
|
||||
_points[index],
|
||||
_points[index + 1],
|
||||
_points[index + 2],
|
||||
_points[index + 3],
|
||||
1.0 // chordal version
|
||||
);
|
||||
}
|
||||
|
||||
LinearCurve::LinearCurve(const Waypoint& start, const Waypoint& end) {
|
||||
_points.push_back(start.position());
|
||||
_points.push_back(start.position());
|
||||
_points.push_back(end.position());
|
||||
_points.push_back(end.position());
|
||||
initializeParameterData();
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
190
src/navigation/pathcurves/avoidcollisioncurve.cpp
Normal file
190
src/navigation/pathcurves/avoidcollisioncurve.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/navigation/pathcurves/avoidcollisioncurve.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/navigation/waypoint.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/projection.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "AvoidCollisionCurve";
|
||||
|
||||
constexpr const double CloseToNodeThresholdFactor = 5.0;
|
||||
constexpr const double AvoidCollisionDistanceFactor = 3.0;
|
||||
constexpr const double CollisionBufferSizeFactor = 1.0;
|
||||
constexpr const int MaxAvoidCollisionSteps = 10;
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
AvoidCollisionCurve::AvoidCollisionCurve(const Waypoint& start, const Waypoint& end) {
|
||||
_relevantNodes = global::navigationHandler->pathNavigator().relevantNodes();
|
||||
|
||||
const glm::dvec3 startNodeCenter = start.node()->worldPosition();
|
||||
const glm::dvec3 endNodeCenter = end.node()->worldPosition();
|
||||
const double startNodeRadius = start.validBoundingSphere;
|
||||
const double endNodeRadius = end.validBoundingSphere;
|
||||
const glm::dvec3 startViewDir = start.rotation() * glm::dvec3(0.0, 0.0, -1.0);
|
||||
|
||||
// Add control points for a catmull-rom spline, first and last will not be intersected
|
||||
_points.push_back(start.position());
|
||||
_points.push_back(start.position());
|
||||
|
||||
// Add an extra point to first go backwards if starting close to planet
|
||||
glm::dvec3 nodeToStart = start.position() - startNodeCenter;
|
||||
double distanceToStartNode = glm::length(nodeToStart);
|
||||
|
||||
if (distanceToStartNode < CloseToNodeThresholdFactor * startNodeRadius) {
|
||||
double distance = startNodeRadius;
|
||||
glm::dvec3 newPos = start.position() + distance * glm::normalize(nodeToStart);
|
||||
_points.push_back(newPos);
|
||||
}
|
||||
|
||||
// Add point for moving out if the end state is in opposite direction
|
||||
glm::dvec3 startToEnd = end.position() - start.position();
|
||||
double cosAngleToTarget = glm::dot(normalize(-startViewDir), normalize(startToEnd));
|
||||
bool targetInOppositeDirection = cosAngleToTarget > 0.7;
|
||||
|
||||
if (targetInOppositeDirection) {
|
||||
const glm::dquat midleRot = glm::slerp(start.rotation(), end.rotation(), 0.5);
|
||||
const glm::dvec3 middleViewDir = midleRot * glm::dvec3(0.0, 0.0, -1.0);
|
||||
const double stepOutDistance = 0.4 * glm::length(startToEnd);
|
||||
|
||||
glm::dvec3 newPos = start.position() + 0.2 * startToEnd -
|
||||
stepOutDistance * glm::normalize(middleViewDir);
|
||||
|
||||
_points.push_back(newPos);
|
||||
}
|
||||
|
||||
// Add an extra point to approach target
|
||||
const glm::dvec3 nodeToEnd = end.position() - endNodeCenter;
|
||||
const double distanceToEndNode = glm::length(nodeToEnd);
|
||||
|
||||
if (distanceToEndNode < CloseToNodeThresholdFactor * endNodeRadius) {
|
||||
double distance = endNodeRadius;
|
||||
glm::dvec3 newPos = end.position() + distance * glm::normalize(nodeToEnd);
|
||||
_points.push_back(newPos);
|
||||
}
|
||||
|
||||
_points.push_back(end.position());
|
||||
_points.push_back(end.position());
|
||||
|
||||
// Create extra points to avoid collision
|
||||
removeCollisions();
|
||||
|
||||
initializeParameterData();
|
||||
}
|
||||
|
||||
// Try to reduce the risk of collision by approximating the curve with linear segments.
|
||||
// If a collision happens, create a new point for the path to go through, in an attempt to
|
||||
// avoid that collision
|
||||
void AvoidCollisionCurve::removeCollisions(int step) {
|
||||
if (step > MaxAvoidCollisionSteps) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int nSegments = static_cast<int>( _points.size() - 3);
|
||||
for (int i = 0; i < nSegments; ++i) {
|
||||
const glm::dvec3 lineStart = _points[i + 1];
|
||||
const glm::dvec3 lineEnd = _points[i + 2];
|
||||
|
||||
for (SceneGraphNode* node : _relevantNodes) {
|
||||
// Do collision check in relative coordinates, to avoid huge numbers
|
||||
const glm::dmat4 modelTransform = node->modelTransform();
|
||||
glm::dvec3 p1 = glm::inverse(modelTransform) * glm::dvec4(lineStart, 1.0);
|
||||
glm::dvec3 p2 = glm::inverse(modelTransform) * glm::dvec4(lineEnd, 1.0);
|
||||
|
||||
// Sphere to check for collision
|
||||
double radius = node->boundingSphere();
|
||||
glm::dvec3 center = glm::dvec3(0.0, 0.0, 0.0);
|
||||
|
||||
// Add a buffer to avoid passing too close to the node.
|
||||
// Dont't add it if any point is inside the buffer
|
||||
double buffer = CollisionBufferSizeFactor * node->boundingSphere();
|
||||
bool p1IsInside = helpers::isPointInsideSphere(p1, center, radius + buffer);
|
||||
bool p2IsInside = helpers::isPointInsideSphere(p2, center, radius + buffer);
|
||||
if (!p1IsInside && !p2IsInside) {
|
||||
radius += buffer;
|
||||
}
|
||||
|
||||
glm::dvec3 intersectionPointModelCoords;
|
||||
bool collision = helpers::lineSphereIntersection(
|
||||
p1,
|
||||
p2,
|
||||
center,
|
||||
radius,
|
||||
intersectionPointModelCoords
|
||||
);
|
||||
|
||||
if (collision) {
|
||||
glm::dvec3 collisionPoint = modelTransform *
|
||||
glm::dvec4(intersectionPointModelCoords, 1.0);
|
||||
|
||||
// before collision response, make sure none of the points are inside the node
|
||||
bool isStartInsideNode = helpers::isPointInsideSphere(p1, center, radius);
|
||||
bool isEndInsideNode = helpers::isPointInsideSphere(p2, center, radius);
|
||||
if (isStartInsideNode || isEndInsideNode) {
|
||||
LWARNING(fmt::format(
|
||||
"Something went wrong! "
|
||||
"At least one point in the path is inside node: {}",
|
||||
node->identifier()
|
||||
));
|
||||
break;
|
||||
}
|
||||
|
||||
// To avoid collision, take a step in an orhtogonal direction of the
|
||||
// collision point and add a new point
|
||||
const glm::dvec3 lineDirection = glm::normalize(lineEnd - lineStart);
|
||||
const glm::dvec3 nodeCenter = node->worldPosition();
|
||||
const glm::dvec3 collisionPointToCenter = nodeCenter - collisionPoint;
|
||||
|
||||
const glm::dvec3 parallell = glm::proj(collisionPointToCenter, lineDirection);
|
||||
const glm::dvec3 orthogonal = collisionPointToCenter - parallell;
|
||||
|
||||
const double avoidCollisionDistance = AvoidCollisionDistanceFactor * radius;
|
||||
|
||||
glm::dvec3 extraKnot = collisionPoint -
|
||||
avoidCollisionDistance * glm::normalize(orthogonal);
|
||||
|
||||
_points.insert(_points.begin() + i + 2, extraKnot);
|
||||
|
||||
step++;
|
||||
removeCollisions(step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
103
src/navigation/pathcurves/zoomoutoverviewcurve.cpp
Normal file
103
src/navigation/pathcurves/zoomoutoverviewcurve.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/navigation/pathcurves/zoomoutoverviewcurve.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/navigation/waypoint.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/projection.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "ZoomOutOverviewCurve";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
// Go far out to get a view of both tagets, aimed to match lookAt orientation
|
||||
ZoomOutOverviewCurve::ZoomOutOverviewCurve(const Waypoint& start, const Waypoint& end) {
|
||||
const double startNodeRadius = start.validBoundingSphere;
|
||||
const double endNodeRadius = end.validBoundingSphere;
|
||||
|
||||
const double endTangentsLengthFactor = 2.0;
|
||||
const double startTangentLength = endTangentsLengthFactor * startNodeRadius;
|
||||
const double endTangentLength = endTangentsLengthFactor * endNodeRadius;
|
||||
|
||||
const glm::dvec3 startNodePos = start.node()->worldPosition();
|
||||
const glm::dvec3 endNodePos = end.node()->worldPosition();
|
||||
const glm::dvec3 startTangentDir = normalize(start.position() - startNodePos);
|
||||
const glm::dvec3 endTangentDir = normalize(end.position() - endNodePos);
|
||||
|
||||
// Start by going outwards
|
||||
_points.push_back(start.position());
|
||||
_points.push_back(start.position());
|
||||
_points.push_back(start.position() + startTangentLength * startTangentDir);
|
||||
|
||||
// Zoom out
|
||||
if (start.nodeIdentifier != end.nodeIdentifier) {
|
||||
const glm::dvec3 n1 = startTangentDir;
|
||||
const glm::dvec3 n2 = endTangentDir;
|
||||
|
||||
// Decide the step direction for the "overview point" based on the directions
|
||||
// at the start and end of the path, to try to get a nice curve shape
|
||||
glm::dvec3 goodStepDirection;
|
||||
if (glm::dot(n1, n2) < 0.0) {
|
||||
// Facing in different directions => step in direction of the cross product
|
||||
goodStepDirection = glm::normalize(glm::cross(-n1, n2));
|
||||
}
|
||||
else {
|
||||
goodStepDirection = glm::normalize(n1 + n2);
|
||||
}
|
||||
|
||||
// Find a direction that is orthogonal to the line between the start and end position
|
||||
const glm::dvec3 startPosToEndPos = end.position() - start.position();
|
||||
const glm::dvec3 outwardStepVector =
|
||||
0.5 * glm::length(startPosToEndPos) * goodStepDirection;
|
||||
|
||||
const glm::dvec3 projectedVec = glm::proj(outwardStepVector, startPosToEndPos);
|
||||
const glm::dvec3 orthogonalComponent = outwardStepVector - projectedVec;
|
||||
const glm::dvec3 stepDirection = glm::normalize(orthogonalComponent);
|
||||
|
||||
// Step half-way along the line between the position and then orthogonally
|
||||
const glm::dvec3 extraKnot = start.position() + 0.5 * startPosToEndPos
|
||||
+ 1.5 * glm::length(startPosToEndPos) * stepDirection;
|
||||
|
||||
_points.push_back(extraKnot);
|
||||
}
|
||||
|
||||
// Closing in on end node
|
||||
_points.push_back(end.position() + endTangentLength * endTangentDir);
|
||||
_points.push_back(end.position());
|
||||
_points.push_back(end.position());
|
||||
|
||||
initializeParameterData();
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
295
src/navigation/pathhelperfunctions.cpp
Normal file
295
src/navigation/pathhelperfunctions.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/navigation/pathhelperfunctions.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/easing.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "Helpers";
|
||||
const double Epsilon = 1E-7;
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction::helpers {
|
||||
|
||||
// Shift and scale to a subinterval [start,end]
|
||||
double shiftAndScale(double t, double start, double end) {
|
||||
ghoul_assert(0.0 < start && start < end&& end < 1.0,
|
||||
"Values must be 0.0 < start < end < 1.0!");
|
||||
double tScaled = t / (end - start) - start;
|
||||
return std::max(0.0, std::min(tScaled, 1.0));
|
||||
}
|
||||
|
||||
glm::dquat lookAtQuaternion(glm::dvec3 eye, glm::dvec3 center, glm::dvec3 up) {
|
||||
glm::dmat4 lookAtMat = glm::lookAt(eye, center, up);
|
||||
return glm::normalize(glm::inverse(glm::quat_cast(lookAtMat)));
|
||||
}
|
||||
|
||||
glm::dvec3 viewDirection(const glm::dquat& q) {
|
||||
return glm::normalize(q * glm::dvec3(0.0, 0.0, -1.0));
|
||||
};
|
||||
|
||||
/*
|
||||
* Calculate the intersection of a line and a sphere
|
||||
* The line segment is defined from p1 to p2
|
||||
* The sphere is of radius r and centered at sc
|
||||
* There are potentially two points of intersection given by
|
||||
* p = p1 + mu1 (p2 - p1)
|
||||
* p = p1 + mu2 (p2 - p1)
|
||||
* Source: http://paulbourke.net/geometry/circlesphere/raysphere.c
|
||||
*/
|
||||
bool lineSphereIntersection(glm::dvec3 p1, glm::dvec3 p2, glm::dvec3 sc,
|
||||
double r, glm::dvec3& intersectionPoint)
|
||||
{
|
||||
long double a, b, c;
|
||||
glm::dvec3 dp = p2 - p1;
|
||||
|
||||
a = dp.x * dp.x + dp.y * dp.y + dp.z * dp.z;
|
||||
b = 2 * (dp.x * (p1.x - sc.x) + dp.y * (p1.y - sc.y) + dp.z * (p1.z - sc.z));
|
||||
c = sc.x * sc.x + sc.y * sc.y + sc.z * sc.z;
|
||||
c += p1.x * p1.x + p1.y * p1.y + p1.z * p1.z;
|
||||
c -= 2 * (sc.x * p1.x + sc.y * p1.y + sc.z * p1.z);
|
||||
c -= r * r;
|
||||
|
||||
long double intersectionTest = b * b - 4.0 * a * c;
|
||||
|
||||
// no intersection
|
||||
if (std::abs(a) < Epsilon || intersectionTest < 0.0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// only care about the first intersection point if we have two
|
||||
const double t = (-b - std::sqrt(intersectionTest)) / (2.0 *a);
|
||||
|
||||
if (t <= Epsilon || t >= abs(1.0 - Epsilon)) return false;
|
||||
|
||||
intersectionPoint = p1 + t * dp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool isPointInsideSphere(const glm::dvec3& p, const glm::dvec3& c, double r) {
|
||||
const glm::dvec3 v = c - p;
|
||||
const long double squaredDistance = v.x * v.x + v.y * v.y + v.z * v.z;
|
||||
const long double squaredRadius = r * r;
|
||||
|
||||
return (squaredDistance <= squaredRadius);
|
||||
}
|
||||
|
||||
double simpsonsRule(double t0, double t1, int n, std::function<double(double)> f) {
|
||||
const double h = (t1 - t0) / static_cast<double>(n);
|
||||
const double endpoints = f(t0) + f(t1);
|
||||
double times4 = 0.0;
|
||||
double times2 = 0.0;
|
||||
|
||||
// weight 4
|
||||
for (int i = 1; i < n; i += 2) {
|
||||
double t = t0 + i * h;
|
||||
times4 += f(t);
|
||||
}
|
||||
|
||||
// weight 2
|
||||
for (int i = 2; i < n; i += 2) {
|
||||
double t = t0 + i * h;
|
||||
times2 += f(t);
|
||||
}
|
||||
|
||||
return (h / 3) * (endpoints + 4 * times4 + 2 * times2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Approximate area under a function using 5-point Gaussian quadrature
|
||||
* https://en.wikipedia.org/wiki/Gaussian_quadrature
|
||||
*/
|
||||
double fivePointGaussianQuadrature(double t0, double t1,
|
||||
std::function<double(double)> f)
|
||||
{
|
||||
struct GaussLengendreCoefficient {
|
||||
double abscissa; // xi
|
||||
double weight; // wi
|
||||
};
|
||||
|
||||
static constexpr GaussLengendreCoefficient coefficients[] = {
|
||||
{ 0.0, 0.5688889 },
|
||||
{ -0.5384693, 0.47862867 },
|
||||
{ 0.5384693, 0.47862867 },
|
||||
{ -0.90617985, 0.23692688 },
|
||||
{ 0.90617985, 0.23692688 }
|
||||
};
|
||||
|
||||
const double a = t0;
|
||||
const double b = t1;
|
||||
double sum = 0.0;
|
||||
for (auto coefficient : coefficients) {
|
||||
// change of interval to [a, b] from [-1, 1] (also 0.5 * (b - a) below)
|
||||
double const t = 0.5 * ((b - a) * coefficient.abscissa + (b + a));
|
||||
sum += f(t) * coefficient.weight;
|
||||
}
|
||||
return 0.5 * (b - a) * sum;
|
||||
}
|
||||
|
||||
} // helpers
|
||||
|
||||
namespace openspace::interaction::interpolation {
|
||||
|
||||
glm::dquat easedSlerp(const glm::dquat q1, const glm::dquat q2, double t) {
|
||||
double tScaled = helpers::shiftAndScale(t, 0.1, 0.9);
|
||||
tScaled = ghoul::sineEaseInOut(tScaled);
|
||||
return glm::slerp(q1, q2, tScaled);
|
||||
}
|
||||
|
||||
// Based on implementation by Mika Rantanen
|
||||
// https://qroph.github.io/2018/07/30/smooth-paths-using-catmull-rom-splines.html
|
||||
glm::dvec3 catmullRom(double t, const glm::dvec3& p0, const glm::dvec3& p1,
|
||||
const glm::dvec3& p2, const glm::dvec3& p3, double alpha)
|
||||
{
|
||||
glm::dvec3 m01, m02, m23, m13;
|
||||
|
||||
double t01 = pow(glm::distance(p0, p1), alpha);
|
||||
double t12 = pow(glm::distance(p1, p2), alpha);
|
||||
double t23 = pow(glm::distance(p2, p3), alpha);
|
||||
|
||||
m01 = (t01 > Epsilon) ? (p1 - p0) / t01 : glm::dvec3{};
|
||||
m23 = (t23 > Epsilon) ? (p3 - p2) / t23 : glm::dvec3{};
|
||||
m02 = (t01 + t12 > Epsilon) ? (p2 - p0) / (t01 + t12) : glm::dvec3{};
|
||||
m13 = (t12 + t23 > Epsilon) ? (p3 - p1) / (t12 + t23) : glm::dvec3{};
|
||||
|
||||
glm::dvec3 m1 = p2 - p1 + t12 * (m01 - m02);
|
||||
glm::dvec3 m2 = p2 - p1 + t12 * (m23 - m13);
|
||||
|
||||
glm::dvec3 a = 2.0 * (p1 - p2) + m1 + m2;
|
||||
glm::dvec3 b = -3.0 * (p1 - p2) - m1 - m1 - m2;
|
||||
glm::dvec3 c = m1;
|
||||
glm::dvec3 d = p1;
|
||||
|
||||
return a * t * t * t
|
||||
+ b * t * t
|
||||
+ c * t
|
||||
+ d;
|
||||
}
|
||||
|
||||
glm::dvec3 cubicBezier(double t, const glm::dvec3& cp1, const glm::dvec3& cp2,
|
||||
const glm::dvec3& cp3, const glm::dvec3& cp4)
|
||||
{
|
||||
ghoul_assert(t >= 0 && t <= 1.0, "Interpolation variable out of range [0, 1]");
|
||||
|
||||
double a = 1.0 - t;
|
||||
return cp1 * a * a * a
|
||||
+ cp2 * t * a * a * 3.0
|
||||
+ cp3 * t * t * a * 3.0
|
||||
+ cp4 * t * t * t;
|
||||
}
|
||||
|
||||
glm::dvec3 linear(double t, const glm::dvec3 &cp1, const glm::dvec3 &cp2) {
|
||||
ghoul_assert(t >= 0 && t <= 1.0, "Interpolation variable out of range [0, 1]");
|
||||
return cp1 * (1.0 - t) + cp2 * t;
|
||||
}
|
||||
|
||||
glm::dvec3 hermite(double t, const glm::dvec3 &p1, const glm::dvec3 &p2,
|
||||
const glm::dvec3 &tangent1, const glm::dvec3 &tangent2)
|
||||
{
|
||||
ghoul_assert(t >= 0 && t <= 1.0, "Interpolation variable out of range [0, 1]");
|
||||
|
||||
if (t <= 0.0) return p1;
|
||||
if (t >= 1.0) return p2;
|
||||
|
||||
const double t2 = t * t;
|
||||
const double t3 = t2 * t;
|
||||
|
||||
// calculate basis functions
|
||||
double const a0 = (2.0 * t3) - (3.0 * t2) + 1.0;
|
||||
double const a1 = (-2.0 * t3) + (3.0 * t2);
|
||||
double const b0 = t3 - (2.0 * t2) + t;
|
||||
double const b1 = t3 - t2;
|
||||
|
||||
return (a0 * p1) + (a1 * p2) + (b0 * tangent1) + (b1 * tangent2);
|
||||
}
|
||||
|
||||
// uniform if tKnots are equally spaced, or else non uniform
|
||||
glm::dvec3 piecewiseCubicBezier(double t, const std::vector<glm::dvec3>& points,
|
||||
const std::vector<double>& tKnots)
|
||||
{
|
||||
ghoul_assert(
|
||||
points.size() > 4,
|
||||
"Minimum of four control points needed for interpolation"
|
||||
);
|
||||
ghoul_assert(
|
||||
(points.size() - 1) % 3 == 0,
|
||||
"A vector containing 3n + 1 control points must be provided"
|
||||
);
|
||||
int nrSegments = (points.size() - 1) / 3;
|
||||
ghoul_assert(
|
||||
rSegments == (tKnots.size() - 1),
|
||||
"Number of interval times must match number of segments"
|
||||
);
|
||||
|
||||
if (t <= 0.0) return points.front();
|
||||
if (t >= 1.0) return points.back();
|
||||
|
||||
// compute current segment index
|
||||
std::vector<double>::const_iterator segmentEndIt =
|
||||
std::lower_bound(tKnots.begin(), tKnots.end(), t);
|
||||
unsigned int segmentIdx = (segmentEndIt - 1) - tKnots.begin();
|
||||
|
||||
double segmentStart = tKnots[segmentIdx];
|
||||
double segmentDuration = (tKnots[segmentIdx + 1] - tKnots[segmentIdx]);
|
||||
double tScaled = (t - segmentStart) / segmentDuration;
|
||||
|
||||
unsigned int idx = segmentIdx * 3;
|
||||
|
||||
// Interpolate using De Casteljau's algorithm
|
||||
return interpolation::cubicBezier(
|
||||
tScaled,
|
||||
points[idx],
|
||||
points[idx + 1],
|
||||
points[idx + 2],
|
||||
points[idx + 3]
|
||||
);
|
||||
}
|
||||
|
||||
glm::dvec3 piecewiseLinear(double t, const std::vector<glm::dvec3>& points,
|
||||
const std::vector<double>& tKnots)
|
||||
{
|
||||
ghoul_assert(points.size() == tKnots.size(), "Must have equal number of points and times!");
|
||||
ghoul_assert(points.size() > 2, "Minimum of two control points needed for interpolation!");
|
||||
|
||||
size_t nrSegments = points.size() - 1;
|
||||
|
||||
if (t <= 0.0) return points.front();
|
||||
if (t >= 1.0) return points.back();
|
||||
|
||||
// compute current segment index
|
||||
std::vector<double>::const_iterator segmentEndIt =
|
||||
std::lower_bound(tKnots.begin(), tKnots.end(), t);
|
||||
unsigned int idx = (segmentEndIt - 1) - tKnots.begin();
|
||||
|
||||
double segmentStart = tKnots[idx];
|
||||
double segmentDuration = (tKnots[idx + 1] - tKnots[idx]);
|
||||
double tScaled = (t - segmentStart) / segmentDuration;
|
||||
|
||||
return interpolation::linear(tScaled, points[idx], points[idx + 1]);
|
||||
}
|
||||
|
||||
} // interpolation
|
||||
597
src/navigation/pathnavigator.cpp
Normal file
597
src/navigation/pathnavigator.cpp
Normal file
@@ -0,0 +1,597 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/navigation/pathnavigator.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/pathcreator.h>
|
||||
#include <openspace/navigation/pathhelperfunctions.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "PathNavigator";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DefaultCurveOptionInfo = {
|
||||
"DefaultCurveOption",
|
||||
"Default Curve Option",
|
||||
"The defualt curve type chosen when generating a path, if none is specified"
|
||||
// TODO: right now there is no way to specify a type for a single path
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo IncludeRollInfo = {
|
||||
"IncludeRoll",
|
||||
"Include Roll",
|
||||
"If disabled, roll is removed from the interpolation of camera orientation"
|
||||
};
|
||||
|
||||
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 =
|
||||
{
|
||||
"ApplyStopBehaviorWhenIdle",
|
||||
"Apply Stop Behavior When Idle",
|
||||
"If enabled, the camera is controlled using the set stop behavior when "
|
||||
"no path is playing"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SpeedScaleInfo = {
|
||||
"SpeedScale",
|
||||
"Speed Scale",
|
||||
"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."
|
||||
};
|
||||
|
||||
constexpr const openspace::properties::Property::PropertyInfo MinBoundingSphereInfo = {
|
||||
"MinimalValidBoundingSphere",
|
||||
"Minimal Valid Bounding Sphere",
|
||||
"The minimal allowed value for a bounding sphere, in meters. Used for "
|
||||
"computation of target positions and path generation, to avoid issues when "
|
||||
"there is no bounding sphere."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo RelevantNodeTagsInfo = {
|
||||
"RelevantNodeTags",
|
||||
"Relevant Node Tags",
|
||||
"List of tags for the nodes that are relevant for path creation, for example "
|
||||
"when avoiding collisions."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#include "pathnavigator_lua.inl"
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
PathNavigator::PathNavigator()
|
||||
: properties::PropertyOwner({ "PathNavigator" })
|
||||
, _defaultCurveOption(
|
||||
DefaultCurveOptionInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _includeRoll(IncludeRollInfo, false)
|
||||
, _stopBehavior(
|
||||
StopBehaviorInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _applyStopBehaviorWhenIdle(ApplyStopBehaviorWhenIdleInfo, false)
|
||||
, _speedScale(SpeedScaleInfo, 1.f, 0.01f, 2.f)
|
||||
, _orbitSpeedFactor(OrbitSpeedFactorInfo, 0.5, 0.0, 20.0)
|
||||
, _minValidBoundingSphere(MinBoundingSphereInfo, 10.0, 1.0, 3e10)
|
||||
, _relevantNodeTags(RelevantNodeTagsInfo)
|
||||
{
|
||||
_defaultCurveOption.addOptions({
|
||||
{ Path::CurveType::AvoidCollision, "AvoidCollision" },
|
||||
{ Path::CurveType::Linear, "Linear" },
|
||||
{ Path::CurveType::ZoomOutOverview, "ZoomOutOverview"}
|
||||
});
|
||||
addProperty(_defaultCurveOption);
|
||||
|
||||
addProperty(_includeRoll);
|
||||
addProperty(_speedScale);
|
||||
|
||||
// OBS! Stop behavior is broken as of core merge
|
||||
//addProperty(_applyStopBehaviorWhenIdle);
|
||||
|
||||
//// Must be listed in the same order as in enum definition
|
||||
//_stopBehavior.addOptions({
|
||||
// { StopBehavior::None, "None" },
|
||||
// { StopBehavior::Orbit, "Orbit" }
|
||||
//});
|
||||
//_stopBehavior = StopBehavior::None;
|
||||
//addProperty(_stopBehavior);
|
||||
|
||||
//addProperty(_orbitSpeedFactor);
|
||||
|
||||
addProperty(_minValidBoundingSphere);
|
||||
|
||||
_relevantNodeTags = std::vector<std::string>{
|
||||
"planet_solarSystem",
|
||||
"moon_solarSystem"
|
||||
};;
|
||||
_relevantNodeTags.onChange([this]() { findRelevantNodes(); });
|
||||
addProperty(_relevantNodeTags);
|
||||
}
|
||||
|
||||
PathNavigator::~PathNavigator() {} // NOLINT
|
||||
|
||||
Camera* PathNavigator::camera() const {
|
||||
return global::navigationHandler->camera();
|
||||
}
|
||||
|
||||
const SceneGraphNode* PathNavigator::anchor() const {
|
||||
return global::navigationHandler->anchorNode();
|
||||
}
|
||||
|
||||
double PathNavigator::speedScale() const {
|
||||
return _speedScale;
|
||||
}
|
||||
|
||||
bool PathNavigator::hasCurrentPath() const {
|
||||
return _currentPath != nullptr;
|
||||
}
|
||||
|
||||
bool PathNavigator::hasFinished() const {
|
||||
if (!hasCurrentPath()) {
|
||||
return true;
|
||||
}
|
||||
return _currentPath->hasReachedEnd();
|
||||
}
|
||||
|
||||
bool PathNavigator::isPlayingPath() const {
|
||||
return !hasFinished();
|
||||
}
|
||||
|
||||
void PathNavigator::updateCamera(double deltaTime) {
|
||||
ghoul_assert(camera() != nullptr, "Camera must not be nullptr");
|
||||
|
||||
if (!hasCurrentPath()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isPlaying) {
|
||||
//// TODO: Determine how this should work
|
||||
//// OBS! Stop behavior is broken as of core merge
|
||||
//if (hasFinished() && _applyStopBehaviorWhenIdle) {
|
||||
// applyStopBehavior(deltaTime);
|
||||
//}
|
||||
return;
|
||||
}
|
||||
|
||||
// If for some reason the time is no longer paused, pause it again
|
||||
// TODO: Before we get here, one time tick happens. Should move this check to engine
|
||||
if (!global::timeManager->isPaused()) {
|
||||
global::timeManager->setPause(true);
|
||||
LINFO("Cannot start simulation time during camera motion");
|
||||
}
|
||||
|
||||
CameraPose newPose = _currentPath->traversePath(deltaTime);
|
||||
const std::string newAnchor = _currentPath->currentAnchor();
|
||||
|
||||
// Set anchor node in orbitalNavigator, to render visible nodes and add activate
|
||||
// navigation when we reach the end.
|
||||
std::string currentAnchor = anchor()->identifier();
|
||||
if (currentAnchor != newAnchor) {
|
||||
global::navigationHandler->orbitalNavigator().setAnchorNode(newAnchor);
|
||||
}
|
||||
|
||||
if (!_includeRoll) {
|
||||
removeRollRotation(newPose, deltaTime);
|
||||
}
|
||||
|
||||
camera()->setPositionVec3(newPose.position);
|
||||
camera()->setRotation(newPose.rotation);
|
||||
|
||||
if (_currentPath->hasReachedEnd()) {
|
||||
LINFO("Reached end of path");
|
||||
_isPlaying = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PathNavigator::createPath(const ghoul::Dictionary& dictionary) {
|
||||
// TODO: Improve how curve types are handled
|
||||
const int curveType = _defaultCurveOption;
|
||||
|
||||
// Ignore paths that are created during session recording, as the camera
|
||||
// position should have been recorded
|
||||
if (global::sessionRecording->isPlayingBack()) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearPath();
|
||||
try {
|
||||
_currentPath = std::make_unique<Path>(
|
||||
PathCreator::createPath(dictionary, Path::CurveType(curveType))
|
||||
);
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
LERROR("Could not create path");
|
||||
return;
|
||||
}
|
||||
|
||||
LINFO("Successfully generated camera path");
|
||||
}
|
||||
|
||||
void PathNavigator::clearPath() {
|
||||
LINFO("Clearing path...");
|
||||
_currentPath = nullptr;
|
||||
}
|
||||
|
||||
void PathNavigator::startPath() {
|
||||
if (!hasCurrentPath()) {
|
||||
LERROR("There is no path to start");
|
||||
return;
|
||||
}
|
||||
|
||||
//OBS! Until we can handle simulation time: early out if not paused
|
||||
if (!global::timeManager->isPaused()) {
|
||||
LERROR("Simulation time must be paused to run a camera path");
|
||||
return;
|
||||
}
|
||||
|
||||
LINFO("Starting path...");
|
||||
_isPlaying = true;
|
||||
}
|
||||
|
||||
void PathNavigator::abortPath() {
|
||||
if (!_isPlaying) {
|
||||
LWARNING("No camera path is playing");
|
||||
return;
|
||||
}
|
||||
_isPlaying = false;
|
||||
clearPath(); // TODO: instead of clearing this could be handled better
|
||||
|
||||
LINFO("Aborted camera path");
|
||||
}
|
||||
|
||||
void PathNavigator::pausePath() {
|
||||
if (hasFinished()) {
|
||||
LERROR("No path to pause (path is empty or has finished).");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isPlaying) {
|
||||
LERROR("Cannot pause a path that is not playing");
|
||||
return;
|
||||
}
|
||||
|
||||
LINFO("Path paused");
|
||||
_isPlaying = false;
|
||||
}
|
||||
|
||||
void PathNavigator::continuePath() {
|
||||
if (hasFinished()) {
|
||||
LERROR("No path to resume (path is empty or has finished).");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isPlaying) {
|
||||
LERROR("Cannot resume a path that is already playing");
|
||||
return;
|
||||
}
|
||||
|
||||
LINFO("Continuing path...");
|
||||
_isPlaying = true;
|
||||
}
|
||||
|
||||
// Created for debugging
|
||||
std::vector<glm::dvec3> PathNavigator::curvePositions(int nSteps) const {
|
||||
if (!hasCurrentPath()) {
|
||||
LERROR("There is no current path to sample points from.");
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<glm::dvec3> positions;
|
||||
const double du = 1.0 / nSteps;
|
||||
const double length = _currentPath->pathLength();
|
||||
for (double u = 0.0; u < 1.0; u += du) {
|
||||
glm::dvec3 position = _currentPath->interpolatedPose(u * length).position;
|
||||
positions.push_back(position);
|
||||
}
|
||||
positions.push_back(_currentPath->endPoint().position());
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
// Created for debugging
|
||||
std::vector<glm::dquat> PathNavigator::curveOrientations(int nSteps) const {
|
||||
if (!hasCurrentPath()) {
|
||||
LERROR("There is no current path to sample points from.");
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<glm::dquat> orientations;
|
||||
const double du = 1.0 / nSteps;
|
||||
const double length = _currentPath->pathLength();
|
||||
for (double u = 0.0; u <= 1.0; u += du) {
|
||||
const glm::dquat orientation =
|
||||
_currentPath->interpolatedPose(u * length).rotation;
|
||||
orientations.push_back(orientation);
|
||||
}
|
||||
orientations.push_back(_currentPath->endPoint().rotation());
|
||||
|
||||
return orientations;
|
||||
}
|
||||
|
||||
|
||||
// Created for debugging
|
||||
std::vector<glm::dvec3> PathNavigator::curveViewDirections(int nSteps) const {
|
||||
if (!hasCurrentPath()) {
|
||||
LERROR("There is no current path to sample points from.");
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<glm::dvec3> viewDirections;
|
||||
const double du = 1.0 / nSteps;
|
||||
for (double u = 0.0; u < 1.0; u += du) {
|
||||
const glm::dquat orientation = _currentPath->interpolatedPose(u).rotation;
|
||||
const glm::dvec3 direction = glm::normalize(
|
||||
orientation * glm::dvec3(0.0, 0.0, -1.0)
|
||||
);
|
||||
viewDirections.push_back(direction);
|
||||
}
|
||||
|
||||
const glm::dquat orientation = _currentPath->interpolatedPose(1.0).rotation;
|
||||
const glm::dvec3 direction = glm::normalize(
|
||||
orientation * glm::dvec3(0.0, 0.0, -1.0)
|
||||
);
|
||||
viewDirections.push_back(direction);
|
||||
|
||||
return viewDirections;
|
||||
}
|
||||
|
||||
// Created for debugging
|
||||
std::vector<glm::dvec3> PathNavigator::controlPoints() const {
|
||||
if (!hasCurrentPath()) {
|
||||
LERROR("There is no current path to sample points from.");
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<glm::dvec3> points;
|
||||
const std::vector<glm::dvec3> curvePoints = _currentPath->controlPoints();
|
||||
points.insert(points.end(), curvePoints.begin(), curvePoints.end());
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
double PathNavigator::minValidBoundingSphere() const {
|
||||
return _minValidBoundingSphere;
|
||||
}
|
||||
|
||||
const std::vector<SceneGraphNode*>& PathNavigator::relevantNodes() {
|
||||
if (!_hasInitializedRelevantNodes) {
|
||||
findRelevantNodes();
|
||||
_hasInitializedRelevantNodes = true;
|
||||
}
|
||||
|
||||
return _relevantNodes;
|
||||
}
|
||||
|
||||
void PathNavigator::findRelevantNodes() {
|
||||
const std::vector<SceneGraphNode*>& allNodes =
|
||||
global::renderEngine->scene()->allSceneGraphNodes();
|
||||
|
||||
const std::vector<std::string> relevantTags = _relevantNodeTags;
|
||||
|
||||
if (allNodes.empty() || relevantTags.empty()) {
|
||||
_relevantNodes = std::vector<SceneGraphNode*>();
|
||||
return;
|
||||
}
|
||||
|
||||
auto isRelevant = [&](const SceneGraphNode* node) {
|
||||
const std::vector<std::string> tags = node->tags();
|
||||
auto result = std::find_first_of(
|
||||
relevantTags.begin(),
|
||||
relevantTags.end(),
|
||||
tags.begin(),
|
||||
tags.end()
|
||||
);
|
||||
|
||||
// does not match any tags => not interesting
|
||||
if (result == relevantTags.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return node->renderable() && (node->boundingSphere() > 0.0);
|
||||
};
|
||||
|
||||
std::vector<SceneGraphNode*> resultingNodes;
|
||||
std::copy_if(
|
||||
allNodes.begin(),
|
||||
allNodes.end(),
|
||||
std::back_inserter(resultingNodes),
|
||||
isRelevant
|
||||
);
|
||||
|
||||
_relevantNodes = resultingNodes;
|
||||
}
|
||||
|
||||
void PathNavigator::removeRollRotation(CameraPose& pose, double deltaTime) {
|
||||
const glm::dvec3 anchorPos = anchor()->worldPosition();
|
||||
const glm::dvec3 cameraDir = glm::normalize(
|
||||
pose.rotation * Camera::ViewDirectionCameraSpace
|
||||
);
|
||||
const double anchorToPosDistance = glm::distance(anchorPos, pose.position);
|
||||
const double notTooCloseDistance = deltaTime * anchorToPosDistance;
|
||||
glm::dvec3 lookAtPos = pose.position + notTooCloseDistance * cameraDir;
|
||||
glm::dquat rollFreeRotation = helpers::lookAtQuaternion(
|
||||
pose.position,
|
||||
lookAtPos,
|
||||
camera()->lookUpVectorWorldSpace()
|
||||
);
|
||||
pose.rotation = rollFreeRotation;
|
||||
}
|
||||
|
||||
void PathNavigator::applyStopBehavior(double deltaTime) {
|
||||
switch (_stopBehavior) {
|
||||
case StopBehavior::None:
|
||||
// Do nothing
|
||||
break;
|
||||
case StopBehavior::Orbit:
|
||||
orbitAnchorNode(deltaTime);
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
void PathNavigator::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 nodeCenter = anchor()->worldPosition();
|
||||
|
||||
const double speedFactor = 0.1 * _orbitSpeedFactor;
|
||||
|
||||
// Compute orbit speed based on factor and distance to surface
|
||||
const double orbitRadius = glm::distance(prevPosition, nodeCenter);
|
||||
const double distanceToSurface = orbitRadius - anchor()->boundingSphere();
|
||||
const double orbitSpeed = distanceToSurface * speedFactor;
|
||||
|
||||
// Compute a new position along the orbit
|
||||
const glm::dvec3 up = camera()->lookUpVectorWorldSpace();
|
||||
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 - make sure we stay at the same height
|
||||
const glm::dvec3 nodeToNewPos = newPosition - nodeCenter;
|
||||
const double targetHeight = glm::distance(prevPosition, nodeCenter);
|
||||
const double heightDiff = glm::length(nodeToNewPos) - targetHeight;
|
||||
newPosition -= heightDiff * glm::normalize(nodeToNewPos);
|
||||
|
||||
// Rotate along 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);
|
||||
}
|
||||
|
||||
scripting::LuaLibrary PathNavigator::luaLibrary() {
|
||||
return {
|
||||
"pathnavigation",
|
||||
{
|
||||
{
|
||||
"isFlying",
|
||||
&luascriptfunctions::isFlying,
|
||||
{},
|
||||
"",
|
||||
"Returns true if a camera path is currently running, and false otherwise"
|
||||
},
|
||||
{
|
||||
"continuePath",
|
||||
&luascriptfunctions::continuePath,
|
||||
{},
|
||||
"",
|
||||
"Continue playing a paused camera path"
|
||||
},
|
||||
{
|
||||
"pausePath",
|
||||
&luascriptfunctions::pausePath,
|
||||
{},
|
||||
"",
|
||||
"Pause a playing camera path"
|
||||
},
|
||||
{
|
||||
"stopPath",
|
||||
&luascriptfunctions::stopPath,
|
||||
{},
|
||||
"",
|
||||
"Stops a path, if one is being played"
|
||||
},
|
||||
{
|
||||
"goTo",
|
||||
&luascriptfunctions::goTo,
|
||||
{},
|
||||
"string [, bool, double]",
|
||||
"Move the camera to the node with the specified name. The optional double "
|
||||
"specifies the duration of the motion. If the optional bool is set to true "
|
||||
"the target up vector for camera is set based on the target node. Either of "
|
||||
"the optional parameters can be left out."
|
||||
},
|
||||
{
|
||||
"goToHeight",
|
||||
&luascriptfunctions::goToHeight,
|
||||
{},
|
||||
"string, double [, bool, double]",
|
||||
"Move the camera to the node with the specified name. The second input "
|
||||
"parameter is the desired target height. The optional double "
|
||||
"specifies the duration of the motion. If the optional bool is set to true "
|
||||
"the target up vector for camera is set based on the target node. Either of "
|
||||
"the optional parameters can be left out."
|
||||
},
|
||||
//{
|
||||
// "goToGeo",
|
||||
// &luascriptfunctions::goToGeo,
|
||||
// {},
|
||||
// "string, double, double, double [, bool, double]",
|
||||
// "Move the camera to the globe with the name given by the input string. "
|
||||
// "The next three input parameters are latitude, longitude and altitude. "
|
||||
// "The optional double specifies the duration of the motion. If the optional "
|
||||
// "bool is set to true the target up vector for camera is set based on the "
|
||||
// "target node. Either of the optional parameters can be left out."
|
||||
//},
|
||||
{
|
||||
"generatePath",
|
||||
&luascriptfunctions::generatePath,
|
||||
{},
|
||||
"table",
|
||||
"Generate the path as described by the lua table input argument"
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
272
src/navigation/pathnavigator_lua.inl
Normal file
272
src/navigation/pathnavigator_lua.inl
Normal file
@@ -0,0 +1,272 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/globebrowsing/globebrowsingmodule.h> // TODO: remove dependancy
|
||||
//#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
namespace {
|
||||
constexpr const double Epsilon = 1e-12;
|
||||
} // namespace
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int isFlying(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::isFlying");
|
||||
|
||||
bool hasFinished = global::navigationHandler->pathNavigator().hasFinished();
|
||||
|
||||
ghoul::lua::push(L, !hasFinished);
|
||||
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int continuePath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::continuePath");
|
||||
|
||||
global::navigationHandler->pathNavigator().continuePath();
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pausePath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::pausePath");
|
||||
|
||||
global::navigationHandler->pathNavigator().pausePath();
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stopPath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::stopPath");
|
||||
|
||||
global::navigationHandler->pathNavigator().abortPath();
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// All the goTo function has the same two optional input parameters at the end. The
|
||||
// purpose of this function is to handle these input parameters and add the result
|
||||
// to the dictionary specifying the instruction for a camera path.
|
||||
int handleOptionalGoToParameters(lua_State* L, const int startLocation,
|
||||
const int nArguments,
|
||||
ghoul::Dictionary& resultInstruction)
|
||||
{
|
||||
const bool firstIsNumber = (lua_isnumber(L, startLocation) != 0);
|
||||
const bool firstIsBool = (lua_isboolean(L, startLocation) != 0);
|
||||
|
||||
if (!(firstIsNumber || firstIsBool)) {
|
||||
const char* msg = lua_pushfstring(
|
||||
L,
|
||||
"%s or %s expected, got %s",
|
||||
lua_typename(L, LUA_TNUMBER),
|
||||
lua_typename(L, LUA_TBOOLEAN),
|
||||
luaL_typename(L, -1)
|
||||
);
|
||||
return ghoul::lua::luaError(
|
||||
L, fmt::format("bad argument #{} ({})", startLocation, msg)
|
||||
);
|
||||
}
|
||||
|
||||
int location = startLocation;
|
||||
|
||||
if (firstIsBool) {
|
||||
const bool useUpFromTarget = (lua_toboolean(L, location) == 1);
|
||||
resultInstruction.setValue("UseTargetUpDirection", useUpFromTarget);
|
||||
|
||||
if (nArguments > startLocation) {
|
||||
location++;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstIsNumber || nArguments > startLocation) {
|
||||
double duration = ghoul::lua::value<double>(L, location);
|
||||
if (duration <= Epsilon) {
|
||||
lua_settop(L, 0);
|
||||
return ghoul::lua::luaError(L, "Duration must be larger than zero.");
|
||||
}
|
||||
resultInstruction.setValue("Duration", duration);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goTo(lua_State* L) {
|
||||
int nArguments = ghoul::lua::checkArgumentsAndThrow(L, { 1, 3 }, "lua::goTo");
|
||||
|
||||
const std::string& nodeIdentifier = ghoul::lua::value<std::string>(L, 1);
|
||||
|
||||
if (!sceneGraphNode(nodeIdentifier)) {
|
||||
lua_settop(L, 0);
|
||||
return ghoul::lua::luaError(L, "Unknown node name: " + nodeIdentifier);
|
||||
}
|
||||
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary insDict;
|
||||
insDict.setValue("Type", "Node"s);
|
||||
insDict.setValue("Target", nodeIdentifier);
|
||||
|
||||
if (nArguments > 1) {
|
||||
int result = handleOptionalGoToParameters(L, 2, nArguments, insDict);
|
||||
if (result != 0) {
|
||||
return result; // An error occurred
|
||||
}
|
||||
}
|
||||
|
||||
global::navigationHandler->pathNavigator().createPath(insDict);
|
||||
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
|
||||
lua_settop(L, 0);
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goToHeight(lua_State* L) {
|
||||
int nArguments = ghoul::lua::checkArgumentsAndThrow(L, { 2, 4 }, "lua::goToHeight");
|
||||
|
||||
const std::string& nodeIdentifier = ghoul::lua::value<std::string>(L, 1);
|
||||
|
||||
if (!sceneGraphNode(nodeIdentifier)) {
|
||||
lua_settop(L, 0);
|
||||
return ghoul::lua::luaError(L, "Unknown node name: " + nodeIdentifier);
|
||||
}
|
||||
|
||||
double height = ghoul::lua::value<double>(L, 2);
|
||||
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary insDict;
|
||||
insDict.setValue("Type", "Node"s);
|
||||
insDict.setValue("Target", nodeIdentifier);
|
||||
insDict.setValue("Height", height);
|
||||
|
||||
if (nArguments > 2) {
|
||||
int result = handleOptionalGoToParameters(L, 3, nArguments, insDict);
|
||||
if (result != 0) {
|
||||
return result; // An error occurred
|
||||
}
|
||||
}
|
||||
|
||||
global::navigationHandler->pathNavigator().createPath(insDict);
|
||||
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
|
||||
lua_settop(L, 0);
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//// @TODO (emmbr 2020-11-06) Ideally, this module shouldn't depend on things from
|
||||
//// Globebrowsing, but we want it for an istallation. Later on, move this functionality
|
||||
//// somewhere else. Maybe combine with the existing "goToGeo" in globebrowsing?
|
||||
//int goToGeo(lua_State* L) {
|
||||
// int nArguments = ghoul::lua::checkArgumentsAndThrow(L, { 4, 6 }, "lua::goToGeo");
|
||||
//
|
||||
// const std::string& nodeIdentifier = ghoul::lua::value<std::string>(L, 1);
|
||||
// const SceneGraphNode* n = sceneGraphNode(nodeIdentifier);
|
||||
// if (!n) {
|
||||
// lua_settop(L, 0);
|
||||
// return ghoul::lua::luaError(L, "Unknown globe name: " + nodeIdentifier);
|
||||
// }
|
||||
//
|
||||
// const double latitude = ghoul::lua::value<double>(L, 2);
|
||||
// const double longitude = ghoul::lua::value<double>(L, 3);
|
||||
// const double altitude = ghoul::lua::value<double>(L, 4);
|
||||
//
|
||||
// using RenderableGlobe = openspace::globebrowsing::RenderableGlobe;
|
||||
// const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
// if (!globe) {
|
||||
// return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
|
||||
// }
|
||||
//
|
||||
// // Compute the relative position based on the input values
|
||||
// glm::dvec3 positionModelCoords = global::moduleEngine->module<GlobeBrowsingModule>()
|
||||
// ->cartesianCoordinatesFromGeo(
|
||||
// *globe,
|
||||
// latitude,
|
||||
// longitude,
|
||||
// altitude
|
||||
// );
|
||||
//
|
||||
// using namespace std::string_literals;
|
||||
// ghoul::Dictionary insDict;
|
||||
// insDict.setValue("Type", "Node"s);
|
||||
// insDict.setValue("Target", nodeIdentifier);
|
||||
// insDict.setValue("Position", positionModelCoords);
|
||||
//
|
||||
// if (nArguments > 4) {
|
||||
// int result = handleOptionalGoToParameters(L, 5, nArguments, insDict);
|
||||
// if (result != 0) {
|
||||
// return result; // An error occurred
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// global::navigationHandler->pathNavigator().createPath(insDict);
|
||||
//
|
||||
// if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
// global::navigationHandler->pathNavigator().startPath();
|
||||
// }
|
||||
//
|
||||
// lua_settop(L, 0);
|
||||
// ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
int generatePath(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::generatePath");
|
||||
|
||||
ghoul::Dictionary dictionary;
|
||||
ghoul::lua::luaDictionaryFromState(L, dictionary);
|
||||
|
||||
global::navigationHandler->pathNavigator().createPath(dictionary);
|
||||
|
||||
if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
|
||||
global::navigationHandler->pathNavigator().startPath();
|
||||
}
|
||||
|
||||
lua_settop(L, 0);
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
117
src/navigation/waypoint.cpp
Normal file
117
src/navigation/waypoint.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/navigation/waypoint.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/navigation/pathnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "Waypoint";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
Waypoint::Waypoint(const glm::dvec3& pos, const glm::dquat& rot, const std::string& ref)
|
||||
: nodeIdentifier(ref)
|
||||
{
|
||||
pose = { pos, rot };
|
||||
|
||||
const SceneGraphNode* node = sceneGraphNode(nodeIdentifier);
|
||||
if (!node) {
|
||||
LERROR(fmt::format("Could not find node '{}'", nodeIdentifier));
|
||||
return;
|
||||
}
|
||||
validBoundingSphere = findValidBoundingSphere(node);
|
||||
}
|
||||
|
||||
Waypoint::Waypoint(const NavigationState& ns) {
|
||||
const SceneGraphNode* anchorNode = sceneGraphNode(ns.anchor);
|
||||
|
||||
if (!anchorNode) {
|
||||
LERROR(fmt::format("Could not find node '{}' to target", ns.anchor));
|
||||
return;
|
||||
}
|
||||
|
||||
nodeIdentifier = ns.anchor;
|
||||
validBoundingSphere = findValidBoundingSphere(anchorNode);
|
||||
pose = ns.cameraPose();
|
||||
}
|
||||
|
||||
glm::dvec3 Waypoint::position() const {
|
||||
return pose.position;
|
||||
}
|
||||
|
||||
glm::dquat Waypoint::rotation() const {
|
||||
return pose.rotation;
|
||||
}
|
||||
|
||||
SceneGraphNode* Waypoint::node() const {
|
||||
return sceneGraphNode(nodeIdentifier);
|
||||
}
|
||||
|
||||
double Waypoint::findValidBoundingSphere(const SceneGraphNode* node) {
|
||||
double bs = static_cast<double>(node->boundingSphere());
|
||||
|
||||
const double minValidBoundingSphere =
|
||||
global::navigationHandler->pathNavigator().minValidBoundingSphere();
|
||||
|
||||
if (bs < minValidBoundingSphere) {
|
||||
// If the bs of the target is too small, try to find a good value in a child node.
|
||||
// Only check the closest children, to avoid deep traversal in the scene graph.
|
||||
// Also, the possibility to find a bounding sphere represents the visual size of
|
||||
// the target well is higher for these nodes.
|
||||
for (SceneGraphNode* child : node->children()) {
|
||||
bs = static_cast<double>(child->boundingSphere());
|
||||
if (bs > minValidBoundingSphere) {
|
||||
LWARNING(fmt::format(
|
||||
"The scene graph node '{}' has no, or a very small, bounding sphere. "
|
||||
"Using bounding sphere of child node '{}' in computations.",
|
||||
node->identifier(),
|
||||
child->identifier()
|
||||
));
|
||||
|
||||
return bs;
|
||||
}
|
||||
}
|
||||
|
||||
LWARNING(fmt::format(
|
||||
"The scene graph node '{}' has no, or a very small, bounding sphere. Using "
|
||||
"minimal value. This might lead to unexpected results.",
|
||||
node->identifier())
|
||||
);
|
||||
|
||||
bs = minValidBoundingSphere;
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
@@ -24,14 +24,14 @@
|
||||
|
||||
#include <openspace/network/parallelpeer.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <openspace/rendering/abufferrenderer.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/performance/performancemanager.h>
|
||||
@@ -36,7 +37,6 @@
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/rendering/deferredcaster.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <openspace/rendering/framebufferrenderer.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/rendering/deferredcaster.h>
|
||||
@@ -33,7 +34,6 @@
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/mission/missionmanager.h>
|
||||
#include <openspace/rendering/abufferrenderer.h>
|
||||
#include <openspace/rendering/dashboard.h>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
@@ -32,7 +33,6 @@
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <openspace/scene/profile.h>
|
||||
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/properties/property.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
@@ -445,7 +446,7 @@ Profile::ParsingError::ParsingError(Severity severity_, std::string msg)
|
||||
|
||||
void Profile::saveCurrentSettingsToProfile(const properties::PropertyOwner& rootOwner,
|
||||
std::string currentTime,
|
||||
interaction::NavigationHandler::NavigationState navState)
|
||||
interaction::NavigationState navState)
|
||||
{
|
||||
_version = Profile::CurrentVersion;
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -88,8 +89,7 @@ int saveSettingsToProfile(lua_State* L) {
|
||||
|
||||
const properties::PropertyOwner& root = *global::rootPropertyOwner;
|
||||
std::string currentTime = std::string(global::timeManager->time().ISO8601());
|
||||
interaction::NavigationHandler::NavigationState navState =
|
||||
global::navigationHandler->navigationState();
|
||||
interaction::NavigationState navState = global::navigationHandler->navigationState();
|
||||
global::profile->saveCurrentSettingsToProfile(root, currentTime, navState);
|
||||
global::configuration->profile = saveFilePath;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
@@ -34,7 +35,6 @@
|
||||
#include <openspace/scene/scenelicensewriter.h>
|
||||
#include <openspace/scene/sceneinitializer.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
@@ -520,7 +520,7 @@ TEST_CASE("Save settings to profile", "[profile]") {
|
||||
p1 = 2.f;
|
||||
p2 = "test-string";
|
||||
|
||||
interaction::NavigationHandler::NavigationState state;
|
||||
interaction::NavigationState state;
|
||||
state.anchor = "anchor";
|
||||
state.aim = "aim";
|
||||
state.referenceFrame = "refFrame";
|
||||
|
||||
Reference in New Issue
Block a user