diff --git a/data/assets/util/ipac.asset b/data/assets/util/ipac.asset new file mode 100644 index 0000000000..5d9140d4eb --- /dev/null +++ b/data/assets/util/ipac.asset @@ -0,0 +1,18 @@ +asset.onInitialize(function() + openspace.clearKeys() + openspace.bindKey("RIGHT", "openspace.navigation.addGlobalRotation(-5.0, 0.0)"); + openspace.bindKey("LEFT", "openspace.navigation.addGlobalRotation(5.0, 0.0)"); + openspace.bindKey("UP", "openspace.navigation.addGlobalRotation(0.0, 5.0)"); + openspace.bindKey("DOWN", "openspace.navigation.addGlobalRotation(0.0, -5.0)"); + + openspace.bindKey("CTRL+RIGHT", "openspace.navigation.addLocalRotation(-5.0, 0.0)"); + openspace.bindKey("CTRL+LEFT", "openspace.navigation.addLocalRotation(5.0, 0.0)"); + openspace.bindKey("CTRL+UP", "openspace.navigation.addLocalRotation(0.0, 5.0)"); + openspace.bindKey("CTRL+DOWN", "openspace.navigation.addLocalRotation(0.0, -5.0)"); + + openspace.bindKey("ALT+UP", "openspace.navigation.addTruckMovement(0.0, 5.0)"); + openspace.bindKey("ALT+DOWN", "openspace.navigation.addTruckMovement(0.0, -5.0)"); + + openspace.bindKey("SPACE", "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Moon');openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);") + openspace.bindKey("Z", "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Earth');openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);") +end) diff --git a/include/openspace/interaction/orbitalnavigator.h b/include/openspace/interaction/orbitalnavigator.h index 0eff98c64c..6478126dda 100644 --- a/include/openspace/interaction/orbitalnavigator.h +++ b/include/openspace/interaction/orbitalnavigator.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,9 @@ public: JoystickCameraStates& joystickStates(); const JoystickCameraStates& joystickStates() const; + ScriptCameraStates& scriptStates(); + const ScriptCameraStates& scriptStates() const; + bool followingNodeRotation() const; const SceneGraphNode* anchorNode() const; const SceneGraphNode* aimNode() const; @@ -146,6 +150,7 @@ private: MouseCameraStates _mouseStates; JoystickCameraStates _joystickStates; + ScriptCameraStates _scriptStates; const SceneGraphNode* _anchorNode = nullptr; const SceneGraphNode* _aimNode = nullptr; diff --git a/include/openspace/interaction/scriptcamerastates.h b/include/openspace/interaction/scriptcamerastates.h new file mode 100644 index 0000000000..2153dee497 --- /dev/null +++ b/include/openspace/interaction/scriptcamerastates.h @@ -0,0 +1,54 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * 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___SCRIPTCAMERASTATES___H__ +#define __OPENSPACE_CORE___SCRIPTCAMERASTATES___H__ + +#include + +namespace openspace::interaction { + +class ScriptCameraStates : public CameraInteractionStates { +public: + ScriptCameraStates(); + + void updateStateFromInput(const InputState& inputState, double deltaTime) override; + + void addLocalRotation(const glm::dvec2& delta); + void addGlobalRotation(const glm::dvec2& delta); + void addTruckMovement(const glm::dvec2& delta); + void addLocalRoll(const glm::dvec2& delta); + void addGlobalRoll(const glm::dvec2& delta); + +private: + glm::dvec2 _localRotation; + glm::dvec2 _globalRotation; + glm::dvec2 _truckMovement; + glm::dvec2 _localRoll; + glm::dvec2 _globalRoll; +}; + +} // namespace openspace::interaction + +#endif // __OPENSPACE_CORE___SCRIPTCAMERASTATES___H__ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 223d5e4e8d..0fd7b64f35 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -54,6 +54,7 @@ set(OPENSPACE_SOURCE ${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 ${OPENSPACE_BASE_DIR}/src/interaction/sessionrecording_lua.inl @@ -236,6 +237,7 @@ set(OPENSPACE_HEADER ${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 ${OPENSPACE_BASE_DIR}/include/openspace/interaction/sessionrecording.inl ${OPENSPACE_BASE_DIR}/include/openspace/interaction/shortcutmanager.h diff --git a/src/interaction/navigationhandler.cpp b/src/interaction/navigationhandler.cpp index f4f0c21dc9..ee711393f7 100644 --- a/src/interaction/navigationhandler.cpp +++ b/src/interaction/navigationhandler.cpp @@ -635,6 +635,41 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() { "int", "Returns the script that is currently bound to be executed when the " "provided button is pressed" + }, + { + "addGlobalRotation", + &luascriptfunctions::addGlobalRotation, + {}, + "double, double", + "Directly adds to the global rotation of the camera" + }, + { + "addLocalRotation", + &luascriptfunctions::addLocalRotation, + {}, + "double, double", + "Directly adds to the local rotation of the camera" + }, + { + "addTruckMovement", + &luascriptfunctions::addTruckMovement, + {}, + "double, double", + "Directly adds to the truck movement of the camera" + }, + { + "addLocalRoll", + &luascriptfunctions::addLocalRoll, + {}, + "double, double", + "Directly adds to the local roll of the camera" + }, + { + "addGlobalRoll", + &luascriptfunctions::addGlobalRoll, + {}, + "double, double", + "Directly adds to the global roll of the camera" } } }; diff --git a/src/interaction/navigationhandler_lua.inl b/src/interaction/navigationhandler_lua.inl index 899859c36e..dcbb407878 100644 --- a/src/interaction/navigationhandler_lua.inl +++ b/src/interaction/navigationhandler_lua.inl @@ -23,6 +23,7 @@ ****************************************************************************************/ #include +#include namespace openspace::luascriptfunctions { @@ -250,4 +251,74 @@ int joystickButton(lua_State* L) { return 1; } +int addGlobalRotation(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addGlobalRotation"); + + const double v1 = ghoul::lua::value(L, 1, ghoul::lua::PopValue::No); + const double v2 = ghoul::lua::value(L, 2, ghoul::lua::PopValue::No); + + global::navigationHandler.orbitalNavigator().scriptStates().addGlobalRotation( + glm::dvec2(v1, v2) + ); + + lua_settop(L, 0); + return 0; +} + +int addLocalRotation(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addLocalRotation"); + + const double v1 = ghoul::lua::value(L, 1, ghoul::lua::PopValue::No); + const double v2 = ghoul::lua::value(L, 2, ghoul::lua::PopValue::No); + + global::navigationHandler.orbitalNavigator().scriptStates().addLocalRotation( + glm::dvec2(v1, v2) + ); + + lua_settop(L, 0); + return 0; +} + +int addTruckMovement(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addTruckMovement"); + + const double v1 = ghoul::lua::value(L, 1, ghoul::lua::PopValue::No); + const double v2 = ghoul::lua::value(L, 2, ghoul::lua::PopValue::No); + + global::navigationHandler.orbitalNavigator().scriptStates().addTruckMovement( + glm::dvec2(v1, v2) + ); + + lua_settop(L, 0); + return 0; +} + +int addLocalRoll(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addLocalRoll"); + + const double v1 = ghoul::lua::value(L, 1, ghoul::lua::PopValue::No); + const double v2 = ghoul::lua::value(L, 2, ghoul::lua::PopValue::No); + + global::navigationHandler.orbitalNavigator().scriptStates().addLocalRoll( + glm::dvec2(v1, v2) + ); + + lua_settop(L, 0); + return 0; +} + +int addGlobalRoll(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addGlobalRoll"); + + const double v1 = ghoul::lua::value(L, 1, ghoul::lua::PopValue::No); + const double v2 = ghoul::lua::value(L, 2, ghoul::lua::PopValue::No); + + global::navigationHandler.orbitalNavigator().scriptStates().addGlobalRoll( + glm::dvec2(v1, v2) + ); + + lua_settop(L, 0); + return 0; +} + } // namespace openspace::luascriptfunctions diff --git a/src/interaction/orbitalnavigator.cpp b/src/interaction/orbitalnavigator.cpp index 2ec2474bf9..8077f7e8e9 100644 --- a/src/interaction/orbitalnavigator.cpp +++ b/src/interaction/orbitalnavigator.cpp @@ -348,6 +348,7 @@ glm::quat OrbitalNavigator::anchorNodeToCameraRotation() const { void OrbitalNavigator::resetVelocities() { _mouseStates.resetVelocities(); _joystickStates.resetVelocities(); + _scriptStates.resetVelocities(); } void OrbitalNavigator::updateStatesFromInput(const InputState& inputState, @@ -355,6 +356,7 @@ void OrbitalNavigator::updateStatesFromInput(const InputState& inputState, { _mouseStates.updateStateFromInput(inputState, deltaTime); _joystickStates.updateStateFromInput(inputState, deltaTime); + _scriptStates.updateStateFromInput(inputState, deltaTime); } void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) { @@ -871,7 +873,8 @@ glm::dquat OrbitalNavigator::roll(double deltaTime, { const glm::dquat mouseRollQuat = glm::angleAxis( _mouseStates.localRollVelocity().x * deltaTime + - _joystickStates.localRollVelocity().x * deltaTime, + _joystickStates.localRollVelocity().x * deltaTime + + _scriptStates.localRollVelocity().x * deltaTime, glm::dvec3(0.0, 0.0, 1.0) ); return localCameraRotation * mouseRollQuat; @@ -892,8 +895,15 @@ glm::dquat OrbitalNavigator::rotateLocally(double deltaTime, 0.0 ) * deltaTime); + const glm::dquat scriptRotationDiff = glm::dquat(glm::dvec3( + _scriptStates.localRotationVelocity().y, + _scriptStates.localRotationVelocity().x, + 0.0 + ) * deltaTime); - return localCameraRotation * joystickRotationDiff * mouseRotationDiff; + + return localCameraRotation * joystickRotationDiff * mouseRotationDiff * + scriptRotationDiff; } glm::dquat OrbitalNavigator::interpolateLocalRotation(double deltaTime, const glm::dquat& localCameraRotation) @@ -1061,19 +1071,24 @@ glm::dvec3 OrbitalNavigator::translateHorizontally(double deltaTime, const glm::dquat mouseRotationDiffCamSpace = glm::dquat(glm::dvec3( -_mouseStates.globalRotationVelocity().y * deltaTime, -_mouseStates.globalRotationVelocity().x * deltaTime, - 0) * speedScale); + 0.0) * speedScale); const glm::dquat joystickRotationDiffCamSpace = glm::dquat(glm::dvec3( -_joystickStates.globalRotationVelocity().y * deltaTime, -_joystickStates.globalRotationVelocity().x * deltaTime, - 0) * speedScale + 0.0) * speedScale + ); + + const glm::dquat scriptRotationDiffCamSpace = glm::dquat(glm::dvec3( + -_scriptStates.globalRotationVelocity().y * deltaTime, + -_scriptStates.globalRotationVelocity().x * deltaTime, + 0.0) * speedScale ); // Transform to world space const glm::dquat rotationDiffWorldSpace = globalCameraRotation * - joystickRotationDiffCamSpace * - mouseRotationDiffCamSpace * - glm::inverse(globalCameraRotation); + joystickRotationDiffCamSpace * scriptRotationDiffCamSpace * + mouseRotationDiffCamSpace * glm::inverse(globalCameraRotation); // Rotate and find the difference vector const glm::dvec3 rotationDiffVec3 = @@ -1134,7 +1149,8 @@ glm::dvec3 OrbitalNavigator::translateVertically(double deltaTime, const glm::dvec3 actualSurfaceToCamera = posDiff - centerToActualSurface; const double totalVelocity = _joystickStates.truckMovementVelocity().y + - _mouseStates.truckMovementVelocity().y; + _mouseStates.truckMovementVelocity().y + + _scriptStates.truckMovementVelocity().y; return cameraPosition - actualSurfaceToCamera * totalVelocity * deltaTime; } @@ -1153,7 +1169,8 @@ glm::dquat OrbitalNavigator::rotateHorizontally(double deltaTime, const glm::dquat mouseCameraRollRotation = glm::angleAxis( _mouseStates.globalRollVelocity().x * deltaTime + - _joystickStates.globalRollVelocity().x * deltaTime, + _joystickStates.globalRollVelocity().x * deltaTime + + _scriptStates.globalRollVelocity().x * deltaTime, directionFromSurfaceToCamera ); return mouseCameraRollRotation * globalCameraRotation; @@ -1239,4 +1256,12 @@ const JoystickCameraStates& OrbitalNavigator::joystickStates() const { return _joystickStates; } +ScriptCameraStates& OrbitalNavigator::scriptStates() { + return _scriptStates; +} + +const ScriptCameraStates& OrbitalNavigator::scriptStates() const { + return _scriptStates; +} + } // namespace openspace::interaction diff --git a/src/interaction/scriptcamerastates.cpp b/src/interaction/scriptcamerastates.cpp new file mode 100644 index 0000000000..ef018796d1 --- /dev/null +++ b/src/interaction/scriptcamerastates.cpp @@ -0,0 +1,118 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * 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 + +#include + +namespace { + const double SENSITIVITY_ADJUSTMENT_INCREASE = 8.0; + const double SENSITIVITY_ADJUSTMENT_DECREASE = 0.5; +} + +namespace openspace::interaction { + +ScriptCameraStates::ScriptCameraStates() : CameraInteractionStates(1.0, 1.0) {} + +void ScriptCameraStates::updateStateFromInput(const InputState& inputState, + double deltaTime) +{ + if (_localRotation != glm::dvec2(0.0)) { + _localRotationState.velocity.set( + _localRotation * _sensitivity, + deltaTime + ); + _localRotation = glm::dvec2(0.0); + } + else { + _localRotationState.velocity.decelerate(deltaTime); + } + + if (_globalRotation != glm::dvec2(0.0)) { + _globalRotationState.velocity.set( + _globalRotation * _sensitivity, + deltaTime + ); + _globalRotation = glm::dvec2(0.0); + } + else { + _globalRotationState.velocity.decelerate(deltaTime); + } + + if (_truckMovement != glm::dvec2(0.0)) { + _truckMovementState.velocity.set( + _truckMovement * _sensitivity, + deltaTime + ); + _truckMovement = glm::dvec2(0.0); + } + else { + _truckMovementState.velocity.decelerate(deltaTime); + } + + if (_localRoll != glm::dvec2(0.0)) { + _localRollState.velocity.set( + _localRoll * _sensitivity, + deltaTime + ); + _localRoll = glm::dvec2(0.0); + } + else { + _localRollState.velocity.decelerate(deltaTime); + } + + if (_globalRoll != glm::dvec2(0.0)) { + _globalRollState.velocity.set( + _globalRoll * _sensitivity, + deltaTime + ); + _globalRoll = glm::dvec2(0.0); + } + else { + _globalRollState.velocity.decelerate(deltaTime); + } +} + +void ScriptCameraStates::addLocalRotation(const glm::dvec2& delta) { + _localRotation += delta; +} + +void ScriptCameraStates::addGlobalRotation(const glm::dvec2& delta) { + _globalRotation += delta; +} + +void ScriptCameraStates::addTruckMovement(const glm::dvec2& delta) { + _truckMovement += delta; +} + +void ScriptCameraStates::addLocalRoll(const glm::dvec2& delta) { + _localRoll += delta; +} + +void ScriptCameraStates::addGlobalRoll(const glm::dvec2& delta) { + _globalRoll += delta; +} + + +} // namespace openspace::interaction