mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-10 05:32:18 -06:00
Merge branch 'master' into feature/jwst-update
This commit is contained in:
@@ -55,6 +55,9 @@
|
||||
#include <openspace/scene/rotation.h>
|
||||
#include <openspace/scene/scale.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif // WIN32
|
||||
|
||||
namespace {
|
||||
const std::string ConfigurationFile = "openspace.cfg";
|
||||
@@ -127,8 +130,21 @@ int main(int argc, char** argv) {
|
||||
constexpr const char* BasePathToken = "${BASE}";
|
||||
FileSys.registerPathToken(BasePathToken, base);
|
||||
|
||||
// Using same configuration for size as in apps/OpenSpace/main.cpp
|
||||
glm::ivec2 size = glm::ivec2(1920, 1080);
|
||||
#ifdef WIN32
|
||||
DEVMODEW dm = { 0 };
|
||||
dm.dmSize = sizeof(DEVMODEW);
|
||||
BOOL success = EnumDisplaySettingsW(nullptr, ENUM_CURRENT_SETTINGS, &dm);
|
||||
if (success) {
|
||||
size.x = dm.dmPelsWidth;
|
||||
size.y = dm.dmPelsHeight;
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
*global::configuration = configuration::loadConfigurationFromFile(
|
||||
configFile.string(),
|
||||
size,
|
||||
""
|
||||
);
|
||||
openspace::global::openSpaceEngine->registerPathTokens();
|
||||
|
||||
@@ -59,7 +59,7 @@ local innerMoons = {
|
||||
Spice = parentSpice
|
||||
},
|
||||
Spice = "BIANCA",
|
||||
Radii = { 51000, 51000, 51000 },
|
||||
Radii = { 64000, 46000, 46000 },
|
||||
Tags = tags,
|
||||
TrailTags = trailTags,
|
||||
GUI = {
|
||||
|
||||
@@ -57,6 +57,26 @@ class KeyboardInputState;
|
||||
|
||||
class OrbitalNavigator : public properties::PropertyOwner {
|
||||
public:
|
||||
struct IdleBehavior : public properties::PropertyOwner {
|
||||
enum class Behavior {
|
||||
Orbit = 0,
|
||||
OrbitAtConstantLat,
|
||||
OrbitAroundUp
|
||||
};
|
||||
|
||||
IdleBehavior();
|
||||
|
||||
properties::BoolProperty apply;
|
||||
properties::BoolProperty shouldTriggerWhenIdle;
|
||||
properties::FloatProperty idleWaitTime;
|
||||
properties::BoolProperty abortOnCameraInteraction;
|
||||
properties::FloatProperty speedScale;
|
||||
properties::FloatProperty dampenInterpolationTime;
|
||||
|
||||
properties::OptionProperty defaultBehavior;
|
||||
std::optional<Behavior> chosenBehavior = std::nullopt;
|
||||
};
|
||||
|
||||
OrbitalNavigator();
|
||||
|
||||
void updateStatesFromInput(const MouseInputState& mouseInputState,
|
||||
@@ -72,6 +92,9 @@ public:
|
||||
*/
|
||||
void updateOnCameraInteraction();
|
||||
|
||||
void tickIdleBehaviorTimer(double deltaTime);
|
||||
void triggerIdleBehavior(std::string_view choice = "");
|
||||
|
||||
Camera* camera() const;
|
||||
void setCamera(Camera* camera);
|
||||
void clearPreviousState();
|
||||
@@ -191,22 +214,8 @@ private:
|
||||
Interpolator<double> _idleBehaviorDampenInterpolator;
|
||||
bool _invertIdleBehaviorInterpolation = false;
|
||||
|
||||
struct IdleBehavior : public properties::PropertyOwner {
|
||||
enum Behavior {
|
||||
Orbit = 0,
|
||||
OrbitAtConstantLat,
|
||||
OrbitAroundUp
|
||||
};
|
||||
|
||||
IdleBehavior();
|
||||
|
||||
properties::BoolProperty apply;
|
||||
properties::OptionProperty chosenBehavior;
|
||||
properties::FloatProperty speedScale;
|
||||
properties::BoolProperty abortOnCameraInteraction;
|
||||
properties::FloatProperty dampenInterpolationTime;
|
||||
};
|
||||
IdleBehavior _idleBehavior;
|
||||
float _idleBehaviorTriggerTimer = 0.f;
|
||||
|
||||
/**
|
||||
* Decomposes the camera's rotation in to a global and a local rotation defined by
|
||||
@@ -344,6 +353,8 @@ private:
|
||||
SurfacePositionHandle calculateSurfacePositionHandle(const SceneGraphNode& node,
|
||||
const glm::dvec3 cameraPositionWorldSpace);
|
||||
|
||||
void resetIdleBehavior();
|
||||
|
||||
/**
|
||||
* Apply the currently selected idle behavior to the position and rotations
|
||||
*/
|
||||
|
||||
@@ -737,6 +737,13 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() {
|
||||
&luascriptfunctions::addGlobalRoll,
|
||||
"double, double",
|
||||
"Directly adds to the global roll of the camera"
|
||||
},
|
||||
{
|
||||
"triggerIdleBehavior",
|
||||
&luascriptfunctions::triggerIdleBehavior,
|
||||
"[string]",
|
||||
"Immediately start applying the chosen IdleBehavior. If none is "
|
||||
"specified, use the one set to default in the OrbitalNavigator."
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -343,4 +343,20 @@ int addGlobalRoll(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int triggerIdleBehavior(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, {0, 1}, "lua::triggerIdleBehavior");
|
||||
std::optional<std::string> choice = ghoul::lua::value<std::optional<std::string>>(L);
|
||||
|
||||
try {
|
||||
global::navigationHandler->orbitalNavigator().triggerIdleBehavior(
|
||||
choice.value_or("")
|
||||
);
|
||||
}
|
||||
catch (ghoul::RuntimeError& e) {
|
||||
return ghoul::lua::luaError(L, e.message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::luascriptfunctions
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/interaction/mouseinputstate.h>
|
||||
#include <openspace/interaction/keyboardinputstate.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
@@ -159,26 +160,29 @@ namespace {
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
StereoInterpolationTimeInfo = {
|
||||
"StereoInterpolationTime",
|
||||
"Stereo Interpolation Time",
|
||||
"The time to interpolate to a new stereoscopic depth "
|
||||
"when the anchor node is changed, in seconds."
|
||||
StereoInterpolationTimeInfo =
|
||||
{
|
||||
"StereoInterpolationTime",
|
||||
"Stereo Interpolation Time",
|
||||
"The time to interpolate to a new stereoscopic depth "
|
||||
"when the anchor node is changed, in seconds."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
RetargetInterpolationTimeInfo = {
|
||||
"RetargetAnchorInterpolationTime",
|
||||
"Retarget Interpolation Time",
|
||||
"The time to interpolate the camera rotation "
|
||||
"when the anchor or aim node is changed, in seconds."
|
||||
RetargetInterpolationTimeInfo =
|
||||
{
|
||||
"RetargetAnchorInterpolationTime",
|
||||
"Retarget Interpolation Time",
|
||||
"The time to interpolate the camera rotation "
|
||||
"when the anchor or aim node is changed, in seconds."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
FollowRotationInterpTimeInfo = {
|
||||
"FollowRotationInterpolationTime",
|
||||
"Follow Rotation Interpolation Time",
|
||||
"The interpolation time when toggling following focus node rotation."
|
||||
FollowRotationInterpTimeInfo =
|
||||
{
|
||||
"FollowRotationInterpolationTime",
|
||||
"Follow Rotation Interpolation Time",
|
||||
"The interpolation time when toggling following focus node rotation."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo InvertMouseButtons = {
|
||||
@@ -190,31 +194,34 @@ namespace {
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
UseAdaptiveStereoscopicDepthInfo = {
|
||||
"UseAdaptiveStereoscopicDepth",
|
||||
"Adaptive Steroscopic Depth",
|
||||
"Dynamically adjust the view scaling based on the distance to the surface of "
|
||||
"the anchor and aim nodes. If enabled, view scale will be set to "
|
||||
"StereoscopicDepthOfFocusSurface / min(anchorDistance, aimDistance). "
|
||||
"If disabled, view scale will be set to 10^StaticViewScaleExponent."
|
||||
};
|
||||
UseAdaptiveStereoscopicDepthInfo =
|
||||
{
|
||||
"UseAdaptiveStereoscopicDepth",
|
||||
"Adaptive Steroscopic Depth",
|
||||
"Dynamically adjust the view scaling based on the distance to the surface of "
|
||||
"the anchor and aim nodes. If enabled, view scale will be set to "
|
||||
"StereoscopicDepthOfFocusSurface / min(anchorDistance, aimDistance). "
|
||||
"If disabled, view scale will be set to 10^StaticViewScaleExponent."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
StaticViewScaleExponentInfo = {
|
||||
"StaticViewScaleExponent",
|
||||
"Static View Scale Exponent",
|
||||
"Statically scale the world by 10^StaticViewScaleExponent. "
|
||||
"Only used if UseAdaptiveStereoscopicDepthInfo is set to false."
|
||||
};
|
||||
StaticViewScaleExponentInfo =
|
||||
{
|
||||
"StaticViewScaleExponent",
|
||||
"Static View Scale Exponent",
|
||||
"Statically scale the world by 10^StaticViewScaleExponent. "
|
||||
"Only used if UseAdaptiveStereoscopicDepthInfo is set to false."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
StereoscopicDepthOfFocusSurfaceInfo = {
|
||||
"StereoscopicDepthOfFocusSurface",
|
||||
"Stereoscopic Depth of the Surface in Focus",
|
||||
"Set the stereoscopically perceived distance (in meters) to the closest "
|
||||
"point out of the surface of the anchor and the center of the aim node. "
|
||||
"Only used if UseAdaptiveStereoscopicDepthInfo is set to true."
|
||||
};
|
||||
StereoscopicDepthOfFocusSurfaceInfo =
|
||||
{
|
||||
"StereoscopicDepthOfFocusSurface",
|
||||
"Stereoscopic Depth of the Surface in Focus",
|
||||
"Set the stereoscopically perceived distance (in meters) to the closest "
|
||||
"point out of the surface of the anchor and the center of the aim node. "
|
||||
"Only used if UseAdaptiveStereoscopicDepthInfo is set to true."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ApplyIdleBehaviorInfo = {
|
||||
"ApplyIdleBehavior",
|
||||
@@ -230,6 +237,22 @@ namespace {
|
||||
"applied. Each option represents a predefined camera behavior."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
ShouldTriggerIdleBehaviorWhenIdleInfo =
|
||||
{
|
||||
"ShouldTriggerWhenIdle",
|
||||
"Should Trigger When Idle",
|
||||
"If true, the chosen idle behavior will trigger automatically after "
|
||||
"a certain time (see 'IdleWaitTime' property)."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo IdleWaitTimeInfo = {
|
||||
"IdleWaitTime",
|
||||
"Idle Wait Time",
|
||||
"The time (seconds) until idle behavior starts, if no camera interaction "
|
||||
"has been performed. Note that friction counts as camera interaction."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo IdleBehaviorSpeedInfo = {
|
||||
"SpeedFactor",
|
||||
"Speed Factor",
|
||||
@@ -238,7 +261,8 @@ namespace {
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
AbortOnCameraInteractionInfo = {
|
||||
AbortOnCameraInteractionInfo =
|
||||
{
|
||||
"AbortOnCameraInteraction",
|
||||
"Abort on Camera Interaction",
|
||||
"If set to true, the idle behavior is aborted on camera interaction. If false, "
|
||||
@@ -248,12 +272,18 @@ namespace {
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
IdleBehaviorDampenInterpolationTimeInfo = {
|
||||
IdleBehaviorDampenInterpolationTimeInfo =
|
||||
{
|
||||
"DampenInterpolationTime",
|
||||
"Start/End Dampen Interpolation Time",
|
||||
"The time to interpolate to/from full speed when an idle behavior is triggered "
|
||||
"or canceled, in seconds."
|
||||
};
|
||||
|
||||
constexpr const char IdleKeyOrbit[] = "Orbit";
|
||||
constexpr const char IdleKeyOrbitAtConstantLat[] = "OrbitAtConstantLatitude";
|
||||
constexpr const char IdleKeyOrbitAroundUp[] = "OrbitAroundUp";
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
@@ -274,19 +304,25 @@ OrbitalNavigator::Friction::Friction()
|
||||
OrbitalNavigator::IdleBehavior::IdleBehavior()
|
||||
: properties::PropertyOwner({ "IdleBehavior" })
|
||||
, apply(ApplyIdleBehaviorInfo, false)
|
||||
, chosenBehavior(IdleBehaviorInfo)
|
||||
, defaultBehavior(IdleBehaviorInfo)
|
||||
, shouldTriggerWhenIdle(ShouldTriggerIdleBehaviorWhenIdleInfo, false)
|
||||
, idleWaitTime(IdleWaitTimeInfo, 5.f, 0.f, 3600.f)
|
||||
, speedScale(IdleBehaviorSpeedInfo, 1.f, 0.01f, 5.f)
|
||||
, abortOnCameraInteraction(AbortOnCameraInteractionInfo, true)
|
||||
, dampenInterpolationTime(IdleBehaviorDampenInterpolationTimeInfo, 0.5f, 0.f, 10.f)
|
||||
{
|
||||
addProperty(apply);
|
||||
chosenBehavior.addOptions({
|
||||
{ IdleBehavior::Behavior::Orbit, "Orbit" },
|
||||
{ IdleBehavior::Behavior::OrbitAtConstantLat, "OrbitAtConstantLatitude" },
|
||||
{ IdleBehavior::Behavior::OrbitAroundUp, "OrbitAroundUp" }
|
||||
using Behavior = IdleBehavior::Behavior;
|
||||
defaultBehavior.addOptions({
|
||||
{ static_cast<int>(Behavior::Orbit), IdleKeyOrbit },
|
||||
{ static_cast<int>(Behavior::OrbitAtConstantLat), IdleKeyOrbitAtConstantLat },
|
||||
{ static_cast<int>(Behavior::OrbitAroundUp), IdleKeyOrbitAroundUp }
|
||||
});
|
||||
chosenBehavior = IdleBehavior::Behavior::Orbit;
|
||||
addProperty(chosenBehavior);
|
||||
defaultBehavior = static_cast<int>(IdleBehavior::Behavior::Orbit);
|
||||
addProperty(defaultBehavior);
|
||||
addProperty(shouldTriggerWhenIdle);
|
||||
addProperty(idleWaitTime);
|
||||
idleWaitTime.setExponent(2.2f);
|
||||
addProperty(speedScale);
|
||||
addProperty(abortOnCameraInteraction);
|
||||
addProperty(dampenInterpolationTime);
|
||||
@@ -454,6 +490,13 @@ OrbitalNavigator::OrbitalNavigator()
|
||||
_idleBehavior.dampenInterpolationTime
|
||||
);
|
||||
});
|
||||
_idleBehavior.shouldTriggerWhenIdle.onChange([&]() {
|
||||
_idleBehaviorTriggerTimer = _idleBehavior.idleWaitTime;
|
||||
});
|
||||
_idleBehavior.idleWaitTime.onChange([&]() {
|
||||
_idleBehaviorTriggerTimer = _idleBehavior.idleWaitTime;
|
||||
});
|
||||
|
||||
addProperty(_anchor);
|
||||
addProperty(_aim);
|
||||
addProperty(_retargetAnchor);
|
||||
@@ -530,6 +573,9 @@ void OrbitalNavigator::updateStatesFromInput(const MouseInputState& mouseInputSt
|
||||
if (interactionHappened) {
|
||||
updateOnCameraInteraction();
|
||||
}
|
||||
else {
|
||||
tickIdleBehaviorTimer(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) {
|
||||
@@ -699,7 +745,8 @@ void OrbitalNavigator::updateCameraScalingFromAnchor(double deltaTime) {
|
||||
_currentCameraToSurfaceDistance = interpolateCameraToSurfaceDistance(
|
||||
deltaTime,
|
||||
_currentCameraToSurfaceDistance,
|
||||
targetCameraToSurfaceDistance);
|
||||
targetCameraToSurfaceDistance
|
||||
);
|
||||
}
|
||||
|
||||
_camera->setScaling(
|
||||
@@ -715,9 +762,19 @@ void OrbitalNavigator::updateCameraScalingFromAnchor(double deltaTime) {
|
||||
void OrbitalNavigator::updateOnCameraInteraction() {
|
||||
// Disable idle behavior if camera interaction happened
|
||||
if (_idleBehavior.apply && _idleBehavior.abortOnCameraInteraction) {
|
||||
_idleBehavior.apply = false;
|
||||
// Prevent interpolating stop, to avoid weirdness when changing anchor, etc
|
||||
_idleBehaviorDampenInterpolator.setInterpolationTime(0.f);
|
||||
resetIdleBehavior();
|
||||
}
|
||||
}
|
||||
|
||||
void OrbitalNavigator::tickIdleBehaviorTimer(double deltaTime) {
|
||||
if (!_idleBehavior.shouldTriggerWhenIdle) {
|
||||
return;
|
||||
}
|
||||
if (_idleBehaviorTriggerTimer > 0.f) {
|
||||
_idleBehaviorTriggerTimer -= static_cast<float>(deltaTime);
|
||||
}
|
||||
else {
|
||||
triggerIdleBehavior();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1502,6 +1559,49 @@ const ScriptCameraStates& OrbitalNavigator::scriptStates() const {
|
||||
return _scriptStates;
|
||||
}
|
||||
|
||||
void OrbitalNavigator::triggerIdleBehavior(std::string_view choice) {
|
||||
OpenSpaceEngine::Mode mode = global::openSpaceEngine->currentMode();
|
||||
if (mode != OpenSpaceEngine::Mode::UserControl) {
|
||||
LERROR(
|
||||
"Could not start idle behavior. The camera is being controlled "
|
||||
"by some other part of the system"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (choice.empty()) {
|
||||
_idleBehavior.chosenBehavior = std::nullopt;
|
||||
}
|
||||
else {
|
||||
IdleBehavior::Behavior behavior;
|
||||
if (choice == IdleKeyOrbit) {
|
||||
behavior = IdleBehavior::Behavior::Orbit;
|
||||
}
|
||||
else if (choice == IdleKeyOrbitAtConstantLat) {
|
||||
behavior = IdleBehavior::Behavior::OrbitAtConstantLat;
|
||||
}
|
||||
else if (choice == IdleKeyOrbitAroundUp) {
|
||||
behavior = IdleBehavior::Behavior::OrbitAroundUp;
|
||||
}
|
||||
else {
|
||||
throw ghoul::RuntimeError(
|
||||
fmt::format("No existing IdleBehavior with identifier '{}'", choice)
|
||||
);
|
||||
}
|
||||
_idleBehavior.chosenBehavior = behavior;
|
||||
}
|
||||
|
||||
_idleBehavior.apply = true;
|
||||
}
|
||||
|
||||
void OrbitalNavigator::resetIdleBehavior() {
|
||||
_idleBehavior.apply = false;
|
||||
_idleBehavior.chosenBehavior = std::nullopt;
|
||||
// Prevent interpolating stop, to avoid weirdness when changing anchor, etc
|
||||
_idleBehaviorDampenInterpolator.setInterpolationTime(0.f);
|
||||
_idleBehaviorTriggerTimer = _idleBehavior.idleWaitTime;
|
||||
}
|
||||
|
||||
void OrbitalNavigator::applyIdleBehavior(double deltaTime, glm::dvec3& position,
|
||||
glm::dquat& localRotation,
|
||||
glm::dquat& globalRotation)
|
||||
@@ -1541,10 +1641,11 @@ void OrbitalNavigator::applyIdleBehavior(double deltaTime, glm::dvec3& position,
|
||||
speedScale *= _invertIdleBehaviorInterpolation ? (1.0 - s) : s;
|
||||
|
||||
// Apply the chosen behavior
|
||||
const IdleBehavior::Behavior chosen =
|
||||
static_cast<IdleBehavior::Behavior>(_idleBehavior.chosenBehavior.value());
|
||||
const IdleBehavior::Behavior choice = _idleBehavior.chosenBehavior.value_or(
|
||||
static_cast<IdleBehavior::Behavior>(_idleBehavior.defaultBehavior.value())
|
||||
);
|
||||
|
||||
switch (chosen) {
|
||||
switch (choice) {
|
||||
case IdleBehavior::Behavior::Orbit:
|
||||
orbitAnchor(deltaTime, position, globalRotation, speedScale);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user