mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 03:00:58 -06:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user