Files
OpenSpace/include/openspace/interaction/interactionmode.h
Alexander Bock d139dd2d22 Clean include guards in OpenSpace core
Remove unused files
2016-12-09 13:54:22 +01:00

284 lines
10 KiB
C++

/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* 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___INTERACTIONMODE___H__
#define __OPENSPACE_CORE___INTERACTIONMODE___H__
#include <openspace/interaction/keyboardcontroller.h>
#include <openspace/network/parallelconnection.h>
#include <openspace/util/mouse.h>
#include <openspace/util/keys.h>
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
#include <modules/globebrowsing/tile/tileindex.h>
#include <modules/globebrowsing/geometry/geodetic2.h>
#endif
#include <list>
namespace openspace {
class Camera;
class SceneGraphNode;
namespace globebrowsing {
class RenderableGlobe;
}
namespace interaction {
template <typename T>
class Interpolator
{
public:
Interpolator(std::function<T(double)> transferFunction)
: _t(0.0)
, _transferFunction(transferFunction) {};
~Interpolator() {};
void start() { _t = 0.0; };
void end() { _t = 1.0; };
void step(double delta) { _t += delta; };
T value() { return _transferFunction(_t); };
bool isInterpolating() { return _t < 1.0; };
private:
std::function<T(double)> _transferFunction;
double _t;
};
class InputState
{
public:
InputState();
~InputState();
// Callback functions
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
void mouseButtonCallback(MouseButton button, MouseAction action);
void mousePositionCallback(double mouseX, double mouseY);
void mouseScrollWheelCallback(double mouseScrollDelta);
// Mutators
void addKeyframe(const datamessagestructures::CameraKeyframe &kf);
void clearKeyframes();
void clearOldKeyframes();
// Accessors
const std::list<std::pair<Key, KeyModifier> >& getPressedKeys() const;
const std::list<MouseButton>& getPressedMouseButtons() const;
glm::dvec2 getMousePosition() const;
double getMouseScrollDelta() const;
const std::vector<datamessagestructures::CameraKeyframe>& keyframes() const;
bool isKeyPressed(std::pair<Key, KeyModifier> keyModPair) const;
bool isKeyPressed(Key key) const;
bool isMouseButtonPressed(MouseButton mouseButton) const;
private:
// Input from keyboard and mouse
std::list<std::pair<Key, KeyModifier> > _keysDown;
std::list<MouseButton> _mouseButtonsDown;
glm::dvec2 _mousePosition;
double _mouseScrollDelta;
// Remote input via keyframes
std::vector<datamessagestructures::CameraKeyframe> _keyframes;
};
class InteractionMode
{
public:
InteractionMode();
~InteractionMode();
// Mutators
virtual void setFocusNode(SceneGraphNode* focusNode);
// Accessors
SceneGraphNode* focusNode();
Interpolator<double>& rotateToFocusNodeInterpolator();
virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime) = 0;
virtual void updateCameraStateFromMouseStates(Camera& camera, double deltaTime) = 0;
protected:
/**
Inner class that acts as a smoothing filter to a variable. The filter has a step
response on a form that resembles the function y = 1-e^(-t/scale). The variable
will be updates as soon as it is set to a value (calling the set() function).
*/
template <typename T, typename ScaleType>
class DelayedVariable {
public:
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) *
std::min(_scaleFactor * dt, 1.0); // less or equal to 1.0 keeps it stable
}
void decelerate(double dt) {
_currentValue = _currentValue + (- _currentValue) *
std::min(_scaleFactor * _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 _scaleFactor;
ScaleType _friction;
T _targetValue;
T _currentValue;
};
struct MouseState {
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;
glm::dquat _previousFocusNodeRotation;
Interpolator<double> _rotateToFocusNodeInterpolator;
};
class KeyframeInteractionMode : public InteractionMode
{
public:
KeyframeInteractionMode();
~KeyframeInteractionMode();
virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime);
virtual void updateCameraStateFromMouseStates(Camera& camera, double deltaTime);
private:
std::vector<datamessagestructures::CameraKeyframe> _keyframes;
double _currentKeyframeTime;
};
class GlobeBrowsingInteractionMode;
class OrbitalInteractionMode : public InteractionMode
{
public:
class MouseStates
{
public:
/**
\param sensitivity
\param velocityScaleFactor can be set to 60 to remove the inertia of the
interaction. Lower value will make it harder to move the camera.
*/
MouseStates(double sensitivity, double velocityScaleFactor);
void updateMouseStatesFromInput(const InputState& inputState, double deltaTime);
void setRotationalFriction(double friction);
void setHorizontalFriction(double friction);
void setVerticalFriction(double friction);
void setSensitivity(double sensitivity);
void setVelocityScaleFactor(double scaleFactor);
glm::dvec2 synchedGlobalRotationMouseVelocity();
glm::dvec2 synchedLocalRotationMouseVelocity();
glm::dvec2 synchedTruckMovementMouseVelocity();
glm::dvec2 synchedLocalRollMouseVelocity();
glm::dvec2 synchedGlobalRollMouseVelocity();
private:
double _sensitivity;
MouseState _globalRotationMouseState;
MouseState _localRotationMouseState;
MouseState _truckMovementMouseState;
MouseState _localRollMouseState;
MouseState _globalRollMouseState;
};
OrbitalInteractionMode(std::shared_ptr<MouseStates> mouseStates);
~OrbitalInteractionMode();
//virtual void update(Camera& camera, const InputState& inputState, double deltaTime);
virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime);
virtual void updateCameraStateFromMouseStates(Camera& camera, double deltaTime);
protected:
//void updateCameraStateFromMouseStates(Camera& camera, double deltaTime);
std::shared_ptr<MouseStates> _mouseStates;
};
class GlobeBrowsingInteractionMode : public OrbitalInteractionMode
{
public:
GlobeBrowsingInteractionMode(std::shared_ptr<MouseStates> mouseStates);
~GlobeBrowsingInteractionMode();
virtual void setFocusNode(SceneGraphNode* focusNode);
//virtual void update(Camera& camera, const InputState& inputState, double deltaTime);
virtual void updateCameraStateFromMouseStates(Camera& camera, double deltaTime);
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
void goToChunk(Camera& camera, globebrowsing::TileIndex ti, glm::vec2 uv,
bool resetCameraDirection);
void goToGeodetic2(Camera& camera, globebrowsing::Geodetic2 geo2,
bool resetCameraDirection);
void goToGeodetic3(Camera& camera, globebrowsing::Geodetic3 geo3);
void resetCameraDirection(Camera& camera, globebrowsing::Geodetic2 geo2);
#endif
private:
//void updateCameraStateFromMouseStates(Camera& camera, double deltaTime);
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
globebrowsing::RenderableGlobe* _globe;
#endif
};
} // namespace interaction
} // namespace openspace
#endif // __OPENSPACE_CORE___INTERACTIONMODE___H__