Add Touch input handling
This commit is contained in:
212
openVulkanoCpp/Input/Touch/InputDeviceTouch.cpp
Normal file
212
openVulkanoCpp/Input/Touch/InputDeviceTouch.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "InputDeviceTouch.hpp"
|
||||
#include "Base/Logger.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace OpenVulkano::Input
|
||||
{
|
||||
void InputDeviceTouch::Init()
|
||||
{
|
||||
InputDevice::Init(InputDeviceType::TOUCH, 0, "Touch");
|
||||
|
||||
m_gestureProcessor.Init();
|
||||
m_gestureProcessor.m_gestureTap.OnTap += EventHandler(this, &InputDeviceTouch::UpdateTap);
|
||||
m_gestureProcessor.m_gesturePan.OnPanStarted += EventHandler(this, &InputDeviceTouch::UpdatePanStarted);
|
||||
m_gestureProcessor.m_gesturePan.OnPanMoved += EventHandler(this, &InputDeviceTouch::UpdatePanMoved);
|
||||
m_gestureProcessor.m_gesturePanTwoFingers.OnPanStarted += EventHandler(this, &InputDeviceTouch::UpdatePanTwoFingersStarted);
|
||||
m_gestureProcessor.m_gesturePanTwoFingers.OnPanMoved += EventHandler(this, &InputDeviceTouch::UpdatePanTwoFingersMoved);
|
||||
m_gestureProcessor.m_gesturePinch.OnPinchStarted += EventHandler(this, &InputDeviceTouch::UpdatePinchStarted);
|
||||
m_gestureProcessor.m_gesturePinch.OnPinchMoved += EventHandler(this, &InputDeviceTouch::UpdatePinchMoved);
|
||||
}
|
||||
|
||||
decltype(InputDeviceTouch::m_touches)::iterator InputDeviceTouch::FindTouch(TouchId id)
|
||||
{
|
||||
return std::find_if(m_touches.begin(), m_touches.end(), [id](const Touch& touch)
|
||||
{
|
||||
return (id == touch.GetId());
|
||||
});
|
||||
}
|
||||
|
||||
TouchId InputDeviceTouch::AddTouch(const Math::Vector2f& position)
|
||||
{
|
||||
m_touches.emplace_back(m_nextId, position);
|
||||
OnTouchAdded(m_touches.back());
|
||||
return m_nextId++;
|
||||
}
|
||||
|
||||
void InputDeviceTouch::TouchDown(TouchId id)
|
||||
{
|
||||
auto touchIter = FindTouch(id);
|
||||
|
||||
if (touchIter != m_touches.end())
|
||||
{
|
||||
touchIter->m_down = true;
|
||||
if (!m_multiTouch && m_touches.size() > 1)
|
||||
{
|
||||
int count = 0;
|
||||
for (const auto &touch : m_touches)
|
||||
{
|
||||
if(touch.IsDown()) count++;
|
||||
if (count > 1)
|
||||
{
|
||||
Logger::INPUT->debug("Begin multitouch");
|
||||
m_multiTouch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OnTouchDown.NotifyAll(*touchIter);
|
||||
m_gestureProcessor.TouchDown(*touchIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::INPUT->warn("Received touch down event for unknown touch id.");
|
||||
}
|
||||
}
|
||||
|
||||
void InputDeviceTouch::TouchUp(TouchId id)
|
||||
{
|
||||
auto touchIter = FindTouch(id);
|
||||
|
||||
if (touchIter != m_touches.end())
|
||||
{
|
||||
touchIter->m_down = false;
|
||||
|
||||
if (m_multiTouch)
|
||||
{
|
||||
bool hasDown = false;
|
||||
for (const auto &touch : m_touches)
|
||||
{
|
||||
if (touch.IsDown())
|
||||
{
|
||||
hasDown = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasDown)
|
||||
{
|
||||
Logger::INPUT->debug("End multitouch");
|
||||
m_multiTouch = false;
|
||||
}
|
||||
}
|
||||
|
||||
OnTouchUp.NotifyAll(*touchIter);
|
||||
m_gestureProcessor.TouchUp(*touchIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::INPUT->warn("Received touch up for unknown touch id.");
|
||||
}
|
||||
}
|
||||
|
||||
void InputDeviceTouch::TouchMoved(TouchId id, const Math::Vector2f& position)
|
||||
{
|
||||
auto touchIter = FindTouch(id);
|
||||
|
||||
if (touchIter != m_touches.end())
|
||||
{
|
||||
touchIter->m_lastPosition = touchIter->m_position;
|
||||
touchIter->m_position = position;
|
||||
|
||||
OnTouchMoved.NotifyAll(*touchIter);
|
||||
m_gestureProcessor.TouchMoved(*touchIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::INPUT->warn("Received touch moved for unknown touch id");
|
||||
}
|
||||
}
|
||||
|
||||
void InputDeviceTouch::RemoveTouch(TouchId id)
|
||||
{
|
||||
auto touchIter = FindTouch(id);
|
||||
if (touchIter != m_touches.end())
|
||||
{
|
||||
auto removedTouch = *touchIter;
|
||||
m_touches.erase(touchIter);
|
||||
|
||||
if (m_touches.empty())
|
||||
{
|
||||
m_multiTouch = false;
|
||||
}
|
||||
|
||||
OnTouchRemoved.NotifyAll(removedTouch);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::INPUT->warn("Received remove request for unknown touch id");
|
||||
}
|
||||
}
|
||||
|
||||
void InputDeviceTouch::UpdatePinchStarted(const Gesture* pinch, const PinchInfo& info)
|
||||
{
|
||||
m_lastPinchInfo = m_nextPinchInfo = info;
|
||||
}
|
||||
|
||||
void InputDeviceTouch::UpdatePanStarted(const Gesture* pan, const PanInfo& info)
|
||||
{
|
||||
m_lastPanInfo = m_nextPanInfo = info;
|
||||
}
|
||||
|
||||
void InputDeviceTouch::UpdatePanTwoFingersStarted(const Gesture* pan, const PanInfo& info)
|
||||
{
|
||||
m_last2FPanInfo = m_next2FPanInfo = info;
|
||||
}
|
||||
|
||||
void InputDeviceTouch::UpdatePinchMoved(const Gesture* pinch, const PinchInfo& info)
|
||||
{
|
||||
m_nextPinchInfo = info;
|
||||
}
|
||||
|
||||
void InputDeviceTouch::UpdatePanMoved(const Gesture* pan, const PanInfo& info)
|
||||
{
|
||||
m_nextPanInfo = info;
|
||||
}
|
||||
|
||||
void InputDeviceTouch::UpdatePanTwoFingersMoved(const Gesture* pan, const PanInfo& info)
|
||||
{
|
||||
m_next2FPanInfo = info;
|
||||
}
|
||||
|
||||
void InputDeviceTouch::UpdateTap(const Gesture* tap, const TapInfo& info)
|
||||
{
|
||||
m_toBePressedButtons = 1;
|
||||
m_nextTap = info.position;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_TAP_DURATION] = info.duration.count();
|
||||
}
|
||||
|
||||
void InputDeviceTouch::Tick()
|
||||
{
|
||||
m_lastPressedButtons = m_pressedButtons;
|
||||
m_pressedButtons = m_toBePressedButtons;
|
||||
m_toBePressedButtons = 0;
|
||||
|
||||
// Tap
|
||||
auto diff = m_nextTap - m_lastTap;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_TAP_X] = diff.x;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_TAP_Y] = diff.y;
|
||||
m_lastTap = m_nextTap;
|
||||
|
||||
// Pan
|
||||
diff = m_nextPanInfo.position - m_lastPanInfo.position;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_PAN_X] = diff.x;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_PAN_Y] = diff.y;
|
||||
m_lastPanInfo = m_nextPanInfo;
|
||||
diff = m_next2FPanInfo.position - m_last2FPanInfo.position;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_PAN_TWO_FINGERS_X] = diff.x;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_PAN_TWO_FINGERS_Y] = diff.y;
|
||||
m_next2FPanInfo = m_last2FPanInfo;
|
||||
|
||||
// Pinch
|
||||
m_axes[InputKey::Touch::Axis::AXIS_PINCH] = m_nextPinchInfo.scale;
|
||||
diff = m_nextPinchInfo.position - m_lastPinchInfo.position;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_PINCH_CENTER_X] = diff.x;
|
||||
m_axes[InputKey::Touch::Axis::AXIS_PINCH_CENTER_Y] = diff.y;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user