Add ktx
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
/* -*- tab-width: 4; -*- */
|
||||
/* vi: set sw=2 ts=4 expandtab: */
|
||||
|
||||
/*
|
||||
* Copyright 2017-2020 Mark Callow, <khronos at callow dot im>.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _SWIPE_DETECTOR_H
|
||||
#define _SWIPE_DETECTOR_H
|
||||
#if defined(_WIN32)
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <math.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include "SDL_gesture.h"
|
||||
|
||||
class SwipeDetector {
|
||||
public:
|
||||
enum class Direction { up, down, left, right };
|
||||
|
||||
SwipeDetector() : gestureSwipe(false) {}
|
||||
bool doEvent(SDL_Event* event);
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
// Not clangcl
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4311)
|
||||
#pragma warning(disable : 4302)
|
||||
#pragma warning(disable : 4312)
|
||||
#endif
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wvoid-pointer-to-int-cast"
|
||||
#endif
|
||||
// These conversions allow storing a Direction in a pointer.
|
||||
// Ugly. Horrible. But preferable to allocating and freeing memory
|
||||
// when passing the information in user events.
|
||||
static inline Direction pointerToDirection(void* p) {
|
||||
return static_cast<SwipeDetector::Direction>(reinterpret_cast<long>(p));
|
||||
}
|
||||
|
||||
// Only preserves the low 32-bits of the pointer; perfect for this use.
|
||||
static inline void* directionToPointer(SwipeDetector::Direction d) {
|
||||
return reinterpret_cast<void*>(static_cast<long>(d));
|
||||
}
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
static const Uint32 swipeGesture = 0x01;
|
||||
|
||||
class vector {
|
||||
public:
|
||||
float w;
|
||||
float h;
|
||||
|
||||
vector() : w(0.0), h(0.0) { }
|
||||
vector(float _w, float _h) : w(_w), h(_h) { }
|
||||
/**
|
||||
* @~English
|
||||
* @internal
|
||||
* @brief Find the angle between the vector and the X-axis
|
||||
*
|
||||
* Positive angles increase counter-clockwise from the X-axis
|
||||
* which has +x to the right.
|
||||
*
|
||||
* @return the angle between the vector and the x axis in degrees.
|
||||
*/
|
||||
double getAngle() {
|
||||
double rad = atan2(h, w);
|
||||
return rad * 180/M_PI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @internal
|
||||
* @brief Find the angle between this vector and another.
|
||||
*
|
||||
* Positive angles increase counter-clockwise.
|
||||
*
|
||||
* @return the angle between the 2 vectors in degrees.
|
||||
*/
|
||||
double getAngle(const vector& v2) {
|
||||
// Reputed to be more accurate but in our use so far both approaches give same answer.
|
||||
//double rad = atan2f(v2.h, v2.w) - SDL_atan2(h, w);
|
||||
double rad = atan2f(w * v2.h - h * v2.w, w * v2.w + h * v2.h);
|
||||
return rad * 180/M_PI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @internal
|
||||
* @brief Find the angle between the vector and the X-axis
|
||||
*
|
||||
* Positive angles increase counter-clockwise from the X-axis
|
||||
* which has +x to the right. Value is normalized to the range 0 to 360.
|
||||
*
|
||||
* @return the angle between the vector and the x axis in degrees.
|
||||
*/
|
||||
double getAngleNormalized() {
|
||||
double rad = atan2(h, w) + M_PI;
|
||||
return fmod(rad*180/M_PI + 180, 360);
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @internal
|
||||
* @brief Return the length of the vector.
|
||||
*
|
||||
* @return the length of the vector.
|
||||
*/
|
||||
float length() { return sqrt(w * w + h * h); }
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @internal
|
||||
* @brief Return the direction of the vector.
|
||||
*
|
||||
* @return the direction
|
||||
*/
|
||||
Direction getDirection() {
|
||||
double angle = getAngleNormalized();
|
||||
return getDirection(angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @~English
|
||||
* @internal
|
||||
* @brief Return a direction given an angle.
|
||||
*
|
||||
* Directions are defined as follows:
|
||||
*
|
||||
* Up: [45, 135]
|
||||
* Right: [0,45] and [315, 360]
|
||||
* Down: [225, 315]
|
||||
* Left: [135, 225]
|
||||
*
|
||||
* @param angle an angle from 0 to 360°
|
||||
* @return the direction of an angle
|
||||
*/
|
||||
static Direction getDirection(double angle){
|
||||
if (inRange(angle, 45, 135)) {
|
||||
return Direction::down;
|
||||
} else if (inRange(angle, 0, 45) || inRange(angle, 315, 360)) {
|
||||
return Direction::right;
|
||||
} else if (inRange(angle, 225, 315)) {
|
||||
return Direction::up;
|
||||
} else {
|
||||
return Direction::left;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @~English
|
||||
* @internal
|
||||
* @brief Check if angle falls within an interval.
|
||||
*
|
||||
* @param angle an angle
|
||||
* @param init the initial bound
|
||||
* @param end the final bound
|
||||
*
|
||||
* @return true if the given angle is in the interval [init, end), false
|
||||
* otherwise.
|
||||
*/
|
||||
static bool inRange(double angle, float init, float end){
|
||||
return (angle >= init) && (angle < end);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
struct gestureStart {
|
||||
Uint64 time;
|
||||
SDL_FPoint point;
|
||||
gestureStart() { time = 0; point.x = point.y = 0.0; }
|
||||
} gestureStart;
|
||||
std::optional<vector> lastVector;
|
||||
bool gestureSwipe;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline std::string toString(SwipeDetector::Direction dir) {
|
||||
switch (dir) {
|
||||
case SwipeDetector::Direction::up: return "up";
|
||||
case SwipeDetector::Direction::down: return "down";
|
||||
case SwipeDetector::Direction::left: return "left";
|
||||
case SwipeDetector::Direction::right: return "right";
|
||||
// This is to hide a warning from MSVC. According to the solution given
|
||||
// in https://developercommunity.visualstudio.com/t/Visual-Studio-warning-on-Strongly-typed-/96302
|
||||
// it is possible to construct an enum class with any value. Thus warning.
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _SWIPE_DETECTOR_H */
|
||||
Reference in New Issue
Block a user