Files
OpenVulkano/openVulkanoCpp/Input/Touch/InputDeviceTouch.cpp
2025-10-12 15:26:11 +02:00

224 lines
6.4 KiB
C++

/*
* 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_gesturePan.OnPanEnded += EventHandler(this, &InputDeviceTouch::UpdatePanStarted);
m_gestureProcessor.m_gesturePanTwoFingers.OnPanStarted += EventHandler(this, &InputDeviceTouch::UpdatePanTwoFingersStarted);
m_gestureProcessor.m_gesturePanTwoFingers.OnPanMoved += EventHandler(this, &InputDeviceTouch::UpdatePanTwoFingersMoved);
m_gestureProcessor.m_gesturePanTwoFingers.OnPanEnded += EventHandler(this, &InputDeviceTouch::UpdatePanTwoFingersStarted);
m_gestureProcessor.m_gesturePinch.OnPinchStarted += EventHandler(this, &InputDeviceTouch::UpdatePinchStarted);
m_gestureProcessor.m_gesturePinch.OnPinchMoved += EventHandler(this, &InputDeviceTouch::UpdatePinchMoved);
m_gestureProcessor.m_gesturePinch.OnPinchEnded += EventHandler(this, &InputDeviceTouch::UpdatePinchStarted);
}
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()
{
if (m_nextPanInfo.position.x > 0 && m_nextPanInfo.position.y > 0)
m_toBePressedButtons |= 1 << InputKey::Touch::BUTTON_PAN; // Handle pan press
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_axes[InputKey::Touch::Axis::AXIS_TAP_X_ABS] = m_nextTap.x;
m_axes[InputKey::Touch::Axis::AXIS_TAP_Y_ABS] = m_nextTap.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_axes[InputKey::Touch::Axis::AXIS_PAN_X_ABS] = m_nextPanInfo.position.x;
m_axes[InputKey::Touch::Axis::AXIS_PAN_Y_ABS] = m_nextPanInfo.position.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_last2FPanInfo = m_next2FPanInfo;
// Pinch
m_axes[InputKey::Touch::Axis::AXIS_PINCH] = m_nextPinchInfo.scale - m_lastPinchInfo.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;
m_lastPinchInfo = m_nextPinchInfo;
}
}