Fix pinch gesture

This commit is contained in:
2023-10-19 14:24:53 +02:00
parent d9dc2ea79f
commit c950e6ae86
5 changed files with 34 additions and 30 deletions

View File

@@ -132,7 +132,7 @@ namespace OpenVulkano::Input
void GesturePan::TouchMoved(const Touch& touch) void GesturePan::TouchMoved(const Touch& touch)
{ {
if (m_pendingTouches.size() > 0) if (!m_pendingTouches.empty())
{ {
bool isPending = false; bool isPending = false;
bool isActive = false; bool isActive = false;

View File

@@ -12,6 +12,7 @@ namespace OpenVulkano::Input
{ {
constexpr float MIN_DISTANCE = 2; constexpr float MIN_DISTANCE = 2;
constexpr float MIN_DISTANCE2 = MIN_DISTANCE * MIN_DISTANCE; constexpr float MIN_DISTANCE2 = MIN_DISTANCE * MIN_DISTANCE;
constexpr float START_DISTANCE = 400;
constexpr uint32_t REQUIRED_TOUCHES = 2; constexpr uint32_t REQUIRED_TOUCHES = 2;
} }
@@ -45,31 +46,29 @@ namespace OpenVulkano::Input
if (!IsActive()) if (!IsActive())
{ {
SetActive(true); SetActive(true);
float distance = CalculateDistance();
m_initialDistance = CalculateDistance(); if (distance < START_DISTANCE)
{
float newDistance = m_initialDistance; SetActive(false);
return;
}
m_initialDistance = distance;
if (m_initialDistance > 0) if (m_initialDistance > 0)
{ {
m_pinchInfo.scale = newDistance > 0 ? m_initialDistance / newDistance : m_lastDistance; m_pinchInfo.scale = m_initialDistance;
m_pinchInfo.position = CalculateCenter(); m_pinchInfo.position = CalculateCenter();
} }
else else
{ {
m_pinchInfo.scale = 1.0f; m_pinchInfo.scale = 0.0f;
m_pinchInfo.position = m_pendingTouches.front().currentPosition; m_pinchInfo.position = m_pendingTouches.front().currentPosition;
} }
if (m_lastDistance == 0)
{
m_lastDistance = newDistance;
}
// fire event
OnPinchStarted.NotifyAll(this, m_pinchInfo); OnPinchStarted.NotifyAll(this, m_pinchInfo);
m_lastDistance = newDistance; m_lastDistance = m_initialDistance;
} }
else else
{ {
@@ -78,11 +77,10 @@ namespace OpenVulkano::Input
} }
} }
float GesturePinch::LinearLength(const std::vector<Math::Vector2f>& points) const float GesturePinch::LinearLength(const std::vector<Math::Vector2f>& points)
{ {
if (points.size() < 2) return 0;
auto start = points.begin(); auto start = points.begin();
if (start == points.end()) return 0;
auto finish = start + 1; auto finish = start + 1;
float sum = 0; float sum = 0;
@@ -112,17 +110,21 @@ namespace OpenVulkano::Input
Math::Vector2f GesturePinch::CalculateCenter() const Math::Vector2f GesturePinch::CalculateCenter() const
{ {
auto center = Math::Vector2f(); Math::Vector2f center(0);
if (m_pendingTouches.size() >= REQUIRED_TOUCHES && IsActive() && !m_paused) if (m_pendingTouches.size() >= REQUIRED_TOUCHES && IsActive() && !m_paused)
{ {
std::vector<Math::Vector2f> positions; int count = 0;
for (const auto& t : m_pendingTouches) for (const auto& t : m_pendingTouches)
{ {
if (t.active) positions.push_back(t.currentPosition); if (t.active)
{
center += t.currentPosition;
count++;
}
} }
for (const auto& position : positions) if (count)
{ {
center += position / (float)positions.size(); center /= count;
} }
} }
return center; return center;
@@ -138,6 +140,7 @@ namespace OpenVulkano::Input
m_paused = false; m_paused = false;
OnPinchEnded.NotifyAll(this, m_pinchInfo); OnPinchEnded.NotifyAll(this, m_pinchInfo);
m_pinchInfo.position = {}; m_pinchInfo.position = {};
m_pinchInfo.scale = 0.0f;
} }
void GesturePinch::TouchDown(const Touch& touch) void GesturePinch::TouchDown(const Touch& touch)
@@ -206,12 +209,12 @@ namespace OpenVulkano::Input
if (m_initialDistance > 0) if (m_initialDistance > 0)
{ {
m_pinchInfo.scale = newDistance > 0 ? m_initialDistance / newDistance : m_lastDistance; m_pinchInfo.scale = (newDistance - m_initialDistance);
m_pinchInfo.position = CalculateCenter(); m_pinchInfo.position = CalculateCenter();
} }
else else
{ {
m_pinchInfo.scale = 1.0f; m_pinchInfo.scale = 0.0f;
m_pinchInfo.position = m_pendingTouches.front().currentPosition; m_pinchInfo.position = m_pendingTouches.front().currentPosition;
} }
@@ -241,4 +244,4 @@ namespace OpenVulkano::Input
if (m_pendingTouches.empty() && IsActive()) Cancel(); if (m_pendingTouches.empty() && IsActive()) Cancel();
} }
} }
} }

View File

@@ -22,7 +22,7 @@ namespace OpenVulkano::Input
void TryStart(); void TryStart();
float LinearLength(std::vector<Math::Vector2f> const &points) const; static float LinearLength(std::vector<Math::Vector2f> const &points) ;
float CalculateDistance() const; float CalculateDistance() const;

View File

@@ -43,7 +43,7 @@ namespace OpenVulkano::Input
Logger::INPUT->debug("Replacing pan with multitouch gesture"); Logger::INPUT->debug("Replacing pan with multitouch gesture");
return ConflictResult::NewGesture; return ConflictResult::NewGesture;
} }
return ConflictResult::BothGestures; return ConflictResult::ExistingGesture;
}; };
} }

View File

@@ -204,9 +204,10 @@ namespace OpenVulkano::Input
m_next2FPanInfo = m_last2FPanInfo; m_next2FPanInfo = m_last2FPanInfo;
// Pinch // Pinch
m_axes[InputKey::Touch::Axis::AXIS_PINCH] = m_nextPinchInfo.scale; m_axes[InputKey::Touch::Axis::AXIS_PINCH] = m_nextPinchInfo.scale - m_lastPinchInfo.scale;
diff = m_nextPinchInfo.position - m_lastPinchInfo.position; 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_X] = diff.x;
m_axes[InputKey::Touch::Axis::AXIS_PINCH_CENTER_Y] = diff.y; m_axes[InputKey::Touch::Axis::AXIS_PINCH_CENTER_Y] = diff.y;
m_lastPinchInfo = m_nextPinchInfo;
} }
} }