Feature/touch fixes (#2463)

* Add Ceres to touch interaction list (Forgotten in previous commit. OBS! This list will be removed)

* Small code updates (Logical ordering of functions, code standard)

* Fix compilation issue when using debug define

* Make touch navigation abort idle behavior

* Make reset a trigger property

* Fix some broken property sliders (the default step size was too big)

* Update interaction monitor state on touch interaction with WebGui

* Add some documentation of what "LM" means, and make unit test a developer property
This commit is contained in:
Emma Broman
2023-02-01 12:44:34 +01:00
committed by GitHub
parent 6694c3e7ee
commit a0f9e88432
5 changed files with 186 additions and 161 deletions

View File

@@ -37,133 +37,13 @@ using namespace TUIO;
namespace {
constexpr openspace::properties::Property::PropertyInfo TouchActiveInfo = {
"TouchActive",
"True if we want to use touch input as 3d navigation",
"True if we want to use touch input as 3D navigation",
"Use this if we want to turn on or off Touch input navigation. "
"Disabling this will reset all current touch inputs to the navigation."
};
}
namespace openspace {
bool TouchModule::processNewInput() {
// Get new input from listener
std::vector<TouchInput> earInputs = _ear->takeInput();
std::vector<TouchInput> earRemovals = _ear->takeRemovals();
for(const TouchInput& input : earInputs) {
updateOrAddTouchInput(input);
}
for(const TouchInput& removal : earRemovals) {
removeTouchInput(removal);
}
// Set touch property to active (to void mouse input, mainly for mtdev bridges)
_touch.touchActive(!_touchPoints.empty());
if (!_touchPoints.empty()) {
global::interactionMonitor->markInteraction();
}
// Erase old input id's that no longer exists
_lastTouchInputs.erase(
std::remove_if(
_lastTouchInputs.begin(),
_lastTouchInputs.end(),
[this](const TouchInput& input) {
return !std::any_of(
_touchPoints.cbegin(),
_touchPoints.cend(),
[&input](const TouchInputHolder& holder) {
return holder.holdsInput(input);
}
);
}
),
_lastTouchInputs.end()
);
if (_tap) {
_touch.tap();
_tap = false;
return true;
}
// Return true if we got new input
if (_touchPoints.size() == _lastTouchInputs.size() &&
!_touchPoints.empty())
{
bool newInput = true;
// go through list and check if the last registrered time is newer than the one in
// lastProcessed (last frame)
std::for_each(
_lastTouchInputs.begin(),
_lastTouchInputs.end(),
[this, &newInput](TouchInput& input) {
std::vector<TouchInputHolder>::iterator holder = std::find_if(
_touchPoints.begin(),
_touchPoints.end(),
[&input](const TouchInputHolder& inputHolder) {
return inputHolder.holdsInput(input);
}
);
if (!holder->isMoving()) {
newInput = true;
}
});
return newInput;
}
else {
return false;
}
}
void TouchModule::clearInputs() {
for (const TouchInput& input : _deferredRemovals) {
for (TouchInputHolder& inputHolder : _touchPoints) {
if (inputHolder.holdsInput(input)) {
inputHolder = std::move(_touchPoints.back());
_touchPoints.pop_back();
break;
}
}
}
_deferredRemovals.clear();
}
void TouchModule::addTouchInput(TouchInput input) {
_touchPoints.emplace_back(input);
}
void TouchModule::updateOrAddTouchInput(TouchInput input) {
for (TouchInputHolder& inputHolder : _touchPoints) {
if (inputHolder.holdsInput(input)){
inputHolder.tryAddInput(input);
return;
}
}
_touchPoints.emplace_back(input);
}
void TouchModule::removeTouchInput(TouchInput input) {
_deferredRemovals.emplace_back(input);
//Check for "tap" gesture:
for (TouchInputHolder& inputHolder : _touchPoints) {
if (inputHolder.holdsInput(input)) {
inputHolder.tryAddInput(input);
const double totalTime = inputHolder.gestureTime();
const float totalDistance = inputHolder.gestureDistance();
//Magic values taken from tuioear.cpp:
const bool isWithinTapTime = totalTime < 0.18;
const bool wasStationary = totalDistance < 0.0004f;
if (isWithinTapTime && wasStationary && _touchPoints.size() == 1 &&
_deferredRemovals.size() == 1)
{
_tap = true;
}
return;
}
}
}
TouchModule::TouchModule()
: OpenSpaceModule("Touch")
, _touchActive(TouchActiveInfo, true)
@@ -253,4 +133,124 @@ void TouchModule::internalInitialize(const ghoul::Dictionary& /*dictionary*/){
});
}
bool TouchModule::processNewInput() {
// Get new input from listener
std::vector<TouchInput> earInputs = _ear->takeInput();
std::vector<TouchInput> earRemovals = _ear->takeRemovals();
for (const TouchInput& input : earInputs) {
updateOrAddTouchInput(input);
}
for (const TouchInput& removal : earRemovals) {
removeTouchInput(removal);
}
// Set touch property to active (to void mouse input, mainly for mtdev bridges)
_touch.touchActive(!_touchPoints.empty());
if (!_touchPoints.empty()) {
global::interactionMonitor->markInteraction();
}
// Erase old input id's that no longer exists
_lastTouchInputs.erase(
std::remove_if(
_lastTouchInputs.begin(),
_lastTouchInputs.end(),
[this](const TouchInput& input) {
return !std::any_of(
_touchPoints.cbegin(),
_touchPoints.cend(),
[&input](const TouchInputHolder& holder) {
return holder.holdsInput(input);
}
);
}
),
_lastTouchInputs.end()
);
if (_tap) {
_touch.tap();
_tap = false;
return true;
}
// Return true if we got new input
if (_touchPoints.size() == _lastTouchInputs.size() &&
!_touchPoints.empty())
{
bool newInput = true;
// go through list and check if the last registrered time is newer than the one in
// lastProcessed (last frame)
std::for_each(
_lastTouchInputs.begin(),
_lastTouchInputs.end(),
[this, &newInput](TouchInput& input) {
std::vector<TouchInputHolder>::iterator holder = std::find_if(
_touchPoints.begin(),
_touchPoints.end(),
[&input](const TouchInputHolder& inputHolder) {
return inputHolder.holdsInput(input);
}
);
if (!holder->isMoving()) {
newInput = true;
}
});
return newInput;
}
else {
return false;
}
}
void TouchModule::clearInputs() {
for (const TouchInput& input : _deferredRemovals) {
for (TouchInputHolder& inputHolder : _touchPoints) {
if (inputHolder.holdsInput(input)) {
inputHolder = std::move(_touchPoints.back());
_touchPoints.pop_back();
break;
}
}
}
_deferredRemovals.clear();
}
void TouchModule::addTouchInput(TouchInput input) {
_touchPoints.emplace_back(input);
}
void TouchModule::updateOrAddTouchInput(TouchInput input) {
for (TouchInputHolder& inputHolder : _touchPoints) {
if (inputHolder.holdsInput(input)) {
inputHolder.tryAddInput(input);
return;
}
}
_touchPoints.emplace_back(input);
}
void TouchModule::removeTouchInput(TouchInput input) {
_deferredRemovals.emplace_back(input);
// Check for "tap" gesture:
for (TouchInputHolder& inputHolder : _touchPoints) {
if (inputHolder.holdsInput(input)) {
inputHolder.tryAddInput(input);
const double totalTime = inputHolder.gestureTime();
const float totalDistance = inputHolder.gestureDistance();
// Magic values taken from tuioear.cpp:
const bool isWithinTapTime = totalTime < 0.18;
const bool wasStationary = totalDistance < 0.0004f;
if (isWithinTapTime && wasStationary && _touchPoints.size() == 1 &&
_deferredRemovals.size() == 1)
{
_tap = true;
}
return;
}
}
}
} // namespace openspace