mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-22 12:59:07 -06:00
Introduce engine modes to handle Camera path and session recording transitions
* Clarifies which system is control over time and camera at what time * Fixes #1845 * Prevent invalid switching between session recoring and camera path playback * Some cleanup, mosly of SessionRecording and NavigationHandler. Also, remove ExternInteraction and some other unused/nonexisting functions
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct CameraPose;
|
||||
class SceneGraphNode;
|
||||
|
||||
/**
|
||||
@@ -67,6 +68,7 @@ public:
|
||||
~Camera() = default;
|
||||
|
||||
// Mutators
|
||||
void setPose(CameraPose pose);
|
||||
void setPositionVec3(glm::dvec3 pos);
|
||||
void setRotation(glm::dquat rotation);
|
||||
void setScaling(float scaling);
|
||||
|
||||
@@ -65,6 +65,15 @@ struct CommandlineArguments {
|
||||
|
||||
class OpenSpaceEngine {
|
||||
public:
|
||||
// A mode that specifies which part of the system is currently in control.
|
||||
// The mode can be used to limit certain features, like setting time, navigation
|
||||
// or triggering scripts
|
||||
enum class Mode {
|
||||
UserControl = 0,
|
||||
SessionRecordingPlayback,
|
||||
CameraPath
|
||||
};
|
||||
|
||||
OpenSpaceEngine();
|
||||
~OpenSpaceEngine();
|
||||
|
||||
@@ -94,6 +103,10 @@ public:
|
||||
|
||||
void toggleShutdownMode();
|
||||
|
||||
Mode currentMode() const;
|
||||
bool setMode(Mode newMode);
|
||||
void resetMode();
|
||||
|
||||
// Guaranteed to return a valid pointer
|
||||
AssetManager& assetManager();
|
||||
LoadingScreen* loadingScreen();
|
||||
@@ -113,7 +126,6 @@ private:
|
||||
void loadFonts();
|
||||
|
||||
void runGlobalCustomizationScripts();
|
||||
void configureLogging();
|
||||
std::string generateFilePath(std::string openspaceRelativePath);
|
||||
void resetPropertyChangeFlagsOfSubowners(openspace::properties::PropertyOwner* po);
|
||||
|
||||
@@ -137,6 +149,8 @@ private:
|
||||
// The first frame might take some more time in the update loop, so we need to know to
|
||||
// disable the synchronization; otherwise a hardware sync will kill us after 1 minute
|
||||
bool _isRenderingFirstFrame = true;
|
||||
|
||||
Mode _currentMode = Mode::UserControl;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* 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___EXTERNINTERACTION___H__
|
||||
#define __OPENSPACE_CORE___EXTERNINTERACTION___H__
|
||||
|
||||
#include <openspace/network/messagestructures.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <ghoul/io/socket/tcpsocket.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class ExternInteraction : public properties::PropertyOwner {
|
||||
public:
|
||||
ExternInteraction();
|
||||
/**
|
||||
* Method that generates a keyframeNavigator CameraPose from a CameraKeyframe
|
||||
* object, and then adds this to the navigationHandler's keyframe navigator.
|
||||
* \param kf The camera keyframe to add.
|
||||
*/
|
||||
void cameraInteraction(datamessagestructures::CameraKeyframe kf);
|
||||
/**
|
||||
* Method that generates a TimeKeyframeData from a TimeKeyframe object, and
|
||||
* then adds this to the timeManager.
|
||||
* \param kf The time keyframe to add.
|
||||
*/
|
||||
void timeInteraction(datamessagestructures::TimeKeyframe kf);
|
||||
/**
|
||||
* Method that passes a ScriptMessage object to the script engine, calling its
|
||||
* queueScript method to add it for execution.
|
||||
* \param sm The ScriptMessage object to queue in the script engine.
|
||||
*/
|
||||
void scriptInteraction(datamessagestructures::ScriptMessage sm);
|
||||
/**
|
||||
* Method that accepts a reference to a CameraKeyframe object, and populates
|
||||
* it with the current properties of the camera from the navigation handler.
|
||||
* \returns CameraKeyframe with current state from NavigationHandler.
|
||||
*/
|
||||
datamessagestructures::CameraKeyframe generateCameraKeyframe();
|
||||
/**
|
||||
* Method that accepts a reference to a TimeKeyframe object, and populates
|
||||
* it with the current time values from the application time manager.
|
||||
* \returns TimeKeyframe The time keyframe.
|
||||
*/
|
||||
datamessagestructures::TimeKeyframe generateTimeKeyframe();
|
||||
/**
|
||||
* Method that accepts a reference to a ScriptMessage object and a script
|
||||
* string, and populates the ScriptMessage with the script and timestamp
|
||||
* of the current application time.
|
||||
* \param script The script to execute in std::string form.
|
||||
* \returns ScriptMessage The ScriptMessage data structure with script.
|
||||
*/
|
||||
datamessagestructures::ScriptMessage generateScriptMessage(std::string script);
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___EXTERNINTERACTION___H__
|
||||
@@ -25,7 +25,8 @@
|
||||
#ifndef __OPENSPACE_CORE___SESSIONRECORDING___H__
|
||||
#define __OPENSPACE_CORE___SESSIONRECORDING___H__
|
||||
|
||||
#include <openspace/interaction/externinteraction.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
@@ -489,12 +490,12 @@ public:
|
||||
static std::string readHeaderElement(std::ifstream& stream, size_t readLen_chars);
|
||||
|
||||
/**
|
||||
* Reads header information from a session recording file
|
||||
*
|
||||
* \param stringstream reference to ifstream that contains the session recording file data
|
||||
* \param readLen_chars number of characters to be read, which may be the expected
|
||||
* length of the header line, or an arbitrary number of characters within it
|
||||
*/
|
||||
* Reads header information from a session recording file
|
||||
*
|
||||
* \param stringstream reference to ifstream that contains the session recording file data
|
||||
* \param readLen_chars number of characters to be read, which may be the expected
|
||||
* length of the header line, or an arbitrary number of characters within it
|
||||
*/
|
||||
static std::string readHeaderElement(std::stringstream& stream, size_t readLen_chars);
|
||||
|
||||
/**
|
||||
@@ -596,12 +597,11 @@ protected:
|
||||
Script,
|
||||
Invalid
|
||||
};
|
||||
struct timelineEntry {
|
||||
struct TimelineEntry {
|
||||
RecordedType keyframeType;
|
||||
unsigned int idxIntoKeyframeTypeArray;
|
||||
Timestamps t3stamps;
|
||||
};
|
||||
ExternInteraction _externInteract;
|
||||
double _timestampRecordStarted = 0.0;
|
||||
Timestamps _timestamps3RecordStarted;
|
||||
double _timestampPlaybackStarted_application = 0.0;
|
||||
@@ -622,6 +622,8 @@ protected:
|
||||
bool playbackScript();
|
||||
bool playbackAddEntriesToTimeline();
|
||||
void signalPlaybackFinishedForComponent(RecordedType type);
|
||||
void handlePlaybackEnd();
|
||||
|
||||
bool findFirstCameraKeyframeInTimeline();
|
||||
Timestamps generateCurrentTimestamp3(double keyframeTime);
|
||||
static void saveStringToFile(const std::string& s, unsigned char* kfBuffer,
|
||||
@@ -635,7 +637,7 @@ protected:
|
||||
datamessagestructures::TimeKeyframe keyframe, int lineNum);
|
||||
bool addKeyframe(Timestamps t3stamps,
|
||||
std::string scriptToQueue, int lineNum);
|
||||
bool addKeyframeToTimeline(std::vector<timelineEntry>& timeline, RecordedType type,
|
||||
bool addKeyframeToTimeline(std::vector<TimelineEntry>& timeline, RecordedType type,
|
||||
size_t indexIntoTypeKeyframes, Timestamps t3stamps, int lineNum);
|
||||
|
||||
void initializePlayback_time(double now);
|
||||
@@ -744,10 +746,10 @@ protected:
|
||||
std::vector<interaction::KeyframeNavigator::CameraPose> _keyframesCamera;
|
||||
std::vector<datamessagestructures::TimeKeyframe> _keyframesTime;
|
||||
std::vector<std::string> _keyframesScript;
|
||||
std::vector<timelineEntry> _timeline;
|
||||
std::vector<TimelineEntry> _timeline;
|
||||
|
||||
std::vector<std::string> _keyframesSavePropertiesBaseline_scripts;
|
||||
std::vector<timelineEntry> _keyframesSavePropertiesBaseline_timeline;
|
||||
std::vector<TimelineEntry> _keyframesSavePropertiesBaseline_timeline;
|
||||
std::vector<std::string> _propertyBaselinesSaved;
|
||||
const std::vector<std::string> _propertyBaselineRejects = {
|
||||
"NavigationHandler.OrbitalNavigator.Anchor",
|
||||
|
||||
@@ -76,7 +76,6 @@ public:
|
||||
void removeKeyframesAfter(double timestamp, Inclusive inclusive = Inclusive::No);
|
||||
void clearKeyframes();
|
||||
size_t nKeyframes() const;
|
||||
const std::vector<datamessagestructures::CameraKeyframe>& keyframes() const;
|
||||
double currentTime() const;
|
||||
void setTimeReferenceMode(KeyframeTimeRef refType, double referenceTimestamp);
|
||||
|
||||
|
||||
@@ -68,16 +68,12 @@ public:
|
||||
|
||||
// Mutators
|
||||
void setFocusNode(SceneGraphNode* node);
|
||||
void resetCameraDirection();
|
||||
|
||||
void setCamera(Camera* camera);
|
||||
void setInterpolationTime(float durationInSeconds);
|
||||
|
||||
void updateCamera(double deltaTime);
|
||||
void setEnableKeyFrameInteraction();
|
||||
void setDisableKeyFrameInteraction();
|
||||
void triggerPlaybackStart();
|
||||
void stopPlayback();
|
||||
|
||||
void resetNavigationUpdateVariables();
|
||||
|
||||
// Accessors
|
||||
Camera* camera() const;
|
||||
@@ -155,8 +151,7 @@ public:
|
||||
private:
|
||||
void applyNavigationState(const NavigationState& ns);
|
||||
void updateCameraTransitions();
|
||||
|
||||
bool _playbackModeEnabled = false;
|
||||
void clearGlobalJoystickStates();
|
||||
|
||||
MouseInputState _mouseInputState;
|
||||
KeyboardInputState _keyboardInputState;
|
||||
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
void startRetargetAim();
|
||||
float retargetInterpolationTime() const;
|
||||
void setRetargetInterpolationTime(float durationInSeconds);
|
||||
void resetNodeMovements();
|
||||
void updatePreviousStateVariables();
|
||||
|
||||
JoystickCameraStates& joystickStates();
|
||||
const JoystickCameraStates& joystickStates() const;
|
||||
@@ -131,6 +131,9 @@ private:
|
||||
bool resetVelocitiesOnChange = true);
|
||||
void setAimNode(const SceneGraphNode* aimNode);
|
||||
|
||||
void updatePreviousAnchorState();
|
||||
void updatePreviousAimState();
|
||||
|
||||
Camera* _camera;
|
||||
|
||||
Friction _friction;
|
||||
|
||||
57
include/openspace/network/messagestructureshelper.h
Normal file
57
include/openspace/network/messagestructureshelper.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* 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___MESSAGESTRUCTURESHELPER___H__
|
||||
#define __OPENSPACE_CORE___MESSAGESTRUCTURESHELPER___H__
|
||||
|
||||
#include <openspace/network/messagestructures.h>
|
||||
|
||||
namespace openspace::datamessagestructures {
|
||||
|
||||
/**
|
||||
* Method that creates a CameraKeyframe object and populates
|
||||
* it with the current properties of the camera from the navigation handler.
|
||||
* \returns CameraKeyframe with current state from NavigationHandler
|
||||
*/
|
||||
CameraKeyframe generateCameraKeyframe();
|
||||
|
||||
/**
|
||||
* Method that creates a TimeKeyframe object and populates
|
||||
* it with the current time values from the application time manager.
|
||||
* \returns TimeKeyframe The time keyframe
|
||||
*/
|
||||
TimeKeyframe generateTimeKeyframe();
|
||||
|
||||
/**
|
||||
* Method that creates a ScriptMessage object from a given script
|
||||
* string, and populates the ScriptMessage with the script and timestamp
|
||||
* of the current application time.
|
||||
* \param script The script to execute in std::string form
|
||||
* \returns ScriptMessage The ScriptMessage data structure with script
|
||||
*/
|
||||
ScriptMessage generateScriptMessage(std::string script);
|
||||
|
||||
} // namespace openspace::datamessagestructures
|
||||
|
||||
#endif // __OPENSPACE_CORE___MESSAGESTRUCTURESHELPER___H__
|
||||
@@ -25,16 +25,13 @@
|
||||
#ifndef __OPENSPACE_CORE___PARALLELPEER___H__
|
||||
#define __OPENSPACE_CORE___PARALLELPEER___H__
|
||||
|
||||
#include <openspace/network/parallelconnection.h>
|
||||
#include <openspace/interaction/externinteraction.h>
|
||||
#include <openspace/network/messagestructures.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/network/messagestructures.h>
|
||||
#include <openspace/network/parallelconnection.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/designpattern/event.h>
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
@@ -133,8 +130,6 @@ private:
|
||||
std::unique_ptr<std::thread> _receiveThread = nullptr;
|
||||
std::shared_ptr<ghoul::Event<>> _connectionEvent;
|
||||
|
||||
ExternInteraction _externInteract;
|
||||
|
||||
ParallelConnection _connection;
|
||||
|
||||
TimeManager::CallbackHandle _timeJumpCallback = -1;
|
||||
|
||||
@@ -150,16 +150,6 @@ public:
|
||||
*/
|
||||
void setTimeReferenceMode(openspace::interaction::KeyframeTimeRef refType);
|
||||
|
||||
/**
|
||||
* Sets the mode for scripts being run from playback
|
||||
*/
|
||||
void triggerPlaybackStart();
|
||||
|
||||
/**
|
||||
* Sets the flag for scripts no longer being run from playback
|
||||
*/
|
||||
void stopPlayback();
|
||||
|
||||
static LuaLibrary luaLibrary();
|
||||
void setModeApplicationTime();
|
||||
void setModeRecordedTime();
|
||||
@@ -174,7 +164,6 @@ private:
|
||||
|
||||
int _currentIndex = 0;
|
||||
double _currentTime = 0;
|
||||
bool _playbackModeEnabled = false;
|
||||
|
||||
openspace::interaction::KeyframeTimeRef _timeframeMode
|
||||
= openspace::interaction::KeyframeTimeRef::Absolute_simTimeJ2000;
|
||||
|
||||
@@ -126,8 +126,6 @@ public:
|
||||
void removeTimeChangeCallback(CallbackHandle handle);
|
||||
void removeDeltaTimeChangeCallback(CallbackHandle handle);
|
||||
void removeDeltaTimeStepsChangeCallback(CallbackHandle handle);
|
||||
void triggerPlaybackStart();
|
||||
void stopPlayback();
|
||||
void removeTimeJumpCallback(CallbackHandle handle);
|
||||
void removeTimelineChangeCallback(CallbackHandle handle);
|
||||
|
||||
@@ -142,6 +140,8 @@ private:
|
||||
double currentApplicationTimeForInterpolation() const;
|
||||
double previousApplicationTimeForInterpolation() const;
|
||||
|
||||
bool isPlayingBackSessionRecording() const;
|
||||
|
||||
Timeline<TimeKeyframeData> _timeline;
|
||||
SyncData<Time> _currentTime;
|
||||
SyncData<Time> _integrateFromTime;
|
||||
@@ -171,7 +171,6 @@ private:
|
||||
|
||||
double _latestConsumedTimestamp = -std::numeric_limits<double>::max();
|
||||
int _nextCallbackHandle = 0;
|
||||
bool _playbackModeEnabled = false;
|
||||
|
||||
std::vector<std::pair<CallbackHandle, TimeChangeCallback>> _timeChangeCallbacks;
|
||||
std::vector<std::pair<CallbackHandle, TimeChangeCallback>> _deltaTimeChangeCallbacks;
|
||||
|
||||
@@ -58,7 +58,6 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/keyboardinputstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/mousecamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/scriptcamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/externinteraction.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/sessionrecording.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/sessionrecording_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/websocketinputstate.cpp
|
||||
@@ -80,6 +79,7 @@ set(OPENSPACE_SOURCE
|
||||
${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/messagestructureshelper.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/network/parallelconnection.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/network/parallelpeer.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/network/parallelpeer_lua.inl
|
||||
@@ -242,7 +242,6 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/keybindingmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/keyboardinputstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/mousecamerastates.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
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/sessionrecording.inl
|
||||
@@ -266,6 +265,7 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/parallelpeer.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/parallelserver.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/messagestructures.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/messagestructureshelper.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/properties/listproperty.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/properties/listproperty.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/properties/numericalproperty.h
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace openspace {
|
||||
@@ -43,6 +44,11 @@ Camera::Camera(const Camera& o)
|
||||
, _cachedLookupVector(o._cachedLookupVector)
|
||||
{}
|
||||
|
||||
void Camera::setPose(CameraPose pose) {
|
||||
setPositionVec3(std::move(pose.position));
|
||||
setRotation(std::move(pose.rotation));
|
||||
}
|
||||
|
||||
void Camera::setPositionVec3(glm::dvec3 pos) {
|
||||
if (!glm::any(glm::isnan(pos))) {
|
||||
std::lock_guard _lock(_mutex);
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/logging/visualstudiooutputlog.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/misc/stacktrace.h>
|
||||
#include <ghoul/misc/stringconversion.h>
|
||||
@@ -105,6 +106,16 @@ namespace {
|
||||
|
||||
constexpr const char* _loggerCat = "OpenSpaceEngine";
|
||||
|
||||
constexpr std::string_view stringify(openspace::OpenSpaceEngine::Mode m) {
|
||||
using Mode = openspace::OpenSpaceEngine::Mode;
|
||||
switch (m) {
|
||||
case Mode::UserControl: return "UserControl";
|
||||
case Mode::CameraPath: return "CameraPath";
|
||||
case Mode::SessionRecordingPlayback: return "SessionRecording";
|
||||
default: throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
openspace::properties::Property::PropertyInfo PrintEventsInfo = {
|
||||
"PrintEvents",
|
||||
"Print Events",
|
||||
@@ -784,7 +795,7 @@ void OpenSpaceEngine::loadAssets() {
|
||||
static_cast<float>(sync->nSynchronizedBytes()) /
|
||||
static_cast<float>(sync->nTotalBytes());
|
||||
}(sync);
|
||||
|
||||
|
||||
_loadingScreen->updateItem(
|
||||
sync->identifier(),
|
||||
sync->name(),
|
||||
@@ -813,7 +824,7 @@ void OpenSpaceEngine::loadAssets() {
|
||||
allAssets.end(),
|
||||
[](const Asset* asset) { return asset->isInitialized() || asset->isFailed(); }
|
||||
);
|
||||
|
||||
|
||||
if (finishedLoading) {
|
||||
break;
|
||||
}
|
||||
@@ -1604,6 +1615,39 @@ void OpenSpaceEngine::toggleShutdownMode() {
|
||||
}
|
||||
}
|
||||
|
||||
OpenSpaceEngine::Mode OpenSpaceEngine::currentMode() const {
|
||||
return _currentMode;
|
||||
}
|
||||
|
||||
bool OpenSpaceEngine::setMode(Mode newMode) {
|
||||
if (_currentMode == Mode::CameraPath && newMode == Mode::CameraPath) {
|
||||
// Special case: It is okay to trigger another camera path while one is
|
||||
// already playing. So just return that we were successful
|
||||
return true;
|
||||
}
|
||||
else if (newMode == _currentMode) {
|
||||
LERROR("Cannot switch to the currectly active mode");
|
||||
return false;
|
||||
}
|
||||
else if (_currentMode != Mode::UserControl && newMode != Mode::UserControl) {
|
||||
LERROR(fmt::format(
|
||||
"Cannot switch to mode '{}' when in '{}' mode",
|
||||
stringify(newMode), stringify(_currentMode)
|
||||
));
|
||||
return false;
|
||||
}
|
||||
|
||||
LDEBUG(fmt::format("Mode: {}", stringify(newMode)));
|
||||
|
||||
_currentMode = newMode;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenSpaceEngine::resetMode() {
|
||||
_currentMode = Mode::UserControl;
|
||||
LDEBUG(fmt::format("Reset engine mode to {}", stringify(_currentMode)));
|
||||
}
|
||||
|
||||
void setCameraFromProfile(const Profile& p) {
|
||||
if (!p.camera.has_value()) {
|
||||
throw ghoul::RuntimeError("No 'camera' entry exists in the startup profile");
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/events/eventengine.h>
|
||||
#include <openspace/interaction/tasks/convertrecfileversiontask.h>
|
||||
@@ -33,6 +34,7 @@
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/network/messagestructureshelper.h>
|
||||
#include <openspace/rendering/luaconsole.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
@@ -204,7 +206,7 @@ bool SessionRecording::startRecording(const std::string& filename) {
|
||||
LERROR("Unable to start recording while already in recording mode");
|
||||
return false;
|
||||
}
|
||||
else if (_state == SessionState::Playback || _state == SessionState::PlaybackPaused) {
|
||||
else if (isPlayingBack()) {
|
||||
LERROR("Unable to start recording while in session playback mode");
|
||||
return false;
|
||||
}
|
||||
@@ -236,8 +238,8 @@ bool SessionRecording::startRecording(const std::string& filename) {
|
||||
|
||||
_timestampRecordStarted = global::windowDelegate->applicationTime();
|
||||
|
||||
//Record the current delta time as the first property to save in the file.
|
||||
//This needs to be saved as a baseline whether or not it changes during recording.
|
||||
// Record the current delta time as the first property to save in the file.
|
||||
// This needs to be saved as a baseline whether or not it changes during recording.
|
||||
_timestamps3RecordStarted = {
|
||||
_timestampRecordStarted,
|
||||
0.0,
|
||||
@@ -268,9 +270,9 @@ void SessionRecording::recordCurrentTimeRate() {
|
||||
|
||||
void SessionRecording::stopRecording() {
|
||||
if (_state == SessionState::Recording) {
|
||||
//Add all property baseline scripts to the beginning of the recording file
|
||||
// Add all property baseline scripts to the beginning of the recording file
|
||||
datamessagestructures::ScriptMessage smTmp;
|
||||
for (timelineEntry initPropScripts : _keyframesSavePropertiesBaseline_timeline) {
|
||||
for (TimelineEntry initPropScripts : _keyframesSavePropertiesBaseline_timeline) {
|
||||
if (initPropScripts.keyframeType == RecordedType::Script) {
|
||||
smTmp._script = _keyframesSavePropertiesBaseline_scripts
|
||||
[initPropScripts.idxIntoKeyframeTypeArray];
|
||||
@@ -283,21 +285,15 @@ void SessionRecording::stopRecording() {
|
||||
);
|
||||
}
|
||||
}
|
||||
for (timelineEntry entry : _timeline) {
|
||||
for (TimelineEntry entry : _timeline) {
|
||||
switch (entry.keyframeType) {
|
||||
case RecordedType::Camera:
|
||||
case RecordedType::Camera:
|
||||
{
|
||||
interaction::KeyframeNavigator::CameraPose kf
|
||||
= _keyframesCamera[entry.idxIntoKeyframeTypeArray];
|
||||
glm::dquat tmpRotation(
|
||||
std::move(kf.rotation.w),
|
||||
std::move(kf.rotation.x),
|
||||
std::move(kf.rotation.y),
|
||||
std::move(kf.rotation.z)
|
||||
);
|
||||
datamessagestructures::CameraKeyframe kfMsg(
|
||||
std::move(kf.position),
|
||||
std::move(tmpRotation),
|
||||
std::move(kf.rotation),
|
||||
std::move(kf.focusNode),
|
||||
std::move(kf.followFocusNodeRotation),
|
||||
std::move(kf.scale)
|
||||
@@ -311,7 +307,7 @@ void SessionRecording::stopRecording() {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case RecordedType::Time:
|
||||
case RecordedType::Time:
|
||||
{
|
||||
datamessagestructures::TimeKeyframe tf
|
||||
= _keyframesTime[entry.idxIntoKeyframeTypeArray];
|
||||
@@ -324,7 +320,7 @@ void SessionRecording::stopRecording() {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case RecordedType::Script:
|
||||
case RecordedType::Script:
|
||||
{
|
||||
smTmp._script = _keyframesScript[entry.idxIntoKeyframeTypeArray];
|
||||
saveSingleKeyframeScript(
|
||||
@@ -336,7 +332,7 @@ void SessionRecording::stopRecording() {
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -370,13 +366,13 @@ bool SessionRecording::startPlayback(std::string& filename,
|
||||
LERROR("Unable to start playback while in session recording mode");
|
||||
return false;
|
||||
}
|
||||
else if (_state == SessionState::Playback || _state == SessionState::PlaybackPaused) {
|
||||
else if (isPlayingBack()) {
|
||||
LERROR("Unable to start new playback while in session playback mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!std::filesystem::is_regular_file(absFilename)) {
|
||||
LERROR("Cannot find the specified playback file.");
|
||||
LERROR("Cannot find the specified playback file");
|
||||
cleanUpPlayback();
|
||||
return false;
|
||||
}
|
||||
@@ -393,7 +389,7 @@ bool SessionRecording::startPlayback(std::string& filename,
|
||||
FileHeaderTitle.length()
|
||||
);
|
||||
if (readBackHeaderString != FileHeaderTitle) {
|
||||
LERROR("Specified playback file does not contain expected header.");
|
||||
LERROR("Specified playback file does not contain expected header");
|
||||
cleanUpPlayback();
|
||||
return false;
|
||||
}
|
||||
@@ -413,7 +409,7 @@ bool SessionRecording::startPlayback(std::string& filename,
|
||||
readHeaderElement(_playbackFile, 1);
|
||||
|
||||
if (_recordingDataMode == DataMode::Binary) {
|
||||
//Close & re-open the file, starting from the beginning, and do dummy read
|
||||
// Close & re-open the file, starting from the beginning, and do dummy read
|
||||
// past the header, version, and data type
|
||||
_playbackFile.close();
|
||||
_playbackFile.open(_playbackFilename, std::ifstream::in | std::ios::binary);
|
||||
@@ -433,7 +429,7 @@ bool SessionRecording::startPlayback(std::string& filename,
|
||||
return false;
|
||||
}
|
||||
_saveRendering_isFirstFrame = true;
|
||||
//Set time reference mode
|
||||
// Set time reference mode
|
||||
_playbackForceSimTimeAtStart = forceSimTimeAtStart;
|
||||
double now = global::windowDelegate->applicationTime();
|
||||
_playbackTimeReferenceMode = timeMode;
|
||||
@@ -454,6 +450,15 @@ bool SessionRecording::startPlayback(std::string& filename,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool canTriggerPlayback = global::openSpaceEngine->setMode(
|
||||
OpenSpaceEngine::Mode::SessionRecordingPlayback
|
||||
);
|
||||
|
||||
if (!canTriggerPlayback) {
|
||||
cleanUpPlayback();
|
||||
return false;
|
||||
}
|
||||
|
||||
LINFO(fmt::format(
|
||||
"Playback session started: ({:8.3f},0.0,{:13.3f}) with {}/{}/{} entries, "
|
||||
"forceTime={}",
|
||||
@@ -514,9 +519,6 @@ bool SessionRecording::initializePlayback_timeline() {
|
||||
}
|
||||
|
||||
void SessionRecording::initializePlayback_triggerStart() {
|
||||
global::navigationHandler->triggerPlaybackStart();
|
||||
global::scriptScheduler->triggerPlaybackStart();
|
||||
global::timeManager->triggerPlaybackStart();
|
||||
_state = SessionState::Playback;
|
||||
}
|
||||
|
||||
@@ -593,16 +595,22 @@ void SessionRecording::signalPlaybackFinishedForComponent(RecordedType type) {
|
||||
initializePlayback_triggerStart();
|
||||
}
|
||||
else {
|
||||
_state = SessionState::Idle;
|
||||
_cleanupNeeded = true;
|
||||
LINFO("Playback session finished");
|
||||
global::eventEngine->publishEvent<events::EventSessionRecordingPlayback>(
|
||||
events::EventSessionRecordingPlayback::State::Finished
|
||||
);
|
||||
handlePlaybackEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SessionRecording::handlePlaybackEnd() {
|
||||
_state = SessionState::Idle;
|
||||
_cleanupNeeded = true;
|
||||
global::eventEngine->publishEvent<events::EventSessionRecordingPlayback>(
|
||||
events::EventSessionRecordingPlayback::State::Finished
|
||||
);
|
||||
global::openSpaceEngine->resetMode();
|
||||
global::navigationHandler->resetNavigationUpdateVariables();
|
||||
}
|
||||
|
||||
void SessionRecording::enableTakeScreenShotDuringPlayback(int fps) {
|
||||
_saveRenderingDuringPlayback = true;
|
||||
_saveRenderingDeltaTime = 1.0 / fps;
|
||||
@@ -615,20 +623,13 @@ void SessionRecording::disableTakeScreenShotDuringPlayback() {
|
||||
}
|
||||
|
||||
void SessionRecording::stopPlayback() {
|
||||
if (_state == SessionState::Playback || _state == SessionState::PlaybackPaused) {
|
||||
_state = SessionState::Idle;
|
||||
_cleanupNeeded = true;
|
||||
if (isPlayingBack()) {
|
||||
LINFO("Session playback stopped");
|
||||
global::eventEngine->publishEvent<events::EventSessionRecordingPlayback>(
|
||||
events::EventSessionRecordingPlayback::State::Finished
|
||||
);
|
||||
handlePlaybackEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void SessionRecording::cleanUpPlayback() {
|
||||
global::navigationHandler->stopPlayback();
|
||||
global::timeManager->stopPlayback();
|
||||
|
||||
Camera* camera = global::navigationHandler->camera();
|
||||
ghoul_assert(camera != nullptr, "Camera must not be nullptr");
|
||||
Scene* scene = camera->parent()->scene();
|
||||
@@ -646,7 +647,6 @@ void SessionRecording::cleanUpPlayback() {
|
||||
}
|
||||
}
|
||||
}
|
||||
global::scriptScheduler->stopPlayback();
|
||||
|
||||
_playbackFile.close();
|
||||
|
||||
@@ -763,7 +763,8 @@ void SessionRecording::saveCameraKeyframeToTimeline() {
|
||||
|
||||
// Create a camera keyframe, then call to populate it with current position
|
||||
// & orientation of camera
|
||||
datamessagestructures::CameraKeyframe kf = _externInteract.generateCameraKeyframe();
|
||||
datamessagestructures::CameraKeyframe kf =
|
||||
datamessagestructures::generateCameraKeyframe();
|
||||
|
||||
Timestamps times = generateCurrentTimestamp3(kf._timestamp);
|
||||
interaction::KeyframeNavigator::CameraPose pbFrame(std::move(kf));
|
||||
@@ -817,8 +818,9 @@ void SessionRecording::saveCameraKeyframeAscii(Timestamps& times,
|
||||
}
|
||||
|
||||
void SessionRecording::saveTimeKeyframeToTimeline() {
|
||||
//Create a time keyframe, then call to populate it with current time props
|
||||
datamessagestructures::TimeKeyframe kf = _externInteract.generateTimeKeyframe();
|
||||
// Create a time keyframe, then call to populate it with current time props
|
||||
datamessagestructures::TimeKeyframe kf =
|
||||
datamessagestructures::generateTimeKeyframe();
|
||||
|
||||
Timestamps times = generateCurrentTimestamp3(kf._timestamp);
|
||||
addKeyframe(times, kf, _recordingEntryNum++);
|
||||
@@ -847,8 +849,7 @@ void SessionRecording::saveTimeKeyframeAscii(Timestamps& times,
|
||||
saveKeyframeToFile(keyframeLine.str(), file);
|
||||
}
|
||||
|
||||
void SessionRecording::saveScriptKeyframeToTimeline(std::string script)
|
||||
{
|
||||
void SessionRecording::saveScriptKeyframeToTimeline(std::string script) {
|
||||
if (doesStartWithSubstring(script, scriptReturnPrefix)) {
|
||||
script = script.substr(scriptReturnPrefix.length());
|
||||
}
|
||||
@@ -860,7 +861,7 @@ void SessionRecording::saveScriptKeyframeToTimeline(std::string script)
|
||||
trimCommandsFromScriptIfFound(script);
|
||||
replaceCommandsFromScriptIfFound(script);
|
||||
datamessagestructures::ScriptMessage sm
|
||||
= _externInteract.generateScriptMessage(script);
|
||||
= datamessagestructures::generateScriptMessage(script);
|
||||
|
||||
Timestamps times = generateCurrentTimestamp3(sm._timestamp);
|
||||
addKeyframe(times, sm._script, _playbackLineNum);
|
||||
@@ -887,8 +888,7 @@ void SessionRecording::saveScriptKeyframeToPropertiesBaseline(std::string script
|
||||
);
|
||||
}
|
||||
|
||||
void SessionRecording::trimCommandsFromScriptIfFound(std::string& script)
|
||||
{
|
||||
void SessionRecording::trimCommandsFromScriptIfFound(std::string& script) {
|
||||
for (std::string trimSnippet : _scriptsToBeTrimmed) {
|
||||
auto findIdx = script.find(trimSnippet);
|
||||
if (findIdx != std::string::npos) {
|
||||
@@ -898,8 +898,7 @@ void SessionRecording::trimCommandsFromScriptIfFound(std::string& script)
|
||||
}
|
||||
}
|
||||
|
||||
void SessionRecording::replaceCommandsFromScriptIfFound(std::string& script)
|
||||
{
|
||||
void SessionRecording::replaceCommandsFromScriptIfFound(std::string& script) {
|
||||
for (ScriptSubstringReplace replacementSnippet : _scriptsToBeReplaced) {
|
||||
auto findIdx = script.find(replacementSnippet.substringFound);
|
||||
if (findIdx != std::string::npos) {
|
||||
@@ -927,7 +926,6 @@ void SessionRecording::saveScriptKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& sm,
|
||||
std::ofstream& file)
|
||||
{
|
||||
|
||||
std::stringstream keyframeLine = std::stringstream();
|
||||
saveHeaderAscii(times, HeaderScriptAscii, keyframeLine);
|
||||
sm.write(keyframeLine);
|
||||
@@ -974,14 +972,14 @@ void SessionRecording::preSynchronization() {
|
||||
saveTimeKeyframeToTimeline();
|
||||
}
|
||||
}
|
||||
else if (_state == SessionState::Playback || _state == SessionState::PlaybackPaused) {
|
||||
else if (isPlayingBack()) {
|
||||
moveAheadInTime();
|
||||
}
|
||||
else if (_cleanupNeeded) {
|
||||
cleanUpPlayback();
|
||||
}
|
||||
|
||||
//Handle callback(s) for change in idle/record/playback state
|
||||
// Handle callback(s) for change in idle/record/playback state
|
||||
if (_state != _lastState) {
|
||||
using K = CallbackHandle;
|
||||
using V = StateChangeCallback;
|
||||
@@ -1033,8 +1031,7 @@ bool SessionRecording::isPlayingBack() const {
|
||||
}
|
||||
|
||||
bool SessionRecording::isSavingFramesDuringPlayback() const {
|
||||
return ((_state == SessionState::Playback || _state == SessionState::PlaybackPaused)
|
||||
&& _saveRenderingDuringPlayback);
|
||||
return (isPlayingBack() && _saveRenderingDuringPlayback);
|
||||
}
|
||||
|
||||
SessionRecording::SessionState SessionRecording::state() const {
|
||||
@@ -1329,7 +1326,7 @@ bool SessionRecording::readCameraKeyframeAscii(Timestamps& times,
|
||||
iss >> entryType;
|
||||
iss >> times.timeOs >> times.timeRec >> times.timeSim;
|
||||
kf.read(iss);
|
||||
//ASCII format does not contain trailing timestamp so add it here
|
||||
// ASCII format does not contain trailing timestamp so add it here
|
||||
kf._timestamp = times.timeOs;
|
||||
|
||||
if (iss.fail() || !iss.eof()) {
|
||||
@@ -1522,7 +1519,7 @@ bool SessionRecording::checkIfScriptUsesScenegraphNode(std::string s) {
|
||||
if (s.rfind(scriptReturnPrefix, 0) == 0) {
|
||||
s.erase(0, scriptReturnPrefix.length());
|
||||
}
|
||||
//This works for both setPropertyValue and setPropertyValueSingle
|
||||
// This works for both setPropertyValue and setPropertyValueSingle
|
||||
if (s.rfind("openspace.setPropertyValue", 0) == 0) {
|
||||
std::string found;
|
||||
if (s.find("(\"") != std::string::npos) {
|
||||
@@ -1582,10 +1579,10 @@ void SessionRecording::eraseSpacesFromString(std::string& s) {
|
||||
std::string SessionRecording::getNameFromSurroundingQuotes(std::string& s) {
|
||||
std::string result;
|
||||
char quote = s.at(0);
|
||||
//Handle either ' or " marks
|
||||
// Handle either ' or " marks
|
||||
if (quote == '\'' || quote == '\"') {
|
||||
size_t quoteCount = std::count(s.begin(), s.end(), quote);
|
||||
//Must be an opening and closing quote char
|
||||
// Must be an opening and closing quote char
|
||||
if (quoteCount == 2) {
|
||||
result = s.substr(1, s.rfind(quote) - 1);
|
||||
}
|
||||
@@ -1722,7 +1719,7 @@ bool SessionRecording::readScriptKeyframeAscii(Timestamps& times,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionRecording::addKeyframeToTimeline(std::vector<timelineEntry>& timeline,
|
||||
bool SessionRecording::addKeyframeToTimeline(std::vector<TimelineEntry>& timeline,
|
||||
RecordedType type,
|
||||
size_t indexIntoTypeKeyframes,
|
||||
Timestamps t3stamps, int lineNum)
|
||||
@@ -1803,7 +1800,7 @@ void SessionRecording::moveAheadInTime() {
|
||||
double currTime = currentTime();
|
||||
lookForNonCameraKeyframesThatHaveComeDue(currTime);
|
||||
updateCameraWithOrWithoutNewKeyframes(currTime);
|
||||
//Unfortunately the first frame is sometimes rendered because globebrowsing reports
|
||||
// Unfortunately the first frame is sometimes rendered because globebrowsing reports
|
||||
// that all chunks are rendered when they apparently are not.
|
||||
if (_saveRendering_isFirstFrame) {
|
||||
_saveRendering_isFirstFrame = false;
|
||||
@@ -2186,7 +2183,7 @@ void SessionRecording::readPlaybackHeader_stream(std::stringstream& conversionIn
|
||||
else {
|
||||
throw ConversionError("Unknown data type in header (needs Ascii or Binary)");
|
||||
}
|
||||
//Read to throw out newline at end of header
|
||||
// Read to throw out newline at end of header
|
||||
readHeaderElement(conversionInStream, 1);
|
||||
}
|
||||
|
||||
@@ -2269,7 +2266,7 @@ std::string SessionRecording::convertFile(std::string filename, int depth)
|
||||
);
|
||||
int conversionLineNum = 1;
|
||||
|
||||
//If this instance of the SessionRecording class isn't the instance with the
|
||||
// If this instance of the SessionRecording class isn't the instance with the
|
||||
// correct version of the file to be converted, then call getLegacy() to recurse
|
||||
// to the next level down in the legacy subclasses until we get the right
|
||||
// version, then proceed with conversion from there.
|
||||
@@ -2490,7 +2487,7 @@ std::string SessionRecording::getLegacyConversionResult(std::string filename, in
|
||||
std::string SessionRecording_legacy_0085::getLegacyConversionResult(std::string filename,
|
||||
int)
|
||||
{
|
||||
//This method is overriden in each legacy subclass, but does nothing in this instance
|
||||
// This method is overriden in each legacy subclass, but does nothing in this instance
|
||||
// as the oldest supported legacy version.
|
||||
LERROR(fmt::format(
|
||||
"Version 00.85 is the oldest supported legacy file format; no conversion "
|
||||
@@ -2541,13 +2538,7 @@ bool SessionRecording_legacy_0085::convertScript(std::stringstream& inStream,
|
||||
lineNum
|
||||
);
|
||||
if (success) {
|
||||
saveSingleKeyframeScript(
|
||||
kf,
|
||||
times,
|
||||
mode,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
saveSingleKeyframeScript(kf, times, mode, outFile, buffer);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/events/event.h>
|
||||
#include <openspace/events/eventengine.h>
|
||||
#include <openspace/interaction/actionmanager.h>
|
||||
@@ -122,10 +123,6 @@ void NavigationHandler::setFocusNode(SceneGraphNode* node) {
|
||||
_camera->setPositionVec3(anchorNode()->worldPosition());
|
||||
}
|
||||
|
||||
void NavigationHandler::resetCameraDirection() {
|
||||
_orbitalNavigator.startRetargetAnchor();
|
||||
}
|
||||
|
||||
void NavigationHandler::setCamera(Camera* camera) {
|
||||
_camera = camera;
|
||||
_orbitalNavigator.setCamera(camera);
|
||||
@@ -166,55 +163,52 @@ void NavigationHandler::setInterpolationTime(float durationInSeconds) {
|
||||
void NavigationHandler::updateCamera(double deltaTime) {
|
||||
ghoul_assert(_camera != nullptr, "Camera must not be nullptr");
|
||||
|
||||
// If there is a navigation state to set, do so immediately and then return
|
||||
if (_pendingNavigationState.has_value()) {
|
||||
applyNavigationState(*_pendingNavigationState);
|
||||
_orbitalNavigator.resetVelocities();
|
||||
_pendingNavigationState.reset();
|
||||
}
|
||||
else if (!_playbackModeEnabled && _camera) {
|
||||
if (_useKeyFrameInteraction) {
|
||||
_keyframeNavigator.updateCamera(*_camera, _playbackModeEnabled);
|
||||
}
|
||||
else if (_pathNavigator.isPlayingPath()) {
|
||||
_pathNavigator.updateCamera(deltaTime);
|
||||
updateCameraTransitions();
|
||||
}
|
||||
else {
|
||||
if (_disableJoystickInputs) {
|
||||
std::fill(
|
||||
global::joystickInputStates->begin(),
|
||||
global::joystickInputStates->end(),
|
||||
JoystickInputState()
|
||||
);
|
||||
}
|
||||
_orbitalNavigator.updateStatesFromInput(
|
||||
_mouseInputState,
|
||||
_keyboardInputState,
|
||||
deltaTime
|
||||
);
|
||||
_orbitalNavigator.updateCameraStateFromStates(deltaTime);
|
||||
updateCameraTransitions();
|
||||
}
|
||||
|
||||
_orbitalNavigator.updateCameraScalingFromAnchor(deltaTime);
|
||||
return;
|
||||
}
|
||||
|
||||
// If session recording (playback mode) was started in the midst of a camera path,
|
||||
// abort the path
|
||||
if (_playbackModeEnabled && _pathNavigator.isPlayingPath()) {
|
||||
_pathNavigator.abortPath();
|
||||
OpenSpaceEngine::Mode mode = global::openSpaceEngine->currentMode();
|
||||
bool playbackMode = (mode == OpenSpaceEngine::Mode::SessionRecordingPlayback);
|
||||
|
||||
// If we're in session recording payback mode, the session recording is responsible
|
||||
// for navigation. So don't do anything more here
|
||||
if (playbackMode || !_camera) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle navigation, based on what navigator is active
|
||||
if (_useKeyFrameInteraction) {
|
||||
_keyframeNavigator.updateCamera(*_camera, playbackMode);
|
||||
}
|
||||
else if (mode == OpenSpaceEngine::Mode::CameraPath) {
|
||||
_pathNavigator.updateCamera(deltaTime);
|
||||
updateCameraTransitions();
|
||||
}
|
||||
else { // orbital navigator
|
||||
if (_disableJoystickInputs) {
|
||||
clearGlobalJoystickStates();
|
||||
}
|
||||
_orbitalNavigator.updateStatesFromInput(
|
||||
_mouseInputState,
|
||||
_keyboardInputState,
|
||||
deltaTime
|
||||
);
|
||||
_orbitalNavigator.updateCameraStateFromStates(deltaTime);
|
||||
updateCameraTransitions();
|
||||
}
|
||||
|
||||
_orbitalNavigator.updateCameraScalingFromAnchor(deltaTime);
|
||||
}
|
||||
|
||||
void NavigationHandler::applyNavigationState(const NavigationState& ns) {
|
||||
_orbitalNavigator.setAnchorNode(ns.anchor);
|
||||
_orbitalNavigator.setAimNode(ns.aim);
|
||||
_camera->setPose(ns.cameraPose());
|
||||
|
||||
CameraPose pose = ns.cameraPose();
|
||||
_camera->setPositionVec3(pose.position);
|
||||
_camera->setRotation(pose.rotation);
|
||||
_orbitalNavigator.clearPreviousState();
|
||||
_orbitalNavigator.resetNodeMovements();
|
||||
resetNavigationUpdateVariables();
|
||||
_pendingNavigationState.reset();
|
||||
}
|
||||
|
||||
void NavigationHandler::updateCameraTransitions() {
|
||||
@@ -328,23 +322,9 @@ void NavigationHandler::updateCameraTransitions() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NavigationHandler::setEnableKeyFrameInteraction() {
|
||||
_useKeyFrameInteraction = true;
|
||||
}
|
||||
|
||||
void NavigationHandler::setDisableKeyFrameInteraction() {
|
||||
_useKeyFrameInteraction = false;
|
||||
}
|
||||
|
||||
void NavigationHandler::triggerPlaybackStart() {
|
||||
_playbackModeEnabled = true;
|
||||
}
|
||||
|
||||
void NavigationHandler::stopPlayback() {
|
||||
void NavigationHandler::resetNavigationUpdateVariables() {
|
||||
_orbitalNavigator.resetVelocities();
|
||||
_orbitalNavigator.resetNodeMovements();
|
||||
_playbackModeEnabled = false;
|
||||
_orbitalNavigator.updatePreviousStateVariables();
|
||||
}
|
||||
|
||||
const SceneGraphNode* NavigationHandler::anchorNode() const {
|
||||
@@ -593,6 +573,14 @@ std::vector<std::string> NavigationHandler::joystickButtonCommand(
|
||||
return _orbitalNavigator.joystickStates().buttonCommand(joystickName, button);
|
||||
}
|
||||
|
||||
void NavigationHandler::clearGlobalJoystickStates() {
|
||||
std::fill(
|
||||
global::joystickInputStates->begin(),
|
||||
global::joystickInputStates->end(),
|
||||
JoystickInputState()
|
||||
);
|
||||
}
|
||||
|
||||
scripting::LuaLibrary NavigationHandler::luaLibrary() {
|
||||
return {
|
||||
"navigation",
|
||||
|
||||
@@ -741,9 +741,9 @@ void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) {
|
||||
posHandle
|
||||
);
|
||||
|
||||
// Update the camera state
|
||||
_camera->setPositionVec3(pose.position);
|
||||
_camera->setRotation(composeCameraRotation(camRot));
|
||||
pose.rotation = composeCameraRotation(camRot);
|
||||
|
||||
_camera->setPose(pose);
|
||||
}
|
||||
|
||||
void OrbitalNavigator::updateCameraScalingFromAnchor(double deltaTime) {
|
||||
@@ -859,34 +859,22 @@ void OrbitalNavigator::setAnchorNode(const SceneGraphNode* anchorNode,
|
||||
resetVelocities();
|
||||
}
|
||||
|
||||
// Mark a changed anchor node as a camera interaction
|
||||
if (changedAnchor) {
|
||||
updateOnCameraInteraction();
|
||||
}
|
||||
|
||||
if (_anchorNode) {
|
||||
_previousAnchorNodePosition = _anchorNode->worldPosition();
|
||||
_previousAnchorNodeRotation = glm::quat_cast(_anchorNode->worldRotationMatrix());
|
||||
}
|
||||
else {
|
||||
_previousAnchorNodePosition.reset();
|
||||
_previousAnchorNodeRotation.reset();
|
||||
updateOnCameraInteraction(); // Mark a changed anchor node as a camera interaction
|
||||
updatePreviousAnchorState();
|
||||
}
|
||||
}
|
||||
|
||||
void OrbitalNavigator::clearPreviousState() {
|
||||
_previousAnchorNodePosition.reset();
|
||||
_previousAnchorNodeRotation.reset();
|
||||
_previousAimNodePosition.reset();
|
||||
_previousAnchorNodePosition = std::nullopt;
|
||||
_previousAnchorNodeRotation = std::nullopt;
|
||||
_previousAimNodePosition = std::nullopt;
|
||||
}
|
||||
|
||||
void OrbitalNavigator::setAimNode(const SceneGraphNode* aimNode) {
|
||||
_retargetAimInterpolator.end();
|
||||
_aimNode = aimNode;
|
||||
|
||||
if (_aimNode) {
|
||||
_previousAimNodePosition = _aimNode->worldPosition();
|
||||
}
|
||||
updatePreviousAimState();
|
||||
}
|
||||
|
||||
void OrbitalNavigator::setAnchorNode(const std::string& anchorNode) {
|
||||
@@ -897,17 +885,29 @@ void OrbitalNavigator::setAimNode(const std::string& aimNode) {
|
||||
_aim.set(aimNode);
|
||||
}
|
||||
|
||||
void OrbitalNavigator::resetNodeMovements() {
|
||||
void OrbitalNavigator::updatePreviousAnchorState() {
|
||||
if (_anchorNode) {
|
||||
_previousAnchorNodePosition = _anchorNode->worldPosition();
|
||||
_previousAnchorNodeRotation = glm::quat_cast(_anchorNode->worldRotationMatrix());
|
||||
}
|
||||
else {
|
||||
_previousAnchorNodePosition = glm::dvec3(0.0);
|
||||
_previousAnchorNodeRotation = glm::dquat();
|
||||
_previousAnchorNodePosition = std::nullopt;
|
||||
_previousAnchorNodeRotation = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
_previousAimNodePosition = _aimNode ? _aimNode->worldPosition() : glm::dvec3(0.0);
|
||||
void OrbitalNavigator::updatePreviousAimState() {
|
||||
if (_aimNode) {
|
||||
_previousAimNodePosition = _aimNode->worldPosition();
|
||||
}
|
||||
else {
|
||||
_previousAimNodePosition = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void OrbitalNavigator::updatePreviousStateVariables() {
|
||||
updatePreviousAnchorState();
|
||||
updatePreviousAimState();
|
||||
}
|
||||
|
||||
void OrbitalNavigator::startRetargetAnchor() {
|
||||
@@ -954,7 +954,6 @@ void OrbitalNavigator::startRetargetAim() {
|
||||
_cameraToSurfaceDistanceInterpolator.start();
|
||||
}
|
||||
|
||||
|
||||
float OrbitalNavigator::retargetInterpolationTime() const {
|
||||
return _retargetInterpolationTime;
|
||||
}
|
||||
@@ -1332,7 +1331,7 @@ double OrbitalNavigator::interpolateCameraToSurfaceDistance(double deltaTime,
|
||||
_cameraToSurfaceDistanceInterpolator.setDeltaTime(static_cast<float>(deltaTime));
|
||||
_cameraToSurfaceDistanceInterpolator.step();
|
||||
|
||||
// Interpolate distance logarithmically.
|
||||
// Interpolate distance logarithmically
|
||||
double result = glm::exp(glm::mix(
|
||||
glm::log(currentDistance),
|
||||
glm::log(targetDistance),
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <openspace/camera/camera.h>
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
@@ -174,13 +174,6 @@ void PathNavigator::updateCamera(double deltaTime) {
|
||||
deltaTime = 0.01;
|
||||
}
|
||||
|
||||
// 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, _speedScale);
|
||||
const std::string newAnchor = _currentPath->currentAnchor();
|
||||
|
||||
@@ -195,8 +188,7 @@ void PathNavigator::updateCamera(double deltaTime) {
|
||||
removeRollRotation(newPose, deltaTime);
|
||||
}
|
||||
|
||||
camera()->setPositionVec3(newPose.position);
|
||||
camera()->setRotation(newPose.rotation);
|
||||
camera()->setPose(newPose);
|
||||
|
||||
if (_currentPath->hasReachedEnd()) {
|
||||
LINFO("Reached end of path");
|
||||
@@ -223,13 +215,15 @@ void PathNavigator::createPath(const ghoul::Dictionary& dictionary) {
|
||||
// We want the user to be able to choose easily
|
||||
const int pathType = _defaultPathType;
|
||||
|
||||
// Ignore paths that are created during session recording, as the camera
|
||||
// position should have been recorded
|
||||
if (global::sessionRecording->isPlayingBack()) {
|
||||
OpenSpaceEngine::Mode m = global::openSpaceEngine->currentMode();
|
||||
if (m == OpenSpaceEngine::Mode::SessionRecordingPlayback) {
|
||||
// Silently ignore any paths that are being created during a session recording
|
||||
// playback. The camera path should already have been recorded
|
||||
return;
|
||||
}
|
||||
|
||||
clearPath();
|
||||
|
||||
try {
|
||||
_currentPath = std::make_unique<Path>(
|
||||
createPathFromDictionary(dictionary, Path::Type(pathType))
|
||||
@@ -253,7 +247,7 @@ void PathNavigator::createPath(const ghoul::Dictionary& dictionary) {
|
||||
}
|
||||
|
||||
void PathNavigator::clearPath() {
|
||||
LINFO("Clearing path");
|
||||
LDEBUG("Clearing path");
|
||||
_currentPath = nullptr;
|
||||
}
|
||||
|
||||
@@ -263,6 +257,11 @@ void PathNavigator::startPath() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!global::openSpaceEngine->setMode(OpenSpaceEngine::Mode::CameraPath)) {
|
||||
LERROR("Could not start camera path");
|
||||
return; // couldn't switch to camera path mode
|
||||
}
|
||||
|
||||
// Always pause the simulation time when flying, to aovid problem with objects
|
||||
// moving. However, keep track of whether the time was running before the path
|
||||
// was started, so we can reset it on finish
|
||||
@@ -348,6 +347,7 @@ void PathNavigator::handlePathEnd() {
|
||||
}
|
||||
_startSimulationTimeOnFinish = false;
|
||||
clearPath();
|
||||
global::openSpaceEngine->resetMode();
|
||||
}
|
||||
|
||||
void PathNavigator::findRelevantNodes() {
|
||||
|
||||
@@ -22,59 +22,22 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/externinteraction.h>
|
||||
#include <openspace/network/messagestructureshelper.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/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/time.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
namespace openspace::datamessagestructures {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
ExternInteraction::ExternInteraction()
|
||||
: properties::PropertyOwner({ "ExternInteration", "External Interaction" })
|
||||
{}
|
||||
|
||||
void ExternInteraction::cameraInteraction(datamessagestructures::CameraKeyframe kf) {
|
||||
interaction::KeyframeNavigator::CameraPose pose;
|
||||
pose.focusNode = std::move(kf._focusNode);
|
||||
pose.position = std::move(kf._position);
|
||||
pose.rotation = std::move(kf._rotation);
|
||||
pose.scale = std::move(kf._scale);
|
||||
pose.followFocusNodeRotation = std::move(kf._followNodeRotation);
|
||||
|
||||
global::navigationHandler->keyframeNavigator().addKeyframe(kf._timestamp, pose);
|
||||
}
|
||||
|
||||
void ExternInteraction::timeInteraction(datamessagestructures::TimeKeyframe kf) {
|
||||
TimeKeyframeData timeKfData;
|
||||
timeKfData.delta = std::move(kf._dt);
|
||||
timeKfData.pause = std::move(kf._paused);
|
||||
timeKfData.jump = std::move(kf._requiresTimeJump);
|
||||
|
||||
global::timeManager->addKeyframe(kf._timestamp, timeKfData);
|
||||
}
|
||||
|
||||
void ExternInteraction::scriptInteraction(datamessagestructures::ScriptMessage sm) {
|
||||
global::scriptEngine->queueScript(
|
||||
std::move(sm._script),
|
||||
scripting::ScriptEngine::RemoteScripting::No
|
||||
);
|
||||
}
|
||||
|
||||
datamessagestructures::CameraKeyframe ExternInteraction::generateCameraKeyframe() {
|
||||
CameraKeyframe generateCameraKeyframe() {
|
||||
interaction::NavigationHandler& navHandler = *global::navigationHandler;
|
||||
datamessagestructures::CameraKeyframe kf;
|
||||
CameraKeyframe kf;
|
||||
const SceneGraphNode* focusNode = navHandler.orbitalNavigator().anchorNode();
|
||||
|
||||
if (!focusNode) {
|
||||
@@ -102,8 +65,8 @@ datamessagestructures::CameraKeyframe ExternInteraction::generateCameraKeyframe(
|
||||
return kf;
|
||||
}
|
||||
|
||||
datamessagestructures::TimeKeyframe ExternInteraction::generateTimeKeyframe() {
|
||||
datamessagestructures::TimeKeyframe kf;
|
||||
TimeKeyframe generateTimeKeyframe() {
|
||||
TimeKeyframe kf;
|
||||
const Time& time = global::timeManager->time();
|
||||
|
||||
kf._dt = global::timeManager->deltaTime();
|
||||
@@ -115,14 +78,13 @@ datamessagestructures::TimeKeyframe ExternInteraction::generateTimeKeyframe() {
|
||||
return kf;
|
||||
}
|
||||
|
||||
datamessagestructures::ScriptMessage ExternInteraction::generateScriptMessage(
|
||||
std::string script)
|
||||
{
|
||||
datamessagestructures::ScriptMessage sm;
|
||||
ScriptMessage generateScriptMessage(std::string script) {
|
||||
ScriptMessage sm;
|
||||
sm._script = std::move(script);
|
||||
// Timestamp as current runtime of OpenSpace instance
|
||||
sm._timestamp = global::windowDelegate->applicationTime();
|
||||
return sm;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
} // namespace openspace::datamessagestructures
|
||||
|
||||
@@ -239,14 +239,6 @@ void ScriptScheduler::setTimeReferenceMode(interaction::KeyframeTimeRef refType)
|
||||
_timeframeMode = refType;
|
||||
}
|
||||
|
||||
void ScriptScheduler::triggerPlaybackStart() {
|
||||
_playbackModeEnabled = true;
|
||||
}
|
||||
|
||||
void ScriptScheduler::stopPlayback() {
|
||||
_playbackModeEnabled = false;
|
||||
}
|
||||
|
||||
double ScriptScheduler::currentTime() const {
|
||||
return _currentTime;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
@@ -228,7 +229,8 @@ int time_interpolateTogglePause(lua_State* L) {
|
||||
int time_pauseToggleViaKeyboard(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::time_pauseToggleViaKeyboard");
|
||||
|
||||
if (global::sessionRecording->isPlayingBack()) {
|
||||
OpenSpaceEngine::Mode m = global::openSpaceEngine->currentMode();
|
||||
if (m == OpenSpaceEngine::Mode::SessionRecordingPlayback) {
|
||||
bool isPlaybackPaused = global::sessionRecording->isPlaybackPaused();
|
||||
global::sessionRecording->setPlaybackPause(!isPlaybackPaused);
|
||||
}
|
||||
@@ -251,7 +253,6 @@ int time_pauseToggleViaKeyboard(lua_State* L) {
|
||||
int time_setPause(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::time_setPause");
|
||||
bool pause = ghoul::lua::value<bool>(L);
|
||||
|
||||
global::timeManager->setPause(pause);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <openspace/util/timemanager.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/actionmanager.h>
|
||||
#include <openspace/interaction/keybindingmanager.h>
|
||||
@@ -115,6 +116,12 @@ TimeManager::TimeManager()
|
||||
void TimeManager::interpolateTime(double targetTime, double durationSeconds) {
|
||||
ghoul_precondition(durationSeconds > 0.f, "durationSeconds must be positive");
|
||||
|
||||
OpenSpaceEngine::Mode m = global::openSpaceEngine->currentMode();
|
||||
if (m == OpenSpaceEngine::Mode::CameraPath) {
|
||||
LERROR("Cannot change simulation time during camera path");
|
||||
return;
|
||||
}
|
||||
|
||||
const double now = currentApplicationTimeForInterpolation();
|
||||
const bool pause = isPaused();
|
||||
|
||||
@@ -240,6 +247,12 @@ TimeKeyframeData TimeManager::interpolate(double applicationTime) {
|
||||
void TimeManager::progressTime(double dt) {
|
||||
ZoneScoped
|
||||
|
||||
OpenSpaceEngine::Mode m = global::openSpaceEngine->currentMode();
|
||||
if (m == OpenSpaceEngine::Mode::CameraPath) {
|
||||
// We don't want to progress time when a camera path is playing, so return
|
||||
return;
|
||||
}
|
||||
|
||||
_integrateFromTime = static_cast<Time&>(_currentTime);
|
||||
// Frames | 1 2 |
|
||||
// |------------------------------------|
|
||||
@@ -274,7 +287,7 @@ void TimeManager::progressTime(double dt) {
|
||||
const std::deque<Keyframe<TimeKeyframeData>>& keyframes = _timeline.keyframes();
|
||||
|
||||
std::function<bool(const KeyframeBase&, double)> comparisonFunc =
|
||||
(global::sessionRecording->isPlayingBack()) ?
|
||||
(isPlayingBackSessionRecording()) ?
|
||||
&compareKeyframeTimeWithTime_playbackWithFrames : &compareKeyframeTimeWithTime;
|
||||
|
||||
auto firstFutureKeyframe = std::lower_bound(
|
||||
@@ -367,7 +380,7 @@ TimeKeyframeData TimeManager::interpolate(const Keyframe<TimeKeyframeData>& past
|
||||
void TimeManager::applyKeyframeData(const TimeKeyframeData& keyframeData, double dt) {
|
||||
const Time& currentTime = keyframeData.time;
|
||||
_deltaTime = _timePaused ? 0.0 : _targetDeltaTime;
|
||||
if (global::sessionRecording->isPlayingBack()) {
|
||||
if (isPlayingBackSessionRecording()) {
|
||||
_currentTime.data().advanceTime(dt * _deltaTime);
|
||||
}
|
||||
else {
|
||||
@@ -408,6 +421,11 @@ void TimeManager::clearKeyframes() {
|
||||
}
|
||||
|
||||
void TimeManager::setTimeNextFrame(Time t) {
|
||||
OpenSpaceEngine::Mode m = global::openSpaceEngine->currentMode();
|
||||
if (global::openSpaceEngine->currentMode() == OpenSpaceEngine::Mode::CameraPath) {
|
||||
LERROR("Cannot change simulation time during camera path");
|
||||
return;
|
||||
}
|
||||
_shouldSetTime = true;
|
||||
_timeNextFrame = std::move(t);
|
||||
clearKeyframes();
|
||||
@@ -647,14 +665,6 @@ void TimeManager::removeDeltaTimeStepsChangeCallback(CallbackHandle handle) {
|
||||
_deltaTimeStepsChangeCallbacks.erase(it);
|
||||
}
|
||||
|
||||
void TimeManager::triggerPlaybackStart() {
|
||||
_playbackModeEnabled = true;
|
||||
}
|
||||
|
||||
void TimeManager::stopPlayback() {
|
||||
_playbackModeEnabled = false;
|
||||
}
|
||||
|
||||
void TimeManager::removeTimeJumpCallback(CallbackHandle handle) {
|
||||
const auto it = std::find_if(
|
||||
_timeJumpCallbacks.begin(),
|
||||
@@ -734,7 +744,6 @@ void TimeManager::interpolateDeltaTime(double newDeltaTime, double interpolation
|
||||
return;
|
||||
}
|
||||
|
||||
double now = currentApplicationTimeForInterpolation();
|
||||
Time newTime(
|
||||
time().j2000Seconds() + (_deltaTime + newDeltaTime) * 0.5 * interpolationDuration
|
||||
);
|
||||
@@ -744,9 +753,10 @@ void TimeManager::interpolateDeltaTime(double newDeltaTime, double interpolation
|
||||
|
||||
_targetDeltaTime = newDeltaTime;
|
||||
|
||||
if (global::sessionRecording->isPlayingBack()) {
|
||||
now = previousApplicationTimeForInterpolation();
|
||||
}
|
||||
double now = isPlayingBackSessionRecording() ?
|
||||
previousApplicationTimeForInterpolation() :
|
||||
currentApplicationTimeForInterpolation();
|
||||
|
||||
addKeyframe(now, currentKeyframe);
|
||||
addKeyframe(now + interpolationDuration, futureKeyframe);
|
||||
}
|
||||
@@ -833,7 +843,12 @@ void TimeManager::interpolatePause(bool pause, double interpolationDuration) {
|
||||
return;
|
||||
}
|
||||
|
||||
double now = currentApplicationTimeForInterpolation();
|
||||
OpenSpaceEngine::Mode engineMode = global::openSpaceEngine->currentMode();
|
||||
if (!pause && engineMode == OpenSpaceEngine::Mode::CameraPath) {
|
||||
LERROR("Cannot unpause simulation time during camera path");
|
||||
return;
|
||||
}
|
||||
|
||||
double targetDelta = pause ? 0.0 : _targetDeltaTime;
|
||||
Time newTime(
|
||||
time().j2000Seconds() + (_deltaTime + targetDelta) * 0.5 * interpolationDuration
|
||||
@@ -843,9 +858,10 @@ void TimeManager::interpolatePause(bool pause, double interpolationDuration) {
|
||||
TimeKeyframeData futureKeyframe = { newTime, _targetDeltaTime, pause, false };
|
||||
_timePaused = pause;
|
||||
|
||||
if (global::sessionRecording->isPlayingBack()) {
|
||||
now = previousApplicationTimeForInterpolation();
|
||||
}
|
||||
double now = isPlayingBackSessionRecording() ?
|
||||
previousApplicationTimeForInterpolation() :
|
||||
currentApplicationTimeForInterpolation();
|
||||
|
||||
clearKeyframes();
|
||||
if (interpolationDuration > 0) {
|
||||
addKeyframe(now, currentKeyframe);
|
||||
@@ -863,7 +879,7 @@ double TimeManager::currentApplicationTimeForInterpolation() const {
|
||||
}
|
||||
|
||||
double TimeManager::previousApplicationTimeForInterpolation() const {
|
||||
//If playing back with frames, this function needs to be called when a time rate
|
||||
// If playing back with frames, this function needs to be called when a time rate
|
||||
// interpolation (either speed change or pause) begins and ends. If the application
|
||||
// time of the interpolation keyframe timestamp (when it was added to timeline) is
|
||||
// exactly the same as when it is evaluated, then the interpolation math fails and
|
||||
@@ -874,6 +890,11 @@ double TimeManager::previousApplicationTimeForInterpolation() const {
|
||||
return _previousApplicationTime;
|
||||
}
|
||||
|
||||
bool TimeManager::isPlayingBackSessionRecording() const {
|
||||
return (global::openSpaceEngine->currentMode() ==
|
||||
OpenSpaceEngine::Mode::SessionRecordingPlayback);
|
||||
}
|
||||
|
||||
void TimeManager::setTimeFromProfile(const Profile& p) {
|
||||
Time t;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user