mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-09 13:00:23 -05:00
Enable setting of friction, sensitivity and followscalefactor in interaction handler.
This commit is contained in:
@@ -58,7 +58,8 @@ return {
|
||||
Camera = {
|
||||
Focus = "Earth",
|
||||
--Focus = "Moon",
|
||||
Position = {1, 0, 0, 5},
|
||||
Position = {526781518487.171326, 257168309890.072144, -1381125204152.817383},
|
||||
Rotation = {-0.106166, 0.981574, -0.084545, 0.134513},
|
||||
},
|
||||
Modules = {
|
||||
"sun",
|
||||
|
||||
@@ -38,7 +38,8 @@ return {
|
||||
CommonFolder = "common",
|
||||
Camera = {
|
||||
Focus = "Earth",
|
||||
Position = {1, 0, 0, 2},
|
||||
Position = {526781518487.171326, 257168309890.072144, -1381125204152.817383},
|
||||
Rotation = {-0.106166, 0.981574, -0.084545, 0.134513},
|
||||
},
|
||||
Modules = {
|
||||
"sun",
|
||||
|
||||
@@ -49,7 +49,8 @@ return {
|
||||
CommonFolder = "common",
|
||||
Camera = {
|
||||
Focus = "NewHorizons",
|
||||
Position = {1, 0, 0, 5},
|
||||
Position = {4662120063743.592773, 1263245003503.724854, -955413856565.788086},
|
||||
Rotation = {0.683224, -0.165934, 0.701234, 0.118073},
|
||||
},
|
||||
Modules = {
|
||||
"sun",
|
||||
|
||||
@@ -36,7 +36,8 @@ return {
|
||||
CommonFolder = "common",
|
||||
Camera = {
|
||||
Focus = "67P",
|
||||
Position = {1, 0, 0, 5},
|
||||
Position = {526781518487.171326, 257168309890.072144, -1381125204152.817383},
|
||||
Rotation = {-0.106166, 0.981574, -0.084545, 0.134513},
|
||||
},
|
||||
Modules = {
|
||||
"sun",
|
||||
|
||||
@@ -160,9 +160,12 @@ public:
|
||||
void setCamera(Camera* camera);
|
||||
|
||||
// Interaction mode setters
|
||||
void setStateFromDictionary(const ghoul::Dictionary& cameraDict);
|
||||
void setCameraStateFromDictionary(const ghoul::Dictionary& cameraDict);
|
||||
void setInteractionModeToOrbital();
|
||||
void setInteractionModeToGlobeBrowsing();
|
||||
void setInteractionFriction(double friction);
|
||||
void setInteractionSensitivity(double sensitivity);
|
||||
void setInteractionFollowScaleFactor(double scaleFactor);
|
||||
|
||||
void resetKeyBindings();
|
||||
|
||||
@@ -176,7 +179,7 @@ public:
|
||||
void update(double deltaTime);
|
||||
|
||||
// Accessors
|
||||
ghoul::Dictionary getStateDictionary();
|
||||
ghoul::Dictionary getCameraStateDictionary();
|
||||
SceneGraphNode* const focusNode() const;
|
||||
Camera* const camera() const;
|
||||
const InputState& inputState() const;
|
||||
|
||||
@@ -105,36 +105,55 @@ protected:
|
||||
template <typename T, typename ScaleType>
|
||||
class DelayedVariable {
|
||||
public:
|
||||
DelayedVariable(ScaleType scale) {
|
||||
_scale = scale;
|
||||
DelayedVariable(ScaleType scaleFactor, ScaleType friction) {
|
||||
_scaleFactor = scaleFactor;
|
||||
_friction = glm::max(friction, ScaleType(0.0));
|
||||
}
|
||||
void set(T value, double dt) {
|
||||
_targetValue = value;
|
||||
_currentValue = _currentValue + (_targetValue - _currentValue) *
|
||||
min(_scale * dt, 1.0); // less or equal to 1.0 keeps it stable
|
||||
min(_scaleFactor * dt, 1.0); // less or equal to 1.0 keeps it stable
|
||||
}
|
||||
void decelerate(double dt) {
|
||||
_currentValue = _currentValue + (- _currentValue) *
|
||||
min(_friction * dt, 1.0); // less or equal to 1.0 keeps it stable
|
||||
}
|
||||
void setHard(T value) {
|
||||
_targetValue = value;
|
||||
_currentValue = value;
|
||||
}
|
||||
void setFriction(ScaleType friction) {
|
||||
_friction = glm::max(friction, ScaleType(0.0));
|
||||
}
|
||||
void setScaleFactor(ScaleType scaleFactor) {
|
||||
_scaleFactor = scaleFactor;
|
||||
}
|
||||
T get() {
|
||||
return _currentValue;
|
||||
}
|
||||
private:
|
||||
ScaleType _scale;
|
||||
ScaleType _scaleFactor;
|
||||
ScaleType _friction;
|
||||
T _targetValue;
|
||||
T _currentValue;
|
||||
};
|
||||
|
||||
struct MouseState {
|
||||
MouseState(double scale)
|
||||
: velocity(scale)
|
||||
MouseState(double scaleFactor)
|
||||
: velocity(scaleFactor, 1)
|
||||
, previousPosition(0.0, 0.0) {}
|
||||
void setFriction(double friction) {
|
||||
velocity.setFriction(friction);
|
||||
}
|
||||
void setVelocityScaleFactor(double scaleFactor) {
|
||||
velocity.setScaleFactor(scaleFactor);
|
||||
}
|
||||
glm::dvec2 previousPosition;
|
||||
DelayedVariable<glm::dvec2, double> velocity;
|
||||
};
|
||||
|
||||
SceneGraphNode* _focusNode = nullptr;
|
||||
glm::dvec3 _previousFocusNodePosition;
|
||||
};
|
||||
|
||||
class KeyframeInteractionMode : public InteractionMode
|
||||
@@ -165,6 +184,9 @@ public:
|
||||
*/
|
||||
MouseStates(double sensitivity, double velocityScaleFactor);
|
||||
void updateMouseStatesFromInput(const InputState& inputState, double deltaTime);
|
||||
void setFriction(double friction);
|
||||
void setSensitivity(double sensitivity);
|
||||
void setVelocityScaleFactor(double scaleFactor);
|
||||
private:
|
||||
friend class OrbitalInteractionMode;
|
||||
friend class GlobeBrowsingInteractionMode;
|
||||
|
||||
@@ -741,7 +741,7 @@ void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActi
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::setStateFromDictionary(const ghoul::Dictionary& cameraDict) {
|
||||
void InteractionHandler::setCameraStateFromDictionary(const ghoul::Dictionary& cameraDict) {
|
||||
bool readSuccessful = true;
|
||||
|
||||
std::string focus;
|
||||
@@ -768,9 +768,13 @@ void InteractionHandler::setStateFromDictionary(const ghoul::Dictionary& cameraD
|
||||
_camera->setPositionVec3(cameraPosition);
|
||||
_camera->setRotation(glm::dquat(
|
||||
cameraRotation.x, cameraRotation.y, cameraRotation.z, cameraRotation.w));
|
||||
|
||||
// Explicitly synch
|
||||
_camera->preSynchronization();
|
||||
_camera->postSynchronizationPreDraw();
|
||||
}
|
||||
|
||||
ghoul::Dictionary InteractionHandler::getStateDictionary() {
|
||||
ghoul::Dictionary InteractionHandler::getCameraStateDictionary() {
|
||||
glm::dvec3 cameraPosition;
|
||||
glm::dquat quat;
|
||||
glm::dvec4 cameraRotation;
|
||||
@@ -787,12 +791,40 @@ ghoul::Dictionary InteractionHandler::getStateDictionary() {
|
||||
return cameraDict;
|
||||
}
|
||||
|
||||
void InteractionHandler::setInteractionFriction(double friction) {
|
||||
if (friction < 0) {
|
||||
LWARNING("Clamping friction factor to a value bigger or equal to 0");
|
||||
friction = glm::max(friction, 0.0);
|
||||
}
|
||||
_mouseStates->setFriction(friction);
|
||||
LINFO("Interaction friction set to: " << friction);
|
||||
}
|
||||
|
||||
void InteractionHandler::setInteractionSensitivity(double sensitivity) {
|
||||
if (sensitivity < 0) {
|
||||
LWARNING("Clamping scale sensitivity to a value bigger or equal to 0");
|
||||
sensitivity = glm::max(sensitivity, 0.0);
|
||||
}
|
||||
_mouseStates->setSensitivity(sensitivity);
|
||||
LINFO("Interaction sensitivity set to: " << sensitivity);
|
||||
}
|
||||
|
||||
void InteractionHandler::setInteractionFollowScaleFactor(double scaleFactor) {
|
||||
const double minFollowScaleFactor = 0.01;
|
||||
if (scaleFactor < minFollowScaleFactor) {
|
||||
LWARNING("Clamping scale factor to a value bigger or equal to " << minFollowScaleFactor);
|
||||
scaleFactor = glm::max(scaleFactor, minFollowScaleFactor);
|
||||
}
|
||||
_mouseStates->setVelocityScaleFactor(scaleFactor);
|
||||
LINFO("Interaction velocity scale factor set to: " << scaleFactor);
|
||||
}
|
||||
|
||||
void InteractionHandler::saveCameraStateToFile(const std::string& filepath) {
|
||||
if (!filepath.empty()) {
|
||||
auto fullpath = absPath(filepath);
|
||||
LINFO("Saving camera position: " << filepath);
|
||||
|
||||
ghoul::Dictionary cameraDict = getStateDictionary();
|
||||
ghoul::Dictionary cameraDict = getCameraStateDictionary();
|
||||
|
||||
// TODO : Should get the camera state as a dictionary and save the dictionary to
|
||||
// a file in form of a lua state and not use ofstreams here.
|
||||
@@ -827,7 +859,7 @@ void InteractionHandler::restoreCameraStateFromFile(const std::string& filepath)
|
||||
ghoul::Dictionary cameraDict;
|
||||
try {
|
||||
ghoul::lua::loadDictionaryFromFile(filepath, cameraDict);
|
||||
setStateFromDictionary(cameraDict);
|
||||
setCameraStateFromDictionary(cameraDict);
|
||||
_cameraUpdatedFromScript = true;
|
||||
}
|
||||
catch (ghoul::RuntimeError& e) {
|
||||
@@ -880,7 +912,25 @@ scripting::ScriptEngine::LuaLibrary InteractionHandler::luaLibrary() {
|
||||
&luascriptfunctions::restoreCameraStateFromFile,
|
||||
"string",
|
||||
"Restore the camera state from file"
|
||||
}
|
||||
},
|
||||
{
|
||||
"setInteractionFriction",
|
||||
&luascriptfunctions::setInteractionFriction,
|
||||
"number",
|
||||
"Set the interaction friction"
|
||||
},
|
||||
{
|
||||
"setInteractionSensitivity",
|
||||
&luascriptfunctions::setInteractionSensitivity,
|
||||
"number",
|
||||
"Set the interaction sensitivity"
|
||||
},
|
||||
{
|
||||
"setInteractionFollowScaleFactor",
|
||||
&luascriptfunctions::setInteractionFollowScaleFactor,
|
||||
"number",
|
||||
"Set the interaction follow scale factor"
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -174,6 +174,43 @@ int saveCameraStateToFile(lua_State* L) {
|
||||
OsEng.interactionHandler().saveCameraStateToFile(cameraStateFilePath);
|
||||
}
|
||||
|
||||
int setInteractionFriction(lua_State* L) {
|
||||
const std::string _loggerCat = "lua.setInteractionFriction";
|
||||
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 1)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
|
||||
|
||||
double friction = luaL_checknumber(L, -1);
|
||||
|
||||
OsEng.interactionHandler().setInteractionFriction(friction);
|
||||
}
|
||||
|
||||
int setInteractionSensitivity(lua_State* L) {
|
||||
const std::string _loggerCat = "lua.setInteractionFriction";
|
||||
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 1)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
|
||||
|
||||
double sensitivity = luaL_checknumber(L, -1);
|
||||
|
||||
OsEng.interactionHandler().setInteractionSensitivity(sensitivity);
|
||||
}
|
||||
|
||||
int setInteractionFollowScaleFactor(lua_State* L) {
|
||||
const std::string _loggerCat = "lua.setInteractionFriction";
|
||||
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 1)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
|
||||
|
||||
double scaleFactor = luaL_checknumber(L, -1);
|
||||
|
||||
OsEng.interactionHandler().setInteractionFollowScaleFactor(scaleFactor);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_OLD_INTERACTIONHANDLER
|
||||
|
||||
/**
|
||||
|
||||
@@ -141,7 +141,6 @@ namespace interaction {
|
||||
|
||||
|
||||
InteractionMode::InteractionMode() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +150,7 @@ InteractionMode::~InteractionMode() {
|
||||
|
||||
void InteractionMode::setFocusNode(SceneGraphNode* focusNode) {
|
||||
_focusNode = focusNode;
|
||||
_previousFocusNodePosition = _focusNode->worldPosition().dvec3();
|
||||
}
|
||||
|
||||
SceneGraphNode* InteractionMode::focusNode() {
|
||||
@@ -198,7 +198,7 @@ void OrbitalInteractionMode::MouseStates::updateMouseStatesFromInput(const Input
|
||||
_localRotationMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity, deltaTime);
|
||||
|
||||
_globalRotationMouseState.previousPosition = mousePosition;
|
||||
_globalRotationMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_globalRotationMouseState.velocity.decelerate(deltaTime);
|
||||
}
|
||||
else {
|
||||
glm::dvec2 mousePositionDelta =
|
||||
@@ -206,15 +206,15 @@ void OrbitalInteractionMode::MouseStates::updateMouseStatesFromInput(const Input
|
||||
_globalRotationMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity, deltaTime);
|
||||
|
||||
_localRotationMouseState.previousPosition = mousePosition;
|
||||
_localRotationMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_localRotationMouseState.velocity.decelerate(deltaTime);
|
||||
}
|
||||
}
|
||||
else { // !button1Pressed
|
||||
_localRotationMouseState.previousPosition = mousePosition;
|
||||
_localRotationMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_localRotationMouseState.velocity.decelerate(deltaTime);
|
||||
|
||||
_globalRotationMouseState.previousPosition = mousePosition;
|
||||
_globalRotationMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_globalRotationMouseState.velocity.decelerate(deltaTime);
|
||||
}
|
||||
if (button2Pressed) {
|
||||
glm::dvec2 mousePositionDelta =
|
||||
@@ -223,7 +223,7 @@ void OrbitalInteractionMode::MouseStates::updateMouseStatesFromInput(const Input
|
||||
}
|
||||
else { // !button2Pressed
|
||||
_truckMovementMouseState.previousPosition = mousePosition;
|
||||
_truckMovementMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_truckMovementMouseState.velocity.decelerate(deltaTime);
|
||||
}
|
||||
if (button3Pressed) {
|
||||
if (keyCtrlPressed) {
|
||||
@@ -232,7 +232,7 @@ void OrbitalInteractionMode::MouseStates::updateMouseStatesFromInput(const Input
|
||||
_localRollMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity, deltaTime);
|
||||
|
||||
_globalRollMouseState.previousPosition = mousePosition;
|
||||
_globalRollMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_globalRollMouseState.velocity.decelerate(deltaTime);
|
||||
}
|
||||
else {
|
||||
glm::dvec2 mousePositionDelta =
|
||||
@@ -240,20 +240,41 @@ void OrbitalInteractionMode::MouseStates::updateMouseStatesFromInput(const Input
|
||||
_globalRollMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity, deltaTime);
|
||||
|
||||
_localRollMouseState.previousPosition = mousePosition;
|
||||
_localRollMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_localRollMouseState.velocity.decelerate(deltaTime);
|
||||
}
|
||||
}
|
||||
else { // !button3Pressed
|
||||
_globalRollMouseState.previousPosition = mousePosition;
|
||||
_globalRollMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_globalRollMouseState.velocity.decelerate(deltaTime);
|
||||
|
||||
_localRollMouseState.previousPosition = mousePosition;
|
||||
_localRollMouseState.velocity.set(glm::dvec2(0, 0), deltaTime);
|
||||
_localRollMouseState.velocity.decelerate(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void OrbitalInteractionMode::MouseStates::setFriction(double friction) {
|
||||
_globalRotationMouseState.setFriction(friction);
|
||||
_localRotationMouseState.setFriction(friction);
|
||||
_truckMovementMouseState.setFriction(friction);
|
||||
_localRollMouseState.setFriction(friction);
|
||||
_globalRollMouseState.setFriction(friction);
|
||||
}
|
||||
|
||||
void OrbitalInteractionMode::MouseStates::setSensitivity(double sensitivity) {
|
||||
_sensitivity = sensitivity;
|
||||
}
|
||||
|
||||
void OrbitalInteractionMode::MouseStates::setVelocityScaleFactor(double scaleFactor) {
|
||||
_globalRotationMouseState.setVelocityScaleFactor(scaleFactor);
|
||||
_localRotationMouseState.setVelocityScaleFactor(scaleFactor);
|
||||
_truckMovementMouseState.setVelocityScaleFactor(scaleFactor);
|
||||
_localRollMouseState.setVelocityScaleFactor(scaleFactor);
|
||||
_globalRollMouseState.setVelocityScaleFactor(scaleFactor);
|
||||
}
|
||||
|
||||
OrbitalInteractionMode::OrbitalInteractionMode(std::shared_ptr<MouseStates> mouseStates)
|
||||
: _mouseStates(mouseStates){
|
||||
: InteractionMode()
|
||||
, _mouseStates(mouseStates){
|
||||
|
||||
}
|
||||
|
||||
@@ -266,9 +287,15 @@ void OrbitalInteractionMode::updateCameraStateFromMouseStates(Camera& camera) {
|
||||
if (_focusNode) {
|
||||
// Read the current state of the camera and focus node
|
||||
dvec3 camPos = camera.positionVec3();
|
||||
|
||||
// Follow focus nodes movement
|
||||
dvec3 centerPos = _focusNode->worldPosition().dvec3();
|
||||
dvec3 focusNodeDiff = centerPos - _previousFocusNodePosition;
|
||||
_previousFocusNodePosition = centerPos;
|
||||
camPos += focusNodeDiff;
|
||||
|
||||
dquat totalRotation = camera.rotationQuaternion();
|
||||
dvec3 directionToCenter = normalize(centerPos - camera.positionVec3());
|
||||
dvec3 directionToCenter = normalize(centerPos - camPos);
|
||||
dvec3 lookUp = camera.lookUpVectorWorldSpace();
|
||||
double boundingSphere = _focusNode->boundingSphere().lengthf();
|
||||
dvec3 camDirection = camera.viewDirectionWorldSpace();
|
||||
@@ -380,8 +407,14 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates(Camera& came
|
||||
double minHeightAboveGround = _globe->cameraMinHeight();
|
||||
|
||||
// Read the current state of the camera and focusnode
|
||||
dvec3 centerPos = _focusNode->worldPosition().dvec3();
|
||||
dvec3 camPos = camera.positionVec3();
|
||||
|
||||
// Follow focus nodes movement
|
||||
dvec3 centerPos = _focusNode->worldPosition().dvec3();
|
||||
dvec3 focusNodeDiff = centerPos - _previousFocusNodePosition;
|
||||
_previousFocusNodePosition = centerPos;
|
||||
camPos += focusNodeDiff;
|
||||
|
||||
dquat totalRotation = camera.rotationQuaternion();
|
||||
dvec3 lookUp = camera.lookUpVectorWorldSpace();
|
||||
dvec3 camDirection = camera.viewDirectionWorldSpace();
|
||||
|
||||
+1
-7
@@ -229,15 +229,9 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
|
||||
// Read the camera dictionary
|
||||
ghoul::Dictionary cameraDictionary;
|
||||
if (dictionary.getValue(KeyCamera, cameraDictionary)) {
|
||||
OsEng.interactionHandler().setStateFromDictionary(cameraDictionary);
|
||||
OsEng.interactionHandler().setCameraStateFromDictionary(cameraDictionary);
|
||||
}
|
||||
|
||||
// explicitly update and sync the camera
|
||||
Camera* c = OsEng.ref().renderEngine().camera();
|
||||
c->preSynchronization();
|
||||
c->postSynchronizationPreDraw();
|
||||
|
||||
|
||||
// HOLY MOLY! This much code to read a camera state? Added the above code with
|
||||
// functions to set camera state from a dictionary in interactio handler and commented
|
||||
// away the below code.
|
||||
|
||||
Reference in New Issue
Block a user