Fixed some touch behavior (especially zoom) and implemented lower-right corner double-tap for zooming out

This commit is contained in:
GPayne
2018-05-08 16:44:53 -06:00
parent d686212b35
commit a767c2fd08
2 changed files with 166 additions and 238 deletions

View File

@@ -38,14 +38,30 @@
#include <openspace/properties/vector/vec4property.h>
//#define TOUCH_DEBUG_PROPERTIES
#define CONST_TIME_DECAY
#define SPEED_BRAKE
#define ZOOM_CORNER_TAP
namespace openspace {
class Camera;
class SceneGraphNode;
//Class used for keeping track of the recent average frame time
class FrameTimeAverage
{
public:
//Update the circular buffer with the most recent frame time
void updateWithNewFrame(double sample);
//Get the value of the most recent average frame time (seconds)
double getAvgFrameTime();
private:
static const int totalSamples = 10;
int _nSamples = 0;
double _samples[totalSamples];
double _runningTotal = 0.0;
int index = 0;
};
class TouchInteraction : public properties::PropertyOwner {
public:
using Point = std::pair<int, TUIO::TuioPoint>;
@@ -53,7 +69,11 @@ public:
TouchInteraction();
// for interpretInteraction()
enum Type { ROT = 0, PINCH, PAN, ROLL, PICK };
enum Type { ROT = 0, PINCH, PAN, ROLL, PICK
#ifdef ZOOM_CORNER_TAP
, ZOOM_OUT
#endif
};
// Stores the velocity in all 6DOF
struct VelocityStates {
@@ -150,6 +170,17 @@ private:
void computeVelocities(const std::vector<TUIO::TuioCursor>& list,
const std::vector<Point>& lastProcessed);
//Compute velocity based on double-tap for zooming
double computeTapZoomDistance(double zoomGain);
//Compute coefficient for velocity decay to be applied in decceleration
double computeConstTimeDecayCoefficient(double velocity);
//Compute coefficient of decay based on current frametime; if frametime has been
// longer than usual then multiple decay steps may be applied to keep the decay
// relative to user time
double computeDecayCoeffFromFrametime(double coeff, int times);
/* Decelerate the velocities. Function is called in step() but is dereferenced from
* frame time to assure same behaviour on all systems
*/
@@ -174,7 +205,8 @@ private:
properties::FloatProperty _rollAngleThreshold;
properties::FloatProperty _orbitSpeedThreshold;
properties::FloatProperty _spinSensitivity;
properties::FloatProperty _zoomSensitivity;
properties::FloatProperty _zoomSensitivityExponential;
properties::FloatProperty _zoomSensitivityProportionalDist;
properties::FloatProperty _zoomSensitivityDistanceThreshold;
properties::FloatProperty _zoomBoundarySphereMultiplier;
properties::FloatProperty _inputStillThreshold;
@@ -186,17 +218,7 @@ private:
properties::Vec4Property _friction;
properties::FloatProperty _pickingRadiusMinimum;
properties::BoolProperty _ignoreGui;
#ifdef CONST_TIME_DECAY
properties::FloatProperty _constTimeDecay_secs;
#endif
#ifdef SPEED_BRAKE
properties::FloatProperty _speedLimitNearVelocityDivider;
properties::FloatProperty _speedLimitDistanceThresholdExp;
#else
properties::FloatProperty _speedLimitDistanceFraction;
#endif
properties::FloatProperty _zoomSpeedAsymmetryGain;
#ifdef TOUCH_DEBUG_PROPERTIES
struct DebugProperties : PropertyOwner {
@@ -228,6 +250,9 @@ private:
bool _directTouchMode;
bool _tap;
bool _doubleTap;
#ifdef ZOOM_CORNER_TAP
bool _zoomOutTap;
#endif
bool _lmSuccess;
bool _guiON;
std::vector<SelectedBody> _selected;
@@ -236,36 +261,6 @@ private:
glm::dquat _toSlerp;
glm::dvec3 _centroid;
#ifdef CONST_TIME_DECAY
class FrameTimeAverage
{
public:
void updateWithNewFrame (double sample)
{
if (sample > 0.0005) {
_samples[index++] = sample;
if (index >= totalSamples)
index = 0;
if (_nSamples < totalSamples)
_nSamples++;
}
}
double getAvgFrameTime () {
if (_nSamples == 0)
return 1.0 / 60.0;
else
return std::accumulate(_samples, _samples + _nSamples, 0.0)
/ (double)(_nSamples);
}
private:
static const int totalSamples = 10;
int _nSamples = 0;
double _samples[totalSamples];
double _runningTotal = 0.0;
int index = 0;
};
FrameTimeAverage _frameTimeAvg;
struct ConstantTimeDecayCoefficients {
@@ -275,7 +270,6 @@ private:
double pan = 0.0;
};
ConstantTimeDecayCoefficients _constTimeDecayCoeff;
#endif
};
} // openspace namespace

View File

@@ -140,12 +140,18 @@ namespace {
"" // @TODO Missing documentation
};
static const openspace::properties::Property::PropertyInfo ZoomSensitivityInfo = {
"ZoomSensitivity",
static const openspace::properties::Property::PropertyInfo ZoomSensitivityExpInfo = {
"ZoomSensitivityExp",
"Sensitivity of exponential zooming in relation to distance from focus node",
"" // @TODO Missing documentation
};
static const openspace::properties::Property::PropertyInfo ZoomSensitivityPropInfo = {
"ZoomSensitivityProp",
"Sensitivity of zooming proportional to distance from focus node",
"" // @TODO Missing documentation
};
static const openspace::properties::Property::PropertyInfo ZoomSensitivityDistanceThresholdInfo = {
"ZoomSensitivityDistanceThreshold",
"Threshold of distance to target node for whether or not to use exponential zooming",
@@ -158,39 +164,11 @@ namespace {
"" // @TODO Missing documentation
};
#ifdef CONST_TIME_DECAY
static const openspace::properties::Property::PropertyInfo ConstantTimeDecaySecsInfo = {
"ConstantTimeDecaySecs",
"Time duration that a pitch/roll/zoom/pan should take to decay to zero (seconds)",
""
};
#endif
#ifdef SPEED_BRAKE
static const openspace::properties::Property::PropertyInfo SpeedLimitNearVelocityDividerInfo = {
"SpeedLimitNearVelocityDivider",
"At close distance, velocity is limited by dividing distance-to-focus-node by this value",
""
};
static const openspace::properties::Property::PropertyInfo SpeedLimitFarDistanceThresholdExpInfo = {
"SpeedLimitFarDistanceThreshold",
"Threshold for distance (exponent for 10^) from camera to focus node where near velocity divider blends to far divider",
""
};
#else
static const openspace::properties::Property::PropertyInfo SpeedLimitDistanceFractionInfo = {
"SpeedLimitDistanceFraction",
"Speed limiting factor as a fraction of distance to focus node",
""
};
#endif //#ifdef SPEED_BRAKE
static const openspace::properties::Property::PropertyInfo ZoomSpeedAsymmetryGainInfo = {
"ZoomSpeedAsymmetryGain",
"At close distance to focus node, zooming-out velocity is this much faster (gain) than zooming-in velocity",
""
};
static const openspace::properties::Property::PropertyInfo InputSensitivityInfo = {
"InputSensitivity",
@@ -259,7 +237,8 @@ TouchInteraction::TouchInteraction()
, _rollAngleThreshold(RollThresholdInfo, 0.025f, 0.f, 0.05f)
, _orbitSpeedThreshold(OrbitSpinningThreshold, 0.005f, 0.f, 0.01f)
, _spinSensitivity(SpinningSensitivityInfo, 1.f, 0.f, 2.f)
, _zoomSensitivity(ZoomSensitivityInfo, 1.035f, 1.0f, 1.1f)
, _zoomSensitivityExponential(ZoomSensitivityExpInfo, 1.03f, 1.0f, 1.1f)
, _zoomSensitivityProportionalDist(ZoomSensitivityPropInfo, 11.f, 5.f, 50.f)
, _zoomSensitivityDistanceThreshold(ZoomSensitivityDistanceThresholdInfo, 0.05, 0.01, 0.25)
, _zoomBoundarySphereMultiplier(ZoomBoundarySphereMultiplierInfo, 1.001, 1.0, 1.01)
, _inputStillThreshold(InputSensitivityInfo, 0.0005f, 0.f, 0.001f)
@@ -267,7 +246,7 @@ TouchInteraction::TouchInteraction()
, _centroidStillThreshold(StationaryCentroidInfo, 0.0018f, 0.f, 0.01f)
, _panEnabled(PanModeInfo, false)
, _interpretPan(PanDeltaDistanceInfo, 0.015f, 0.f, 0.1f)
, _slerpTime(SlerpTimeInfo, 3.f, 0.f, 5.f)
, _slerpTime(SlerpTimeInfo, 3.f, 0.1f, 5.f)
, _guiButton(
GuiButtonSizeInfo,
glm::ivec2(32, 64),
@@ -291,17 +270,8 @@ TouchInteraction::TouchInteraction()
false
)
, _vel{ glm::dvec2(0.0), 0.0, 0.0, glm::dvec2(0.0) }
, _sensitivity{ glm::dvec2(0.08, 0.045), 4.0, 2.75, glm::dvec2(0.08, 0.045) }
#ifdef SPEED_BRAKE
, _speedLimitNearVelocityDivider(SpeedLimitNearVelocityDividerInfo, 0.7f, 0.01f, 3.f)
, _speedLimitDistanceThresholdExp(SpeedLimitFarDistanceThresholdExpInfo, 8.6, 7.0, 10.0)
#else
, _speedLimitDistanceFraction(SpeedLimitDistanceFractionInfo, 7.f, 0.1f, 20.0f)
#endif
#ifdef CONST_TIME_DECAY
, _sensitivity{ glm::dvec2(0.08, 0.045), 12.0 /*4.0*/, 2.75, glm::dvec2(0.08, 0.045) }
, _constTimeDecay_secs(ConstantTimeDecaySecsInfo, 1.75f, 0.1f, 4.0f)
#endif
, _zoomSpeedAsymmetryGain(ZoomSpeedAsymmetryGainInfo, 15.f, 1.f, 100.f)
// calculated with two vectors with known diff in length, then
// projDiffLength/diffLength.
, _projectionScaleFactor(1.000004)
@@ -312,6 +282,9 @@ TouchInteraction::TouchInteraction()
, _directTouchMode(false)
, _tap(false)
, _doubleTap(false)
#ifdef ZOOM_CORNER_TAP
, _zoomOutTap(false)
#endif
, _lmSuccess(true)
, _guiON(false)
#ifdef TOUCH_DEBUG_PROPERTIES
@@ -330,19 +303,11 @@ TouchInteraction::TouchInteraction()
addProperty(_rollAngleThreshold);
addProperty(_orbitSpeedThreshold);
addProperty(_spinSensitivity);
addProperty(_zoomSensitivity);
addProperty(_zoomSensitivityExponential);
addProperty(_zoomSensitivityProportionalDist);
addProperty(_zoomSensitivityDistanceThreshold);
addProperty(_zoomBoundarySphereMultiplier);
#ifdef SPEED_BRAKE
addProperty(_speedLimitNearVelocityDivider);
addProperty(_speedLimitDistanceThresholdExp);
#else
addProperty(_speedLimitDistanceFraction);
#endif
#ifdef CONST_TIME_DECAY
addProperty(_constTimeDecay_secs);
#endif
addProperty(_zoomSpeedAsymmetryGain);
addProperty(_inputStillThreshold);
addProperty(_centroidStillThreshold);
addProperty(_panEnabled);
@@ -389,6 +354,27 @@ void TouchInteraction::updateStateFromInput(const std::vector<TuioCursor>& list,
_time.initSession();
}
#ifdef ZOOM_CORNER_TAP
WindowWrapper& wrapper = OsEng.windowWrapper();
glm::ivec2 res = wrapper.currentWindowSize();
glm::dvec2 pos = glm::vec2(
list.at(0).getScreenX(res.x),
list.at(0).getScreenY(res.y)
);
const float bottomCornerSizeForZoomTap_fraction = 0.08f;
int zoomTapThresholdX = (float)res.x * (1.0f - bottomCornerSizeForZoomTap_fraction);
int zoomTapThresholdY = (float)res.y * (1.0f - bottomCornerSizeForZoomTap_fraction);
bool isTapInLowerCorner = ( std::abs(pos.x) > zoomTapThresholdX
&& std::abs(pos.y) > zoomTapThresholdY );
if( _doubleTap && isTapInLowerCorner ) {
_zoomOutTap = true;
_tap = false;
_doubleTap = false;
}
#endif
if (!guiMode(list)) {
if (_directTouchMode && _selected.size() > 0 && list.size() == _selected.size()) {
#ifdef TOUCH_DEBUG_PROPERTIES
@@ -444,6 +430,7 @@ bool TouchInteraction::guiMode(const std::vector<TuioCursor>& list) {
else if (_guiON) {
module.touchInput = { _guiON, pos, 1 }; // emulate touch input as a mouse
}
return _guiON;
}
@@ -952,6 +939,11 @@ int TouchInteraction::interpretInteraction(const std::vector<TuioCursor>& list,
_debugProperties.minDiff = minDiff;
#endif
#ifdef ZOOM_CORNER_TAP
if (_zoomOutTap)
return ZOOM_OUT;
else
#endif
if (_doubleTap) {
return PICK;
}
@@ -988,10 +980,6 @@ void TouchInteraction::computeVelocities(const std::vector<TuioCursor>& list,
{
TuioCursor cursor = list.at(0);
const int action = interpretInteraction(list, lastProcessed);
#ifdef CONST_TIME_DECAY
double stepsToDecay = _constTimeDecay_secs / _frameTimeAvg.getAvgFrameTime();
const double postDecayVelocityTarget = 1e-6;
#endif
#ifdef TOUCH_DEBUG_PROPERTIES
const std::map<int, std::string> interactionNames = {
@@ -1005,7 +993,8 @@ void TouchInteraction::computeVelocities(const std::vector<TuioCursor>& list,
if (pinchConsecCt > 0 && action != PINCH) {
if( pinchConsecCt > 3 )
LINFO("PINCH_gesture_ended_with " << pinchConsecZoomFactor << " drag_distance_and " << pinchConsecCt << " counts.");
LINFO("PINCH_gesture_ended_with " << pinchConsecZoomFactor
<< " drag_distance_and " << pinchConsecCt << " counts.");
pinchConsecCt = 0;
pinchConsecZoomFactor = 0.0;
}
@@ -1016,15 +1005,9 @@ void TouchInteraction::computeVelocities(const std::vector<TuioCursor>& list,
_vel.orbit += glm::dvec2(cursor.getXSpeed() *
_sensitivity.orbit.x, cursor.getYSpeed() *
_sensitivity.orbit.y);
#ifdef CONST_TIME_DECAY
/*double orbitVelocityAvg = (cursor.getXSpeed() * _sensitivity.orbit.x
+ cursor.getYSpeed() * _sensitivity.orbit.y) / 2.0;*/
double orbitVelocityAvg = glm::distance(_vel.orbit.x, _vel.orbit.y);
if( stepsToDecay > 0.0 && std::abs(orbitVelocityAvg) > 0.0 )
_constTimeDecayCoeff.orbit = std::pow((postDecayVelocityTarget / std::abs(orbitVelocityAvg)), (1.0 / stepsToDecay));
else
_constTimeDecayCoeff.orbit = 1.0;
#endif
_constTimeDecayCoeff.orbit
= computeConstTimeDecayCoefficient(orbitVelocityAvg);
break;
}
case PINCH: {
@@ -1057,42 +1040,26 @@ void TouchInteraction::computeVelocities(const std::vector<TuioCursor>& list,
glm::dvec3 centerPos = _focusNode->worldPosition();
glm::dvec3 currDistanceToFocusNode = camPos - centerPos;
double distanceFromFocusSurface = length(currDistanceToFocusNode) - _focusNode->boundingSphere();
double distanceFromFocusSurface = length(currDistanceToFocusNode)
- _focusNode->boundingSphere();
double zoomFactor = (distance - lastDistance);
#ifdef TOUCH_DEBUG_PROPERTIES
pinchConsecCt++;
pinchConsecZoomFactor += zoomFactor;
#endif
#ifdef CONST_TIME_DECAY
if( stepsToDecay > 0.0 && std::abs(_vel.zoom) > 0.0 )
//Use half the number of steps for zooming in order to decay faster
_constTimeDecayCoeff.zoom = std::pow((postDecayVelocityTarget / std::abs(_vel.zoom)), (1.0 / stepsToDecay / 2));
else
_constTimeDecayCoeff.zoom = 1.0;
#endif
if ((length(currDistanceToFocusNode) / distanceFromFocusSurface) > _zoomSensitivityDistanceThreshold) {
zoomFactor *= pow(std::abs(distanceFromFocusSurface), (float)_zoomSensitivity);
}
//Make zoom-out gestures faster near the focus node
if (zoomFactor < 0.0) {
double distanceThreshold = std::pow(10.0, (double)_speedLimitDistanceThresholdExp);
double zoomOutGain;
if (distanceFromFocusSurface < distanceThreshold) {
zoomOutGain = _zoomSpeedAsymmetryGain;
} else if (distanceFromFocusSurface < (distanceThreshold * 10)) {
double zoomOutGainBeyondUnity = _zoomSpeedAsymmetryGain - 1.0;
double ratioOfZoomOutGainToApplyBasedOnDistance = 1.0 - (distanceFromFocusSurface - distanceThreshold)
/ (distanceThreshold * 10 - distanceThreshold);
zoomOutGain = 1.0 + zoomOutGainBeyondUnity*ratioOfZoomOutGainToApplyBasedOnDistance;
} else {
zoomOutGain = 1.0;
_constTimeDecayCoeff.zoom = computeConstTimeDecayCoefficient(_vel.zoom);
if (distanceFromFocusSurface > 0.1) {
double ratioOfDistanceToNodeVsSurface = length(currDistanceToFocusNode)
/ distanceFromFocusSurface;
if (ratioOfDistanceToNodeVsSurface > _zoomSensitivityDistanceThreshold) {
zoomFactor *= pow(std::abs(distanceFromFocusSurface),
(float)_zoomSensitivityExponential);
}
zoomFactor *= zoomOutGain;
} else {
zoomFactor = 1.0;
}
_vel.zoom += zoomFactor * _sensitivity.zoom *
_vel.zoom = zoomFactor * _zoomSensitivityProportionalDist *
std::max(_touchScreenSize.value() * 0.1, 1.0);
break;
}
@@ -1132,27 +1099,15 @@ void TouchInteraction::computeVelocities(const std::vector<TuioCursor>& list,
) / list.size();
_vel.roll += -rollFactor * _sensitivity.roll;
#ifdef CONST_TIME_DECAY
if( stepsToDecay > 0.0 && std::abs(_vel.roll) > 0.0 )
_constTimeDecayCoeff.roll = std::pow((postDecayVelocityTarget / std::abs(_vel.roll)), (1.0 / stepsToDecay));
else
_constTimeDecayCoeff.roll = 1.0;
#endif
_constTimeDecayCoeff.roll = computeConstTimeDecayCoefficient(_vel.roll);
break;
}
case PAN: {
// add local rotation velocity
_vel.pan += glm::dvec2(cursor.getXSpeed() *
_sensitivity.pan.x, cursor.getYSpeed() * _sensitivity.pan.y);
#ifdef CONST_TIME_DECAY
/*double panVelocityAvg = (cursor.getXSpeed() * _sensitivity.pan.x
+ cursor.getYSpeed() * _sensitivity.pan.y) / 2.0;*/
double panVelocityAvg = glm::distance(_vel.pan.x, _vel.pan.y);
if( stepsToDecay > 0.0 && std::abs(panVelocityAvg) > 0.0 )
_constTimeDecayCoeff.pan = std::pow((postDecayVelocityTarget / std::abs(panVelocityAvg)), (1.0 / stepsToDecay));
else
_constTimeDecayCoeff.pan = 1.0;
#endif
_constTimeDecayCoeff.pan = computeConstTimeDecayCoefficient(panVelocityAvg);
break;
}
case PICK: {
@@ -1178,19 +1133,42 @@ void TouchInteraction::computeVelocities(const std::vector<TuioCursor>& list,
else {
// zooms in to current if PICK interpret happened but only space was
// selected
double dist = glm::distance(
_camera->positionVec3(), _camera->focusPositionVec3()
) - _focusNode->boundingSphere();
_vel.zoom = _sensitivity.zoom *
std::max(_touchScreenSize.value() * 0.1, 1.0) *
_tapZoomFactor * dist;
_vel.zoom = computeTapZoomDistance(0.3);
_constTimeDecayCoeff.zoom = computeConstTimeDecayCoefficient(_vel.zoom);
}
break;
}
#ifdef ZOOM_CORNER_TAP
case ZOOM_OUT: {
// zooms out from current if triple tap occurred
_vel.zoom = computeTapZoomDistance(-1.0);
_constTimeDecayCoeff.zoom = computeConstTimeDecayCoefficient(_vel.zoom);
}
#endif
}
}
double TouchInteraction::computeConstTimeDecayCoefficient(double velocity) {
const double postDecayVelocityTarget = 1e-6;
double stepsToDecay = _constTimeDecay_secs / _frameTimeAvg.getAvgFrameTime();
if (stepsToDecay > 0.0 && std::abs(velocity) > postDecayVelocityTarget)
return std::pow((postDecayVelocityTarget / std::abs(velocity)), (1.0 / stepsToDecay));
else
return 1.0;
}
double TouchInteraction::computeTapZoomDistance(double zoomGain) {
double dist = glm::distance(_camera->positionVec3(), _camera->focusPositionVec3());
dist -= _focusNode->boundingSphere();
double newVelocity = dist * _tapZoomFactor;
newVelocity *= std::max(_touchScreenSize.value() * 0.1, 1.0);
newVelocity *= _zoomSensitivityProportionalDist * zoomGain;
return newVelocity;
}
// Main update call, calculates the new orientation and position for the camera depending
// on _vel and dt. Called every frame
void TouchInteraction::step(double dt) {
@@ -1270,27 +1248,7 @@ void TouchInteraction::step(double dt) {
double planetBoundaryRadius = length(centerToBoundingSphere);
planetBoundaryRadius *= _zoomBoundarySphereMultiplier;
double distToSurface = length(centerToCamera - planetBoundaryRadius);
//Speed Limit on zoom velocity
#ifdef SPEED_BRAKE
double nearSpeedLimit = distToSurface / _speedLimitNearVelocityDivider;
double farSpeedLimit = _vel.zoom;
double distanceThreshold = std::pow(10.0, (double)_speedLimitDistanceThresholdExp);
double speedLimit;
if (distToSurface < distanceThreshold) {
double velocityFraction = distToSurface / distanceThreshold;
speedLimit = farSpeedLimit * velocityFraction + nearSpeedLimit * (1.0 - velocityFraction);
}
else {
speedLimit = farSpeedLimit;
}
#else
double speedLimit = _speedLimitDistanceFraction * distanceFromFocusSurface;
#endif
if (std::abs(_vel.zoom) > 1e-7)
_vel.zoom = (std::min(std::abs(speedLimit), std::abs(_vel.zoom))) * (_vel.zoom > 0.0 ? 1.0 : -1.0);
else
_vel.zoom = 0.0;
//Apply the velocity to update camera position
if (length(_vel.zoom*dt) < distToSurface &&
length(centerToCamera + directionToCenter*_vel.zoom*dt)
@@ -1321,6 +1279,9 @@ void TouchInteraction::step(double dt) {
_tap = false;
_doubleTap = false;
#ifdef ZOOM_CORNER_TAP
_zoomOutTap = false;
#endif
if (_reset) {
resetToDefault();
}
@@ -1372,9 +1333,7 @@ void TouchInteraction::unitTest() {
// Assume: frequency = 0.01, dt = 0.05 (200 fps), _timeSlack = 0.0001
// times = floor((0.05 + 0.0001) / 0.01) = 5
// _timeSlack = 0.0501 % 0.01 = 0.01
void TouchInteraction::decelerate(double dt) {
#ifdef CONST_TIME_DECAY
_frameTimeAvg.updateWithNewFrame(dt);
double expectedFrameTime = _frameTimeAvg.getAvgFrameTime();
@@ -1384,68 +1343,24 @@ void TouchInteraction::decelerate(double dt) {
// Save the new time slack for the next frame
_timeSlack = fmod((dt + _timeSlack), expectedFrameTime) * expectedFrameTime;
if (times > 0) {
if (_constTimeDecayCoeff.orbit > 0.0001)
_vel.orbit *= std::pow(_constTimeDecayCoeff.orbit, times);
else
_vel.orbit = { 0.0, 0.0 };
//Ensure the number of times to apply the decay coefficient is valid
times = std::min(times, 1);
if (_constTimeDecayCoeff.roll > 0.0001)
_vel.roll *= std::pow(_constTimeDecayCoeff.roll, times);
else
_vel.roll = 0.0;
if (_constTimeDecayCoeff.pan > 0.0001)
_vel.pan *= std::pow(_constTimeDecayCoeff.pan, times);
else
_vel.pan = { 0.0, 0.0 };
if( _constTimeDecayCoeff.zoom > 0.0001) {
// Decelerate zoom velocity quicker if we're close enough to use direct-manipulation
if (!_directTouchMode && _currentRadius > _nodeRadiusThreshold &&
_vel.zoom > _focusNode->boundingSphere())
{
_vel.zoom *= std::pow(2 * _constTimeDecayCoeff.zoom, times);
}
else {
_vel.zoom *= std::pow(_constTimeDecayCoeff.zoom, times);
}
}
else {
_vel.zoom = 0.0;
}
}
#else
double frequency = 1.0 / _deceleratesPerSecond;
// Number of times velocities should decelerate, depending on chosen frequency and
// time slack over from last frame
int times = static_cast<int>((dt + _timeSlack) / frequency);
// Save the new time slack for the next frame
_timeSlack = fmod((dt + _timeSlack), frequency) * frequency;
// Decelerate zoom velocity quicker if we're close enough to use direct-manipulation
if (!_directTouchMode && _currentRadius > _nodeRadiusThreshold &&
_vel.zoom > _focusNode->boundingSphere())
{
_vel.zoom *= std::pow(1 - 2 * _friction.value().y, times);
}
_vel.orbit *= std::pow(1 - _friction.value().x, times);
_vel.roll *= std::pow(1 - _friction.value().z, times);
_vel.pan *= std::pow(1 - _friction.value().w, times);
#endif //#ifdef CONST_TIME_DECAY
#ifndef CONST_TIME_DECAY
float frictionDecayValue = _friction.value().y;
#endif //#ifndef CONST_TIME_DECAY
_vel.orbit *= computeDecayCoeffFromFrametime(_constTimeDecayCoeff.orbit, times);
_vel.roll *= computeDecayCoeffFromFrametime(_constTimeDecayCoeff.roll, times);
_vel.pan *= computeDecayCoeffFromFrametime(_constTimeDecayCoeff.pan, times);
_vel.zoom *= computeDecayCoeffFromFrametime(_constTimeDecayCoeff.zoom, times);
glm::dvec3 camPos = _camera->positionVec3();
glm::dvec3 centerPos = _focusNode->worldPosition();
glm::dvec3 centerToCamera = camPos - centerPos;
}
#ifndef CONST_TIME_DECAY
_vel.zoom *= std::pow((1 - frictionDecayValue), times);
#endif //#ifndef CONST_TIME_DECAY
double TouchInteraction::computeDecayCoeffFromFrametime(double coeff, int times) {
if( coeff > 0.00001 )
return std::pow(coeff, times);
else
return 0.0;
}
// Called if all fingers are off the screen
@@ -1501,7 +1416,7 @@ void TouchInteraction::resetToDefault() {
_rollAngleThreshold.set(0.025f);
_orbitSpeedThreshold.set(0.005f);
_spinSensitivity.set(1.0f);
_zoomSensitivity.set(1.01f);
_zoomSensitivityExponential.set(1.025f);
_inputStillThreshold.set(0.0005f);
_centroidStillThreshold.set(0.0018f);
_interpretPan.set(0.015f);
@@ -1533,6 +1448,25 @@ void TouchInteraction::setFocusNode(SceneGraphNode* focusNode) {
_focusNode = focusNode;
}
void FrameTimeAverage::updateWithNewFrame(double sample) {
if (sample > 0.0005) {
_samples[index++] = sample;
if (index >= totalSamples)
index = 0;
if (_nSamples < totalSamples)
_nSamples++;
}
}
double FrameTimeAverage::getAvgFrameTime() {
double ft;
if (_nSamples == 0)
ft = 1.0 / 60.0; //Just guess at 60fps if no data is available yet
else
ft = std::accumulate(_samples, _samples + _nSamples, 0.0) / (double)(_nSamples);
return ft;
}
#ifdef TOUCH_DEBUG_PROPERTIES
TouchInteraction::DebugProperties::DebugProperties()
: properties::PropertyOwner({ "TouchDebugProperties" })