mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-23 04:30:09 -05:00
Merge pull request #1115 from OpenSpace/feature/continuous-pinch
Feature/continuous pinch
This commit is contained in:
@@ -32,6 +32,9 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
// The TouchInput represents a single finger/device-input at a specific point in time.
|
||||
// the fingerId and touchDeviceId coupled with the timestamp allows this to be compared
|
||||
// with other TouchInputs in order to calculate gesture-like behaviour.
|
||||
struct TouchInput {
|
||||
TouchInput(size_t touchDeviceId, size_t fingerId, float x, float y, double timestamp);
|
||||
glm::vec2 screenCoordinates(glm::vec2 resolution) const;
|
||||
@@ -46,19 +49,25 @@ struct TouchInput {
|
||||
float y;
|
||||
float dx = 0.f; // movement in x direction since last touch input
|
||||
float dy = 0.f; // movement in y direction since last touch input
|
||||
double timestamp; // timestamp in seconds from global touch initialization
|
||||
double timestamp; // timestamp in seconds from global touch initialization
|
||||
};
|
||||
|
||||
// The TouchInputHolder holds one or many TouchInputs, in order to track the history of
|
||||
// the finger/input device
|
||||
class TouchInputHolder {
|
||||
public:
|
||||
TouchInputHolder(TouchInput input);
|
||||
|
||||
// tryAddInput:
|
||||
// Succeeds upon a different input than last.
|
||||
// Fails upon a too similar input as last.
|
||||
// Updates time for the last input if same position.
|
||||
bool tryAddInput(TouchInput input);
|
||||
|
||||
void clearInputs();
|
||||
|
||||
// Checks whether or not this Holder actually holds a specific input (based on IDs)
|
||||
// Succeeds when `input` is held by this Holder
|
||||
// Fails if `input` is not held by this Holder
|
||||
bool holdsInput(const TouchInput &input) const;
|
||||
|
||||
size_t touchDeviceId() const;
|
||||
@@ -72,12 +81,14 @@ public:
|
||||
double gestureTime() const;
|
||||
|
||||
size_t numInputs() const;
|
||||
const TouchInput& firstInput() const;
|
||||
const TouchInput& latestInput() const;
|
||||
const std::deque<TouchInput>& peekInputs() const;
|
||||
|
||||
private:
|
||||
//A deque of recorded inputs. Adding newer points to the front of the queue
|
||||
std::deque<TouchInput> _inputs;
|
||||
TouchInput _firstInput;
|
||||
|
||||
size_t _touchDeviceId;
|
||||
size_t _fingerId;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/vector/ivec2property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
@@ -96,7 +97,7 @@ public:
|
||||
std::vector<TouchInput>& lastProcessed);
|
||||
|
||||
// Calculates the new camera state with velocities and time since last frame
|
||||
void step(double dt);
|
||||
void step(double dt, bool directTouch = false);
|
||||
|
||||
// Called each frame we have no new input, used to reset data
|
||||
void resetAfterInput();
|
||||
@@ -166,6 +167,7 @@ private:
|
||||
properties::IntProperty _deceleratesPerSecond;
|
||||
properties::FloatProperty _touchScreenSize;
|
||||
properties::FloatProperty _tapZoomFactor;
|
||||
properties::FloatProperty _pinchZoomFactor;
|
||||
properties::FloatProperty _nodeRadiusThreshold;
|
||||
properties::FloatProperty _rollAngleThreshold;
|
||||
properties::FloatProperty _orbitSpeedThreshold;
|
||||
@@ -202,7 +204,7 @@ private:
|
||||
double pinchConsecZoomFactor = 0;
|
||||
//int stepVelUpdate = 0;
|
||||
#endif
|
||||
|
||||
std::array<TouchInputHolder, 2> _pinchInputs;
|
||||
// Class variables
|
||||
VelocityStates _vel;
|
||||
VelocityStates _lastVel;
|
||||
@@ -242,4 +244,3 @@ private:
|
||||
} // openspace namespace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_TOUCH___TOUCH_INTERACTION___H__
|
||||
|
||||
|
||||
@@ -117,6 +117,13 @@ namespace {
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PinchZoomFactorInfo = {
|
||||
"PinchZoomFactor",
|
||||
"Scaling distance travelled on pinch",
|
||||
"This value is used to reduce the amount of pinching needed. A linear kind of "
|
||||
"sensitivity that will alter the pinch-zoom speed."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DirectManipulationInfo = {
|
||||
"DirectManipulationRadius",
|
||||
"Radius a planet has to have to activate direct-manipulation",
|
||||
@@ -264,6 +271,7 @@ TouchInteraction::TouchInteraction()
|
||||
, _deceleratesPerSecond(DecelatesPerSecondInfo, 240, 60, 300)
|
||||
, _touchScreenSize(TouchScreenSizeInfo, 55.0f, 5.5f, 150.0f)
|
||||
, _tapZoomFactor(TapZoomFactorInfo, 0.2f, 0.f, 0.5f)
|
||||
, _pinchZoomFactor(PinchZoomFactorInfo, 0.01f, 0.f, 0.2f)
|
||||
, _nodeRadiusThreshold(DirectManipulationInfo, 0.2f, 0.0f, 1.0f)
|
||||
, _rollAngleThreshold(RollThresholdInfo, 0.025f, 0.f, 0.05f)
|
||||
, _orbitSpeedThreshold(OrbitSpinningThreshold, 0.005f, 0.f, 0.01f)
|
||||
@@ -277,7 +285,12 @@ TouchInteraction::TouchInteraction()
|
||||
0.25f
|
||||
)
|
||||
, _zoomBoundarySphereMultiplier(ZoomBoundarySphereMultiplierInfo, 1.001f, 1.f, 1.01f)
|
||||
, _zoomOutLimit(ZoomOutLimitInfo, std::numeric_limits<double>::max(), 1000.0, std::numeric_limits<double>::max())
|
||||
, _zoomOutLimit(
|
||||
ZoomOutLimitInfo,
|
||||
std::numeric_limits<double>::max(),
|
||||
1000.0,
|
||||
std::numeric_limits<double>::max()
|
||||
)
|
||||
, _zoomInLimit(ZoomInLimitInfo, -1.0, 0.0, std::numeric_limits<double>::max())
|
||||
, _inputStillThreshold(InputSensitivityInfo, 0.0005f, 0.f, 0.001f)
|
||||
// used to void wrongly interpreted roll interactions
|
||||
@@ -307,8 +320,9 @@ TouchInteraction::TouchInteraction()
|
||||
{ "Ignore GUI", "Disable GUI touch interaction", "" },
|
||||
false
|
||||
)
|
||||
, _pinchInputs({ TouchInput(0, 0, 0.0, 0.0, 0.0), TouchInput(0, 0, 0.0, 0.0, 0.0) })
|
||||
, _vel{ glm::dvec2(0.0), 0.0, 0.0, glm::dvec2(0.0) }
|
||||
, _sensitivity{ glm::dvec2(0.08, 0.045), 12.0 /*4.0*/, 2.75, glm::dvec2(0.08, 0.045) }
|
||||
, _sensitivity{ glm::dvec2(0.08, 0.045), 12.0, 2.75, glm::dvec2(0.08, 0.045) }
|
||||
, _constTimeDecay_secs(ConstantTimeDecaySecsInfo, 1.75f, 0.1f, 4.0f)
|
||||
// calculated with two vectors with known diff in length, then
|
||||
// projDiffLength/diffLength.
|
||||
@@ -320,6 +334,7 @@ TouchInteraction::TouchInteraction()
|
||||
addProperty(_deceleratesPerSecond);
|
||||
addProperty(_touchScreenSize);
|
||||
addProperty(_tapZoomFactor);
|
||||
addProperty(_pinchZoomFactor);
|
||||
addProperty(_nodeRadiusThreshold);
|
||||
addProperty(_rollAngleThreshold);
|
||||
addProperty(_orbitSpeedThreshold);
|
||||
@@ -494,7 +509,7 @@ void TouchInteraction::directControl(const std::vector<TouchInputHolder>& list)
|
||||
_vel.pan = glm::dvec2(par.at(4), par.at(5));
|
||||
}
|
||||
}
|
||||
step(1.0);
|
||||
step(1.0, true);
|
||||
|
||||
// Reset velocities after setting new camera state
|
||||
_lastVel = _vel;
|
||||
@@ -777,6 +792,15 @@ int TouchInteraction::interpretInteraction(const std::vector<TouchInputHolder>&
|
||||
return ROLL;
|
||||
}
|
||||
else {
|
||||
const bool sameInput0 = _pinchInputs[0].holdsInput(list[0].latestInput());
|
||||
const bool sameInput1 = _pinchInputs[1].holdsInput(list[1].latestInput());
|
||||
if (sameInput0 && sameInput1) {
|
||||
_pinchInputs[0].tryAddInput(list[0].latestInput());
|
||||
_pinchInputs[1].tryAddInput(list[1].latestInput());
|
||||
} else {
|
||||
_pinchInputs[0] = TouchInputHolder(list[0].latestInput());
|
||||
_pinchInputs[1] = TouchInputHolder(list[1].latestInput());
|
||||
}
|
||||
return PINCH;
|
||||
}
|
||||
}
|
||||
@@ -816,6 +840,9 @@ void TouchInteraction::computeVelocities(const std::vector<TouchInputHolder>& li
|
||||
#endif
|
||||
|
||||
const TouchInputHolder& inputHolder = list.at(0);
|
||||
const glm::ivec2 windowSize = global::windowDelegate.currentWindowSize();
|
||||
const float aspectRatio =
|
||||
static_cast<float>(windowSize.x) / static_cast<float>(windowSize.y);
|
||||
switch (action) {
|
||||
case ROT: { // add rotation velocity
|
||||
_vel.orbit += glm::dvec2(inputHolder.speedX() *
|
||||
@@ -829,54 +856,31 @@ void TouchInteraction::computeVelocities(const std::vector<TouchInputHolder>& li
|
||||
}
|
||||
case PINCH: {
|
||||
// add zooming velocity - dependant on distance difference between contact
|
||||
// points this/last frame
|
||||
double distance = std::accumulate(
|
||||
list.begin(),
|
||||
list.end(),
|
||||
0.0,
|
||||
[&](double d, const TouchInputHolder& c) {
|
||||
const glm::vec2 currPos = { c.latestInput().x, c.latestInput().y };
|
||||
return d + glm::distance(currPos, _centroid);
|
||||
}
|
||||
) / list.size();
|
||||
double lastDistance = std::accumulate(
|
||||
lastProcessed.begin(),
|
||||
lastProcessed.end(),
|
||||
0.f,
|
||||
[&](float d, const TouchInput& p) {
|
||||
const glm::vec2 lastPos = { p.x, p.y };
|
||||
return d + glm::distance(lastPos, _centroid);
|
||||
}
|
||||
) / lastProcessed.size();
|
||||
// points this/first frame
|
||||
using namespace glm;
|
||||
const TouchInput& startFinger0 = _pinchInputs[0].firstInput();
|
||||
const TouchInput& startFinger1 = _pinchInputs[1].firstInput();
|
||||
const dvec2 startVec0 = dvec2(startFinger0.x * aspectRatio, startFinger0.y);
|
||||
const dvec2 startVec1 = dvec2(startFinger1.x * aspectRatio, startFinger1.y);
|
||||
double distToCentroidStart = length(startVec0 - startVec1) / 2.0;
|
||||
|
||||
glm::dvec3 camPos = _camera->positionVec3();
|
||||
glm::dvec3 centerPos = anchor->worldPosition();
|
||||
glm::dvec3 currDistanceToFocusNode = camPos - centerPos;
|
||||
const TouchInput& endFinger0 = _pinchInputs[0].latestInput();
|
||||
const TouchInput& endFinger1 = _pinchInputs[1].latestInput();
|
||||
const dvec2 endVec0 = dvec2(endFinger0.x * aspectRatio, endFinger0.y);
|
||||
const dvec2 endVec1 = dvec2(endFinger1.x * aspectRatio, endFinger1.y);
|
||||
double distToCentroidEnd = length(endVec0 - endVec1) / 2.0;
|
||||
|
||||
const double distanceFromFocusSurface =
|
||||
length(currDistanceToFocusNode) - anchor->boundingSphere();
|
||||
double zoomFactor = (distance - lastDistance);
|
||||
double zoomFactor = distToCentroidEnd - distToCentroidStart;
|
||||
#ifdef TOUCH_DEBUG_PROPERTIES
|
||||
pinchConsecCt++;
|
||||
pinchConsecZoomFactor += zoomFactor;
|
||||
#endif
|
||||
|
||||
_constTimeDecayCoeff.zoom = computeConstTimeDecayCoefficient(_vel.zoom);
|
||||
if (distanceFromFocusSurface > 0.1) {
|
||||
const double ratioOfDistanceToNodeVsSurface =
|
||||
length(currDistanceToFocusNode) / distanceFromFocusSurface;
|
||||
if (ratioOfDistanceToNodeVsSurface > _zoomSensitivityDistanceThreshold) {
|
||||
zoomFactor *= pow(
|
||||
std::abs(distanceFromFocusSurface),
|
||||
static_cast<float>(_zoomSensitivityExponential)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
zoomFactor = 1.0;
|
||||
}
|
||||
_vel.zoom = zoomFactor * _zoomSensitivityProportionalDist *
|
||||
std::max(_touchScreenSize.value() * 0.1, 1.0);
|
||||
_constTimeDecayCoeff.zoom = 1.0;
|
||||
_vel.zoom = zoomFactor *
|
||||
_pinchZoomFactor *
|
||||
_zoomSensitivityProportionalDist *
|
||||
std::max(_touchScreenSize.value() * 0.1, 1.0);
|
||||
break;
|
||||
}
|
||||
case ROLL: {
|
||||
@@ -917,7 +921,7 @@ void TouchInteraction::computeVelocities(const std::vector<TouchInputHolder>& li
|
||||
break;
|
||||
}
|
||||
case PAN: {
|
||||
// add local rotation velocity
|
||||
// add local rotation velocity
|
||||
_vel.pan += glm::dvec2(inputHolder.speedX() *
|
||||
_sensitivity.pan.x, inputHolder.speedY() * _sensitivity.pan.y);
|
||||
double panVelocityAvg = glm::distance(_vel.pan.x, _vel.pan.y);
|
||||
@@ -925,7 +929,7 @@ void TouchInteraction::computeVelocities(const std::vector<TouchInputHolder>& li
|
||||
break;
|
||||
}
|
||||
case PICK: {
|
||||
// pick something in the scene as focus node
|
||||
// pick something in the scene as focus node
|
||||
if (_pickingSelected) {
|
||||
setFocusNode(_pickingSelected);
|
||||
|
||||
@@ -992,7 +996,7 @@ double TouchInteraction::computeTapZoomDistance(double zoomGain) {
|
||||
|
||||
// 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) {
|
||||
void TouchInteraction::step(double dt, bool directTouch) {
|
||||
using namespace glm;
|
||||
|
||||
const SceneGraphNode* anchor =
|
||||
@@ -1103,22 +1107,45 @@ void TouchInteraction::step(double dt) {
|
||||
_loggerCat, _zoomOutLimit.value()
|
||||
));
|
||||
}
|
||||
const double currentPosDistance = length(centerToCamera);
|
||||
|
||||
//Apply the velocity to update camera position
|
||||
glm::dvec3 zoomDistanceIncrement = directionToCenter * _vel.zoom * dt;
|
||||
double zoomVelocity = _vel.zoom;
|
||||
if (!directTouch) {
|
||||
const double distanceFromSurface =
|
||||
length(currentPosDistance) - anchor->boundingSphere();
|
||||
if (distanceFromSurface > 0.1) {
|
||||
const double ratioOfDistanceToNodeVsSurface =
|
||||
length(currentPosDistance) / distanceFromSurface;
|
||||
if (ratioOfDistanceToNodeVsSurface > _zoomSensitivityDistanceThreshold) {
|
||||
zoomVelocity *= pow(
|
||||
std::abs(distanceFromSurface),
|
||||
static_cast<float>(_zoomSensitivityExponential)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
zoomVelocity = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
const glm::dvec3 zoomDistanceIncrement = directionToCenter * zoomVelocity * dt;
|
||||
const double newPosDistance = length(centerToCamera + zoomDistanceIncrement);
|
||||
const double currentPosDistance = length(centerToCamera);
|
||||
|
||||
// Possible with other navigations performed outside touch interaction
|
||||
const bool currentPosViolatingZoomOutLimit =
|
||||
(currentPosDistance >= _zoomOutLimit.value());
|
||||
(currentPosDistance >= _zoomOutLimit);
|
||||
const bool willNewPositionViolateZoomOutLimit =
|
||||
(newPosDistance >= _zoomOutLimit.value());
|
||||
(newPosDistance >= _zoomOutLimit);
|
||||
bool willNewPositionViolateZoomInLimit =
|
||||
(newPosDistance < zoomInBounds);
|
||||
bool willNewPositionViolateDirection =
|
||||
(currentPosDistance <= length(zoomDistanceIncrement));
|
||||
|
||||
if (!willNewPositionViolateZoomInLimit
|
||||
&& !willNewPositionViolateZoomOutLimit) {
|
||||
if (!willNewPositionViolateZoomInLimit &&
|
||||
!willNewPositionViolateDirection &&
|
||||
!willNewPositionViolateZoomOutLimit)
|
||||
{
|
||||
camPos += zoomDistanceIncrement;
|
||||
}
|
||||
else if (currentPosViolatingZoomOutLimit) {
|
||||
@@ -1218,7 +1245,6 @@ void TouchInteraction::resetAfterInput() {
|
||||
module.touchInput.active = false;
|
||||
module.touchInput.action = 0;
|
||||
}
|
||||
|
||||
_lmSuccess = true;
|
||||
// Ensure that _guiON is consistent with properties in OnScreenGUI and
|
||||
_guiON = module.gui.isEnabled();
|
||||
@@ -1228,6 +1254,11 @@ void TouchInteraction::resetAfterInput() {
|
||||
_lastVel.zoom = 0.0;
|
||||
_lastVel.roll = 0.0;
|
||||
_lastVel.pan = glm::dvec2(0.0);
|
||||
|
||||
_constTimeDecayCoeff.zoom = computeConstTimeDecayCoefficient(_vel.zoom);
|
||||
_pinchInputs[0].clearInputs();
|
||||
_pinchInputs[1].clearInputs();
|
||||
|
||||
_selected.clear();
|
||||
_pickingSelected = nullptr;
|
||||
}
|
||||
@@ -1240,6 +1271,7 @@ void TouchInteraction::resetToDefault() {
|
||||
_deceleratesPerSecond.set(240);
|
||||
_touchScreenSize.set(55.0f);
|
||||
_tapZoomFactor.set(0.2f);
|
||||
_pinchZoomFactor.set(0.01f);
|
||||
_nodeRadiusThreshold.set(0.2f);
|
||||
_rollAngleThreshold.set(0.025f);
|
||||
_orbitSpeedThreshold.set(0.005f);
|
||||
|
||||
@@ -40,12 +40,18 @@
|
||||
#define ENABLE_DIRECTMSG
|
||||
|
||||
namespace {
|
||||
using namespace std::chrono;
|
||||
constexpr const char* _loggerCat = "win32_touch";
|
||||
HHOOK gTouchHook = nullptr;
|
||||
std::thread* gMouseHookThread;
|
||||
HHOOK gMouseHook = nullptr;
|
||||
bool gStarted = false;
|
||||
std::chrono::microseconds gStartTime = std::chrono::microseconds(0);
|
||||
microseconds gStartTime = microseconds(0);
|
||||
const long long gFrequency = []() -> long long {
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
return frequency.QuadPart;
|
||||
}();
|
||||
std::unordered_map<
|
||||
UINT32,
|
||||
std::unique_ptr<openspace::TouchInputHolder>
|
||||
@@ -79,10 +85,14 @@ LRESULT CALLBACK HookCallback(int nCode, WPARAM wParam, LPARAM lParam) {
|
||||
break;
|
||||
}
|
||||
|
||||
using namespace std::chrono;
|
||||
const microseconds timestamp = duration_cast<microseconds>(
|
||||
high_resolution_clock::now().time_since_epoch()
|
||||
) - gStartTime;
|
||||
//Implementation from microsoft STL of high_resolution_clock(steady_clock):
|
||||
const long long freq = gFrequency;
|
||||
const long long whole = (info.PerformanceCount / freq) * std::micro::den;
|
||||
const long long part = (info.PerformanceCount % freq) *
|
||||
std::micro::den / freq;
|
||||
const microseconds timestamp =
|
||||
duration<UINT64, std::micro>(whole + part) - gStartTime;
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(pStruct->hwnd, reinterpret_cast<LPRECT>(&rect));
|
||||
|
||||
@@ -100,7 +110,7 @@ LRESULT CALLBACK HookCallback(int nCode, WPARAM wParam, LPARAM lParam) {
|
||||
static_cast<size_t>(info.pointerId),
|
||||
xPos,
|
||||
yPos,
|
||||
static_cast<double>(timestamp.count())/1'000'000.0
|
||||
static_cast<double>(timestamp.count()) / 1'000'000.0
|
||||
);
|
||||
|
||||
if (info.pointerFlags & POINTER_FLAG_DOWN) {
|
||||
@@ -213,9 +223,8 @@ Win32TouchHook::Win32TouchHook(void* nativeWindow)
|
||||
|
||||
if (!gStarted) {
|
||||
gStarted = true;
|
||||
gStartTime = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
std::chrono::high_resolution_clock::now().time_since_epoch()
|
||||
);
|
||||
gStartTime =
|
||||
duration_cast<microseconds>(high_resolution_clock::now().time_since_epoch());
|
||||
#ifdef ENABLE_TUIOMESSAGES
|
||||
gTuioServer = new TUIO::TuioServer("localhost", 3333);
|
||||
TUIO::TuioTime::initSession();
|
||||
|
||||
@@ -221,7 +221,7 @@ void TouchModule::internalInitialize(const ghoul::Dictionary& /*dictionary*/){
|
||||
global::callback::touchUpdated.push_back(
|
||||
[this](TouchInput i) {
|
||||
updateOrAddTouchInput(i);
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+21
-9
@@ -73,32 +73,41 @@ float TouchInput::angleToPos(float otherX, float otherY) const {
|
||||
|
||||
TouchInputHolder::TouchInputHolder(TouchInput input)
|
||||
: _inputs{ input }
|
||||
, _firstInput(input)
|
||||
, _touchDeviceId(input.touchDeviceId)
|
||||
, _fingerId(input.fingerId)
|
||||
{}
|
||||
|
||||
bool TouchInputHolder::tryAddInput(TouchInput input) {
|
||||
if(_inputs.empty()) {
|
||||
_inputs.emplace_front(input);
|
||||
return true;
|
||||
}
|
||||
constexpr const double ONE_MS = 0.001;
|
||||
const TouchInput& lastInput = latestInput();
|
||||
input.dx = input.x - lastInput.x;
|
||||
input.dy = input.y - lastInput.y;
|
||||
|
||||
const bool sameTimeAsLastInput = (input.timestamp - lastInput.timestamp) > ONE_MS;
|
||||
bool wasInserted = false;
|
||||
if (isMoving()) {
|
||||
const bool sameTimeAsLastInput = (input.timestamp - lastInput.timestamp) < ONE_MS;
|
||||
bool successful = false;
|
||||
if (!sameTimeAsLastInput && isMoving()) {
|
||||
_inputs.emplace_front(input);
|
||||
wasInserted = true;
|
||||
successful = true;
|
||||
}
|
||||
else if (sameTimeAsLastInput && input.isMoving()) {
|
||||
else if (!sameTimeAsLastInput && input.isMoving()) {
|
||||
_inputs.emplace_front(input);
|
||||
wasInserted = true;
|
||||
successful = true;
|
||||
}
|
||||
else if (!sameTimeAsLastInput){
|
||||
_inputs.front().timestamp = input.timestamp;
|
||||
successful = true;
|
||||
}
|
||||
|
||||
constexpr const int MaxInputs = 128;
|
||||
if (_inputs.size() > MaxInputs) {
|
||||
_inputs.pop_back();
|
||||
}
|
||||
return wasInserted;
|
||||
return successful;
|
||||
}
|
||||
|
||||
void TouchInputHolder::clearInputs() {
|
||||
@@ -142,8 +151,7 @@ bool TouchInputHolder::isMoving() const {
|
||||
if (_inputs.size() <= 1) {
|
||||
return false;
|
||||
}
|
||||
const TouchInput& currentInput = _inputs[0];
|
||||
return currentInput.dx != 0.f || currentInput.dy != 0.f;
|
||||
return latestInput().isMoving();
|
||||
}
|
||||
|
||||
float TouchInputHolder::gestureDistance() const {
|
||||
@@ -174,6 +182,10 @@ size_t TouchInputHolder::numInputs() const {
|
||||
return _inputs.size();
|
||||
}
|
||||
|
||||
const TouchInput& TouchInputHolder::firstInput() const {
|
||||
return _firstInput;
|
||||
}
|
||||
|
||||
const TouchInput& TouchInputHolder::latestInput() const {
|
||||
return _inputs.front();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user