mirror of
https://github.com/overte-org/overte.git
synced 2025-04-24 03:13:32 +02:00
move TouchEvent out of EventTypes to its own file
This commit is contained in:
parent
3aa7c3c7dc
commit
e72409bf39
5 changed files with 270 additions and 235 deletions
|
@ -20,6 +20,7 @@
|
|||
#include "EventTypes.h"
|
||||
#include "KeyEvent.h"
|
||||
#include "MouseEvent.h"
|
||||
#include "TouchEvent.h"
|
||||
|
||||
class AbstractInputController : public QObject {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -14,209 +14,18 @@
|
|||
|
||||
#include "KeyEvent.h"
|
||||
#include "MouseEvent.h"
|
||||
#include "TouchEvent.h"
|
||||
|
||||
#include "EventTypes.h"
|
||||
|
||||
void registerEventTypes(QScriptEngine* engine) {
|
||||
qScriptRegisterMetaType(engine, KeyEvent::toScriptValue, KeyEvent::fromScriptValue);
|
||||
qScriptRegisterMetaType(engine, MouseEvent::toScriptValue, MouseEvent::fromScriptValue);
|
||||
qScriptRegisterMetaType(engine, touchEventToScriptValue, touchEventFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, TouchEvent::toScriptValue, TouchEvent::fromScriptValue);
|
||||
qScriptRegisterMetaType(engine, wheelEventToScriptValue, wheelEventFromScriptValue);
|
||||
qScriptRegisterMetaType(engine, spatialEventToScriptValue, spatialEventFromScriptValue);
|
||||
}
|
||||
|
||||
TouchEvent::TouchEvent() :
|
||||
x(0.0f),
|
||||
y(0.0f),
|
||||
isPressed(false),
|
||||
isMoved(false),
|
||||
isStationary(false),
|
||||
isReleased(false),
|
||||
isShifted(false),
|
||||
isControl(false),
|
||||
isMeta(false),
|
||||
isAlt(false),
|
||||
touchPoints(0),
|
||||
points(),
|
||||
radius(0.0f),
|
||||
isPinching(false),
|
||||
isPinchOpening(false),
|
||||
angles(),
|
||||
angle(0.0f),
|
||||
deltaAngle(0.0f),
|
||||
isRotating(false),
|
||||
rotating("none")
|
||||
{
|
||||
};
|
||||
|
||||
TouchEvent::TouchEvent(const QTouchEvent& event) :
|
||||
// these values are not set by initWithQTouchEvent() because they only apply to comparing to other events
|
||||
isPinching(false),
|
||||
isPinchOpening(false),
|
||||
deltaAngle(0.0f),
|
||||
isRotating(false),
|
||||
rotating("none")
|
||||
{
|
||||
initWithQTouchEvent(event);
|
||||
}
|
||||
|
||||
TouchEvent::TouchEvent(const QTouchEvent& event, const TouchEvent& other) {
|
||||
initWithQTouchEvent(event);
|
||||
calculateMetaAttributes(other);
|
||||
}
|
||||
|
||||
// returns the angle (in degrees) between two points (note: 0 degrees is 'east')
|
||||
float angleBetweenPoints(const glm::vec2& a, const glm::vec2& b ) {
|
||||
glm::vec2 length = b - a;
|
||||
float angle = DEGREES_PER_RADIAN * std::atan2(length.y, length.x);
|
||||
if (angle < 0) {
|
||||
angle += 360.0f;
|
||||
};
|
||||
return angle;
|
||||
}
|
||||
|
||||
void TouchEvent::initWithQTouchEvent(const QTouchEvent& event) {
|
||||
// convert the touch points into an average
|
||||
const QList<QTouchEvent::TouchPoint>& tPoints = event.touchPoints();
|
||||
float touchAvgX = 0.0f;
|
||||
float touchAvgY = 0.0f;
|
||||
touchPoints = tPoints.count();
|
||||
if (touchPoints > 1) {
|
||||
for (int i = 0; i < touchPoints; ++i) {
|
||||
touchAvgX += tPoints[i].pos().x();
|
||||
touchAvgY += tPoints[i].pos().y();
|
||||
|
||||
// add it to our points vector
|
||||
glm::vec2 thisPoint(tPoints[i].pos().x(), tPoints[i].pos().y());
|
||||
points << thisPoint;
|
||||
}
|
||||
touchAvgX /= (float)(touchPoints);
|
||||
touchAvgY /= (float)(touchPoints);
|
||||
} else {
|
||||
// I'm not sure this should ever happen, why would Qt send us a touch event for only one point?
|
||||
// maybe this happens in the case of a multi-touch where all but the last finger is released?
|
||||
touchAvgX = tPoints[0].pos().x();
|
||||
touchAvgY = tPoints[0].pos().y();
|
||||
}
|
||||
x = touchAvgX;
|
||||
y = touchAvgY;
|
||||
|
||||
// after calculating the center point (average touch point), determine the maximum radius
|
||||
// also calculate the rotation angle for each point
|
||||
float maxRadius = 0.0f;
|
||||
glm::vec2 center(x,y);
|
||||
for (int i = 0; i < touchPoints; ++i) {
|
||||
glm::vec2 touchPoint(tPoints[i].pos().x(), tPoints[i].pos().y());
|
||||
float thisRadius = glm::distance(center,touchPoint);
|
||||
if (thisRadius > maxRadius) {
|
||||
maxRadius = thisRadius;
|
||||
}
|
||||
|
||||
// calculate the angle for this point
|
||||
float thisAngle = angleBetweenPoints(center,touchPoint);
|
||||
angles << thisAngle;
|
||||
}
|
||||
radius = maxRadius;
|
||||
|
||||
// after calculating the angles for each touch point, determine the average angle
|
||||
float totalAngle = 0.0f;
|
||||
for (int i = 0; i < touchPoints; ++i) {
|
||||
totalAngle += angles[i];
|
||||
}
|
||||
angle = totalAngle/(float)touchPoints;
|
||||
|
||||
isPressed = event.touchPointStates().testFlag(Qt::TouchPointPressed);
|
||||
isMoved = event.touchPointStates().testFlag(Qt::TouchPointMoved);
|
||||
isStationary = event.touchPointStates().testFlag(Qt::TouchPointStationary);
|
||||
isReleased = event.touchPointStates().testFlag(Qt::TouchPointReleased);
|
||||
|
||||
// keyboard modifiers
|
||||
isShifted = event.modifiers().testFlag(Qt::ShiftModifier);
|
||||
isMeta = event.modifiers().testFlag(Qt::MetaModifier);
|
||||
isControl = event.modifiers().testFlag(Qt::ControlModifier);
|
||||
isAlt = event.modifiers().testFlag(Qt::AltModifier);
|
||||
}
|
||||
|
||||
void TouchEvent::calculateMetaAttributes(const TouchEvent& other) {
|
||||
// calculate comparative event attributes...
|
||||
if (other.radius > radius) {
|
||||
isPinching = true;
|
||||
isPinchOpening = false;
|
||||
} else if (other.radius < radius) {
|
||||
isPinchOpening = true;
|
||||
isPinching = false;
|
||||
} else {
|
||||
isPinching = other.isPinching;
|
||||
isPinchOpening = other.isPinchOpening;
|
||||
}
|
||||
|
||||
// determine if the points are rotating...
|
||||
// note: if the number of touch points change between events, then we don't consider ourselves to be rotating
|
||||
if (touchPoints == other.touchPoints) {
|
||||
deltaAngle = angle - other.angle;
|
||||
if (other.angle < angle) {
|
||||
isRotating = true;
|
||||
rotating = "clockwise";
|
||||
} else if (other.angle > angle) {
|
||||
isRotating = true;
|
||||
rotating = "counterClockwise";
|
||||
} else {
|
||||
isRotating = false;
|
||||
rotating = "none";
|
||||
}
|
||||
} else {
|
||||
deltaAngle = 0.0f;
|
||||
isRotating = false;
|
||||
rotating = "none";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QScriptValue touchEventToScriptValue(QScriptEngine* engine, const TouchEvent& event) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
obj.setProperty("x", event.x);
|
||||
obj.setProperty("y", event.y);
|
||||
obj.setProperty("isPressed", event.isPressed);
|
||||
obj.setProperty("isMoved", event.isMoved);
|
||||
obj.setProperty("isStationary", event.isStationary);
|
||||
obj.setProperty("isReleased", event.isReleased);
|
||||
obj.setProperty("isShifted", event.isShifted);
|
||||
obj.setProperty("isMeta", event.isMeta);
|
||||
obj.setProperty("isControl", event.isControl);
|
||||
obj.setProperty("isAlt", event.isAlt);
|
||||
obj.setProperty("touchPoints", event.touchPoints);
|
||||
|
||||
QScriptValue pointsObj = engine->newArray();
|
||||
int index = 0;
|
||||
foreach (glm::vec2 point, event.points) {
|
||||
QScriptValue thisPoint = vec2toScriptValue(engine, point);
|
||||
pointsObj.setProperty(index, thisPoint);
|
||||
index++;
|
||||
}
|
||||
obj.setProperty("points", pointsObj);
|
||||
obj.setProperty("radius", event.radius);
|
||||
obj.setProperty("isPinching", event.isPinching);
|
||||
obj.setProperty("isPinchOpening", event.isPinchOpening);
|
||||
|
||||
obj.setProperty("angle", event.angle);
|
||||
obj.setProperty("deltaAngle", event.deltaAngle);
|
||||
QScriptValue anglesObj = engine->newArray();
|
||||
index = 0;
|
||||
foreach (float angle, event.angles) {
|
||||
anglesObj.setProperty(index, angle);
|
||||
index++;
|
||||
}
|
||||
obj.setProperty("angles", anglesObj);
|
||||
|
||||
obj.setProperty("isRotating", event.isRotating);
|
||||
obj.setProperty("rotating", event.rotating);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void touchEventFromScriptValue(const QScriptValue& object, TouchEvent& event) {
|
||||
// nothing for now...
|
||||
}
|
||||
|
||||
WheelEvent::WheelEvent() :
|
||||
x(0.0f),
|
||||
y(0.0f),
|
||||
|
|
|
@ -12,50 +12,12 @@
|
|||
#ifndef hifi_EventTypes_h
|
||||
#define hifi_EventTypes_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QTouchEvent>
|
||||
#include <QWheelEvent>
|
||||
|
||||
|
||||
class TouchEvent {
|
||||
public:
|
||||
TouchEvent();
|
||||
TouchEvent(const QTouchEvent& event);
|
||||
TouchEvent(const QTouchEvent& event, const TouchEvent& other);
|
||||
|
||||
float x;
|
||||
float y;
|
||||
bool isPressed;
|
||||
bool isMoved;
|
||||
bool isStationary;
|
||||
bool isReleased;
|
||||
bool isShifted;
|
||||
bool isControl;
|
||||
bool isMeta;
|
||||
bool isAlt;
|
||||
int touchPoints;
|
||||
QVector<glm::vec2> points;
|
||||
float radius;
|
||||
bool isPinching;
|
||||
bool isPinchOpening;
|
||||
|
||||
// angles are in degrees
|
||||
QVector<float> angles; // angle from center to each point
|
||||
float angle; // the average of the angles
|
||||
float deltaAngle; // the change in average angle from last event
|
||||
bool isRotating;
|
||||
QString rotating;
|
||||
|
||||
private:
|
||||
void initWithQTouchEvent(const QTouchEvent& event);
|
||||
void calculateMetaAttributes(const TouchEvent& other);
|
||||
};
|
||||
|
||||
class WheelEvent {
|
||||
public:
|
||||
WheelEvent();
|
||||
|
@ -86,16 +48,12 @@ public:
|
|||
private:
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(TouchEvent)
|
||||
Q_DECLARE_METATYPE(WheelEvent)
|
||||
Q_DECLARE_METATYPE(SpatialEvent)
|
||||
|
||||
void registerEventTypes(QScriptEngine* engine);
|
||||
|
||||
|
||||
QScriptValue touchEventToScriptValue(QScriptEngine* engine, const TouchEvent& event);
|
||||
void touchEventFromScriptValue(const QScriptValue& object, TouchEvent& event);
|
||||
|
||||
QScriptValue wheelEventToScriptValue(QScriptEngine* engine, const WheelEvent& event);
|
||||
void wheelEventFromScriptValue(const QScriptValue& object, WheelEvent& event);
|
||||
|
||||
|
|
211
libraries/script-engine/src/TouchEvent.cpp
Normal file
211
libraries/script-engine/src/TouchEvent.cpp
Normal file
|
@ -0,0 +1,211 @@
|
|||
//
|
||||
// TouchEvent.cpp
|
||||
// script-engine/src
|
||||
//
|
||||
// Created by Stephen Birarda on 2014-10-27.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <qscriptengine.h>
|
||||
#include <qscriptvalue.h>
|
||||
#include <QTouchEvent>
|
||||
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "TouchEvent.h"
|
||||
|
||||
TouchEvent::TouchEvent() :
|
||||
x(0.0f),
|
||||
y(0.0f),
|
||||
isPressed(false),
|
||||
isMoved(false),
|
||||
isStationary(false),
|
||||
isReleased(false),
|
||||
isShifted(false),
|
||||
isControl(false),
|
||||
isMeta(false),
|
||||
isAlt(false),
|
||||
touchPoints(0),
|
||||
points(),
|
||||
radius(0.0f),
|
||||
isPinching(false),
|
||||
isPinchOpening(false),
|
||||
angles(),
|
||||
angle(0.0f),
|
||||
deltaAngle(0.0f),
|
||||
isRotating(false),
|
||||
rotating("none")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TouchEvent::TouchEvent(const QTouchEvent& event) :
|
||||
// these values are not set by initWithQTouchEvent() because they only apply to comparing to other events
|
||||
isPinching(false),
|
||||
isPinchOpening(false),
|
||||
deltaAngle(0.0f),
|
||||
isRotating(false),
|
||||
rotating("none")
|
||||
{
|
||||
initWithQTouchEvent(event);
|
||||
}
|
||||
|
||||
TouchEvent::TouchEvent(const QTouchEvent& event, const TouchEvent& other) {
|
||||
initWithQTouchEvent(event);
|
||||
calculateMetaAttributes(other);
|
||||
}
|
||||
|
||||
// returns the angle (in degrees) between two points (note: 0 degrees is 'east')
|
||||
float angleBetweenPoints(const glm::vec2& a, const glm::vec2& b ) {
|
||||
glm::vec2 length = b - a;
|
||||
float angle = DEGREES_PER_RADIAN * std::atan2(length.y, length.x);
|
||||
if (angle < 0) {
|
||||
angle += 360.0f;
|
||||
};
|
||||
return angle;
|
||||
}
|
||||
|
||||
void TouchEvent::initWithQTouchEvent(const QTouchEvent& event) {
|
||||
// convert the touch points into an average
|
||||
const QList<QTouchEvent::TouchPoint>& tPoints = event.touchPoints();
|
||||
float touchAvgX = 0.0f;
|
||||
float touchAvgY = 0.0f;
|
||||
touchPoints = tPoints.count();
|
||||
if (touchPoints > 1) {
|
||||
for (int i = 0; i < touchPoints; ++i) {
|
||||
touchAvgX += tPoints[i].pos().x();
|
||||
touchAvgY += tPoints[i].pos().y();
|
||||
|
||||
// add it to our points vector
|
||||
glm::vec2 thisPoint(tPoints[i].pos().x(), tPoints[i].pos().y());
|
||||
points << thisPoint;
|
||||
}
|
||||
touchAvgX /= (float)(touchPoints);
|
||||
touchAvgY /= (float)(touchPoints);
|
||||
} else {
|
||||
// I'm not sure this should ever happen, why would Qt send us a touch event for only one point?
|
||||
// maybe this happens in the case of a multi-touch where all but the last finger is released?
|
||||
touchAvgX = tPoints[0].pos().x();
|
||||
touchAvgY = tPoints[0].pos().y();
|
||||
}
|
||||
x = touchAvgX;
|
||||
y = touchAvgY;
|
||||
|
||||
// after calculating the center point (average touch point), determine the maximum radius
|
||||
// also calculate the rotation angle for each point
|
||||
float maxRadius = 0.0f;
|
||||
glm::vec2 center(x,y);
|
||||
for (int i = 0; i < touchPoints; ++i) {
|
||||
glm::vec2 touchPoint(tPoints[i].pos().x(), tPoints[i].pos().y());
|
||||
float thisRadius = glm::distance(center,touchPoint);
|
||||
if (thisRadius > maxRadius) {
|
||||
maxRadius = thisRadius;
|
||||
}
|
||||
|
||||
// calculate the angle for this point
|
||||
float thisAngle = angleBetweenPoints(center,touchPoint);
|
||||
angles << thisAngle;
|
||||
}
|
||||
radius = maxRadius;
|
||||
|
||||
// after calculating the angles for each touch point, determine the average angle
|
||||
float totalAngle = 0.0f;
|
||||
for (int i = 0; i < touchPoints; ++i) {
|
||||
totalAngle += angles[i];
|
||||
}
|
||||
angle = totalAngle/(float)touchPoints;
|
||||
|
||||
isPressed = event.touchPointStates().testFlag(Qt::TouchPointPressed);
|
||||
isMoved = event.touchPointStates().testFlag(Qt::TouchPointMoved);
|
||||
isStationary = event.touchPointStates().testFlag(Qt::TouchPointStationary);
|
||||
isReleased = event.touchPointStates().testFlag(Qt::TouchPointReleased);
|
||||
|
||||
// keyboard modifiers
|
||||
isShifted = event.modifiers().testFlag(Qt::ShiftModifier);
|
||||
isMeta = event.modifiers().testFlag(Qt::MetaModifier);
|
||||
isControl = event.modifiers().testFlag(Qt::ControlModifier);
|
||||
isAlt = event.modifiers().testFlag(Qt::AltModifier);
|
||||
}
|
||||
|
||||
void TouchEvent::calculateMetaAttributes(const TouchEvent& other) {
|
||||
// calculate comparative event attributes...
|
||||
if (other.radius > radius) {
|
||||
isPinching = true;
|
||||
isPinchOpening = false;
|
||||
} else if (other.radius < radius) {
|
||||
isPinchOpening = true;
|
||||
isPinching = false;
|
||||
} else {
|
||||
isPinching = other.isPinching;
|
||||
isPinchOpening = other.isPinchOpening;
|
||||
}
|
||||
|
||||
// determine if the points are rotating...
|
||||
// note: if the number of touch points change between events, then we don't consider ourselves to be rotating
|
||||
if (touchPoints == other.touchPoints) {
|
||||
deltaAngle = angle - other.angle;
|
||||
if (other.angle < angle) {
|
||||
isRotating = true;
|
||||
rotating = "clockwise";
|
||||
} else if (other.angle > angle) {
|
||||
isRotating = true;
|
||||
rotating = "counterClockwise";
|
||||
} else {
|
||||
isRotating = false;
|
||||
rotating = "none";
|
||||
}
|
||||
} else {
|
||||
deltaAngle = 0.0f;
|
||||
isRotating = false;
|
||||
rotating = "none";
|
||||
}
|
||||
}
|
||||
|
||||
QScriptValue TouchEvent::toScriptValue(QScriptEngine* engine, const TouchEvent& event) {
|
||||
QScriptValue obj = engine->newObject();
|
||||
obj.setProperty("x", event.x);
|
||||
obj.setProperty("y", event.y);
|
||||
obj.setProperty("isPressed", event.isPressed);
|
||||
obj.setProperty("isMoved", event.isMoved);
|
||||
obj.setProperty("isStationary", event.isStationary);
|
||||
obj.setProperty("isReleased", event.isReleased);
|
||||
obj.setProperty("isShifted", event.isShifted);
|
||||
obj.setProperty("isMeta", event.isMeta);
|
||||
obj.setProperty("isControl", event.isControl);
|
||||
obj.setProperty("isAlt", event.isAlt);
|
||||
obj.setProperty("touchPoints", event.touchPoints);
|
||||
|
||||
QScriptValue pointsObj = engine->newArray();
|
||||
int index = 0;
|
||||
foreach (glm::vec2 point, event.points) {
|
||||
QScriptValue thisPoint = vec2toScriptValue(engine, point);
|
||||
pointsObj.setProperty(index, thisPoint);
|
||||
index++;
|
||||
}
|
||||
obj.setProperty("points", pointsObj);
|
||||
obj.setProperty("radius", event.radius);
|
||||
obj.setProperty("isPinching", event.isPinching);
|
||||
obj.setProperty("isPinchOpening", event.isPinchOpening);
|
||||
|
||||
obj.setProperty("angle", event.angle);
|
||||
obj.setProperty("deltaAngle", event.deltaAngle);
|
||||
QScriptValue anglesObj = engine->newArray();
|
||||
index = 0;
|
||||
foreach (float angle, event.angles) {
|
||||
anglesObj.setProperty(index, angle);
|
||||
index++;
|
||||
}
|
||||
obj.setProperty("angles", anglesObj);
|
||||
|
||||
obj.setProperty("isRotating", event.isRotating);
|
||||
obj.setProperty("rotating", event.rotating);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void TouchEvent::fromScriptValue(const QScriptValue& object, TouchEvent& event) {
|
||||
// nothing for now...
|
||||
}
|
56
libraries/script-engine/src/TouchEvent.h
Normal file
56
libraries/script-engine/src/TouchEvent.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// TouchEvent.h
|
||||
// script-engine/src
|
||||
//
|
||||
// Created by Stephen Birarda on 2014-10-27.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_TouchEvent_h
|
||||
#define hifi_TouchEvent_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class TouchEvent {
|
||||
public:
|
||||
TouchEvent();
|
||||
TouchEvent(const QTouchEvent& event);
|
||||
TouchEvent(const QTouchEvent& event, const TouchEvent& other);
|
||||
|
||||
static QScriptValue toScriptValue(QScriptEngine* engine, const TouchEvent& event);
|
||||
static void fromScriptValue(const QScriptValue& object, TouchEvent& event);
|
||||
|
||||
float x;
|
||||
float y;
|
||||
bool isPressed;
|
||||
bool isMoved;
|
||||
bool isStationary;
|
||||
bool isReleased;
|
||||
bool isShifted;
|
||||
bool isControl;
|
||||
bool isMeta;
|
||||
bool isAlt;
|
||||
int touchPoints;
|
||||
QVector<glm::vec2> points;
|
||||
float radius;
|
||||
bool isPinching;
|
||||
bool isPinchOpening;
|
||||
|
||||
// angles are in degrees
|
||||
QVector<float> angles; // angle from center to each point
|
||||
float angle; // the average of the angles
|
||||
float deltaAngle; // the change in average angle from last event
|
||||
bool isRotating;
|
||||
QString rotating;
|
||||
|
||||
private:
|
||||
void initWithQTouchEvent(const QTouchEvent& event);
|
||||
void calculateMetaAttributes(const TouchEvent& other);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(TouchEvent)
|
||||
|
||||
#endif // hifi_TouchEvent_h
|
Loading…
Reference in a new issue