Add ktx
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2017-2020 Mark Callow.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @class SwipeDetector
|
||||
* @~English
|
||||
*
|
||||
* @brief Definition of a class for detecting swipes.
|
||||
*
|
||||
* @author Mark Callow, github.com/MarkCallow.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "SwipeDetector.h"
|
||||
#include <SDL3/SDL_log.h>
|
||||
|
||||
#if !defined(SWIPEDETECTOR_LOG_GESTURE_EVENTS)
|
||||
#define SWIPEDETECTOR_LOG_GESTURE_EVENTS 0
|
||||
#endif
|
||||
#if !defined(SWIPEDETECTOR_LOG_GESTURE_DETECTION)
|
||||
#define SWIPEDETECTOR_LOG_GESTURE_DETECTION 0
|
||||
#endif
|
||||
|
||||
bool
|
||||
SwipeDetector::doEvent(SDL_Event* event)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_FINGER_UP: {
|
||||
int numFingers;
|
||||
SDL_Finger** fingers = SDL_GetTouchFingers(event->tfinger.touchID, &numFingers);
|
||||
if (SWIPEDETECTOR_LOG_GESTURE_EVENTS) {
|
||||
SDL_Log("SD: Finger: %" SDL_PRIx64 " UP - fingers: %i, x: %f, y: %f",
|
||||
event->tfinger.fingerID, numFingers, event->tfinger.x, event->tfinger.y);
|
||||
}
|
||||
// SDL_GetTouchFingers appears to return the number of fingers
|
||||
// down *before* the event was generated, so 1 means the last finger
|
||||
// just lifted.
|
||||
if (numFingers == 1 && gestureStart.time != 0) {
|
||||
gestureStart.time = 0;
|
||||
gestureSwipe = false;
|
||||
if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) {
|
||||
SDL_Log("***************** SD: FINGER_UP, %smultigesture done *****************",
|
||||
gestureSwipe ? "Swipe complete & " : "");
|
||||
}
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
SDL_free(fingers);
|
||||
break;
|
||||
}
|
||||
case GESTURE_MULTIGESTURE: {
|
||||
Gesture_MultiGestureEvent& mgesture = *(Gesture_MultiGestureEvent *)event;
|
||||
if (SWIPEDETECTOR_LOG_GESTURE_EVENTS) {
|
||||
SDL_Log("SD: MG Event: x = %f, y = %f, dAng = %f (%f), dR = %f, numFingers = %i, time = %" SDL_PRIu64,
|
||||
mgesture.x,
|
||||
mgesture.y,
|
||||
mgesture.dTheta * 180.0 / M_PI,
|
||||
mgesture.dTheta,
|
||||
mgesture.dDist,
|
||||
mgesture.numFingers,
|
||||
mgesture.timestamp);
|
||||
}
|
||||
if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) {
|
||||
SDL_Log("SD: mgestureSwipe = %i, time = %" SDL_PRIu64,
|
||||
gestureSwipe,
|
||||
(mgesture.timestamp - gestureStart.time) / 1000000);
|
||||
}
|
||||
if (gestureStart.time == 0) {
|
||||
if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) {
|
||||
SDL_Log("************ SD: Multigesture detection start **************");
|
||||
}
|
||||
gestureStart.time = mgesture.timestamp;
|
||||
gestureStart.point.x = mgesture.x;
|
||||
gestureStart.point.y = mgesture.y;
|
||||
lastVector.reset();
|
||||
gestureSwipe = false;
|
||||
} else {
|
||||
if (!gestureSwipe) {
|
||||
vector sv; // Vector from start point to current position
|
||||
float velocity;
|
||||
float theta; // Angle between current vector and previous vector.
|
||||
float duration;
|
||||
sv.w = mgesture.x - gestureStart.point.x;
|
||||
sv.h = mgesture.y - gestureStart.point.y;
|
||||
float distance = sv.length();
|
||||
if (lastVector.has_value()) {
|
||||
// SDL2 timestamps were in milliseconds, SDL3 are nanoseconds. Given the
|
||||
// normalized distances reported, using nanoseconds leads to 0 velocitySq.
|
||||
duration = static_cast<float>(
|
||||
(mgesture.timestamp - gestureStart.time) / 1000000.0);
|
||||
|
||||
velocity = distance / duration;
|
||||
assert(!std::isinf(velocity));
|
||||
theta = static_cast<float>(lastVector->getAngle(sv));
|
||||
if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) {
|
||||
SDL_Log("SD: Detection: distance = %f, velocity = %f, theta = %f, sv angle = %f, sv angle normalized = %f, lastv angle = %f",
|
||||
distance, velocity, theta,
|
||||
sv.getAngle(),
|
||||
sv.getAngleNormalized(),
|
||||
lastVector->getAngle());
|
||||
}
|
||||
lastVector = sv;
|
||||
// Multiple events with the same timestamp is a possibility
|
||||
// hence the isinf() check.
|
||||
if (std::abs(theta) < 3.0 && std::abs(mgesture.dDist) > 0.01 && !std::isinf(velocity) && velocity > 0.0007) {
|
||||
if (SWIPEDETECTOR_LOG_GESTURE_DETECTION)
|
||||
SDL_Log("----------------- SD: Swipe %s detected -----------------",
|
||||
toString(sv.getDirection()).c_str());
|
||||
gestureSwipe = true;
|
||||
if (SDL_EventEnabled(SDL_EVENT_USER)) {
|
||||
SDL_Event user_event;
|
||||
// SDL will copy this entire struct! Initialize to keep memory
|
||||
// checkers happy.
|
||||
SDL_zero(user_event);
|
||||
user_event.type = SDL_EVENT_USER;
|
||||
user_event.user.code = swipeGesture;
|
||||
user_event.user.data1 = SwipeDetector::directionToPointer(sv.getDirection());
|
||||
user_event.user.data2 = NULL;
|
||||
SDL_PushEvent(&user_event);
|
||||
}
|
||||
} else {
|
||||
if (SWIPEDETECTOR_LOG_GESTURE_DETECTION) SDL_Log("SD: No swipe detected.");
|
||||
result = true;
|
||||
}
|
||||
} else {
|
||||
lastVector = sv;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user