Smooth movements using delay.

This commit is contained in:
Kalle Bladin
2016-05-24 19:34:57 -04:00
parent 54a824e667
commit f2c7a826b3
2 changed files with 105 additions and 34 deletions

View File

@@ -182,6 +182,12 @@ public:
virtual void update(double deltaTime) = 0;
protected:
template <typename T>
T delay(T in, T target, double scale) {
return in + (target - in) * scale;
}
std::shared_ptr<InputState> _inputState;
SceneGraphNode* _focusNode;
Camera* _camera;
@@ -195,8 +201,21 @@ public:
virtual void update(double deltaTime);
private:
glm::dvec2 _previousMousePosition;
//glm::dvec2 _mouseVelocity;
glm::dvec2 _previousMousePositionGlobalRotation;
glm::dvec2 _mouseVelocityTargetGlobalRotation;
glm::dvec2 _mouseVelocityGlobalRotation;
glm::dvec2 _previousMousePositionLocalRotation;
glm::dvec2 _mouseVelocityTargetLocalRotation;
glm::dvec2 _mouseVelocityLocalRotation;
glm::dvec2 _previousMousePositionMove;
glm::dvec2 _mouseVelocityTargetMove;
glm::dvec2 _mouseVelocityMove;
glm::dvec2 _previousMousePositionRoll;
glm::dvec2 _mouseVelocityTargetRoll;
glm::dvec2 _mouseVelocityRoll;
glm::dquat _localCameraRotation;
glm::dquat _globalCameraRotation;

View File

@@ -711,10 +711,11 @@ OrbitalInteractionMode::~OrbitalInteractionMode()
void OrbitalInteractionMode::update(double deltaTime)
{
glm::dvec2 mousePosition = _inputState->getMousePosition();
glm::dvec2 mousePositionDelta =
_previousMousePosition - mousePosition;
glm::dvec2 mouseVelocity = mousePositionDelta * deltaTime * 0.01;
bool button1Pressed = _inputState->isMouseButtonPressed(MouseButton::Button1);
bool button2Pressed = _inputState->isMouseButtonPressed(MouseButton::Button2);
@@ -730,49 +731,100 @@ void OrbitalInteractionMode::update(double deltaTime)
glm::dvec3 newPosition = camPos;
if (button1Pressed) {
if (keyCtrlPressed) { // Do local rotation
glm::dvec3 eulerAngles(mouseVelocity.y, 0, 0);
glm::dquat rotationDiff = glm::dquat(eulerAngles);
_localCameraRotation = _localCameraRotation * rotationDiff;
}
else if (glm::length(mouseVelocity) > 0) { // Do global rotation
glm::dvec3 eulerAngles(-mouseVelocity.y, -mouseVelocity.x, 0);
glm::dquat rotationDiffCamSpace = glm::dquat(eulerAngles);
glm::dquat newRotationCamspace =
_globalCameraRotation * rotationDiffCamSpace;
glm::dquat rotationDiffWorldSpace =
newRotationCamspace * glm::inverse(_globalCameraRotation);
glm::dvec3 rotationDiffVec3 = posDiff * rotationDiffWorldSpace - posDiff;
newPosition = camPos + rotationDiffVec3;
glm::dvec3 lookUp = _camera->lookUpVectorWorldSpace();
glm::dmat4 lookAtMat = glm::lookAt(
glm::dvec3(0,0,0),
glm::normalize(centerPos - newPosition),
lookUp);
_globalCameraRotation =
glm::normalize(glm::quat_cast(glm::inverse(lookAtMat)));
if (keyCtrlPressed) { // Do local rotation
glm::dvec2 mousePositionDelta =
_previousMousePositionLocalRotation - mousePosition;
_mouseVelocityTargetLocalRotation = mousePositionDelta * deltaTime * 0.01;
}
else{ // Do global rotation
glm::dvec2 mousePositionDelta =
_previousMousePositionGlobalRotation - mousePosition;
_mouseVelocityTargetGlobalRotation = mousePositionDelta * deltaTime * 0.01;
}
}
if (button2Pressed) { // Move position
newPosition += - posDiff * mouseVelocity.y * 0.1;
glm::dvec2 mousePositionDelta =
_previousMousePositionMove - mousePosition;
_mouseVelocityTargetMove = mousePositionDelta * deltaTime * 0.01;
}
if (button3Pressed) { // Do roll
glm::dvec2 mousePositionDelta =
_previousMousePositionRoll - mousePosition;
_mouseVelocityTargetRoll = mousePositionDelta * deltaTime * 0.01;
}
{
glm::dvec3 eulerAngles(_mouseVelocityLocalRotation.y, 0, 0);
glm::dquat rotationDiff = glm::dquat(eulerAngles);
_localCameraRotation = _localCameraRotation * rotationDiff;
}
{
glm::dvec3 eulerAngles(-_mouseVelocityGlobalRotation.y, -_mouseVelocityGlobalRotation.x, 0);
glm::dquat rotationDiffCamSpace = glm::dquat(eulerAngles);
glm::dquat newRotationCamspace =
_globalCameraRotation * rotationDiffCamSpace;
glm::dquat rotationDiffWorldSpace =
newRotationCamspace * glm::inverse(_globalCameraRotation);
glm::dvec3 rotationDiffVec3 = posDiff * rotationDiffWorldSpace - posDiff;
newPosition = camPos + rotationDiffVec3;
glm::dvec3 lookUp = _camera->lookUpVectorWorldSpace();
glm::dmat4 lookAtMat = glm::lookAt(
glm::dvec3(0, 0, 0),
glm::normalize(centerPos - newPosition),
lookUp);
_globalCameraRotation =
glm::normalize(glm::quat_cast(glm::inverse(lookAtMat)));
}
{
newPosition += -posDiff * _mouseVelocityMove.y;
}
{
glm::dquat cameraRollRotation =
glm::angleAxis(mouseVelocity.x, glm::normalize(posDiff));
glm::angleAxis(_mouseVelocityRoll.x, glm::normalize(posDiff));
_globalCameraRotation = cameraRollRotation * _globalCameraRotation;
}
_camera->setRotation(_globalCameraRotation * _localCameraRotation);
_camera->setPositionVec3(newPosition);
}
// Update new state
if (!button1Pressed && !button2Pressed && !button3Pressed) {
_previousMousePosition = mousePosition + (_previousMousePosition - mousePosition) * 0.8;
if (!button1Pressed) {
//_previousMousePosition = mousePosition + (_previousMousePosition - mousePosition) * 0.8;
_previousMousePositionGlobalRotation = mousePosition;
_mouseVelocityTargetGlobalRotation = glm::dvec2(0,0);
_previousMousePositionLocalRotation = mousePosition;
_mouseVelocityTargetLocalRotation = glm::dvec2(0, 0);
}
if (!button2Pressed) {
//_previousMousePosition = mousePosition + (_previousMousePosition - mousePosition) * 0.8;
_previousMousePositionMove = mousePosition;
_mouseVelocityTargetMove = glm::dvec2(0, 0);
}
if (!button3Pressed) {
//_previousMousePosition = mousePosition + (_previousMousePosition - mousePosition) * 0.8;
_previousMousePositionRoll = mousePosition;
_mouseVelocityTargetRoll = glm::dvec2(0, 0);
}
double scale = 0.02;
_mouseVelocityGlobalRotation = delay(_mouseVelocityGlobalRotation, _mouseVelocityTargetGlobalRotation, scale);
_mouseVelocityLocalRotation = delay(_mouseVelocityLocalRotation, _mouseVelocityTargetLocalRotation, scale);
_mouseVelocityMove = delay(_mouseVelocityMove, _mouseVelocityTargetMove, scale);
_mouseVelocityRoll = delay(_mouseVelocityRoll, _mouseVelocityTargetRoll, scale);
}