Enable setting of friction, sensitivity and followscalefactor in interaction handler.

This commit is contained in:
Kalle Bladin
2016-06-29 21:13:04 -04:00
parent 24152be38e
commit 161d722623
10 changed files with 180 additions and 37 deletions
+2 -1
View File
@@ -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",
+2 -1
View File
@@ -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",
+2 -1
View File
@@ -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",
+2 -1
View File
@@ -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;
+55 -5
View File
@@ -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
/**
+46 -13
View File
@@ -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
View File
@@ -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.