mirror of
https://github.com/lubosz/overte.git
synced 2025-04-10 15:57:39 +02:00
isLeftHand, isRightHand, isMouse
This commit is contained in:
parent
55ac585cd9
commit
7d420f5242
23 changed files with 176 additions and 127 deletions
|
@ -64,11 +64,12 @@ Item {
|
|||
keyItem.state = "mouseOver";
|
||||
|
||||
var globalPosition = keyItem.mapToGlobal(mouseArea1.mouseX, mouseArea1.mouseY);
|
||||
var deviceId = Web3DOverlay.deviceIdByTouchPoint(globalPosition.x, globalPosition.y);
|
||||
var hand = deviceId - 1; // based on touchEventUtils.js, deviceId is 'hand + 1', so 'hand' is 'deviceId' - 1
|
||||
var pointerID = Web3DOverlay.deviceIdByTouchPoint(globalPosition.x, globalPosition.y);
|
||||
|
||||
if (hand == leftHand || hand == rightHand) {
|
||||
Controller.triggerHapticPulse(_HAPTIC_STRENGTH, _HAPTIC_DURATION, hand);
|
||||
if (Pointers.isLeftHand(pointerID)) {
|
||||
Controller.triggerHapticPulse(_HAPTIC_STRENGTH, _HAPTIC_DURATION, leftHand);
|
||||
} else if (Pointers.isRightHand(pointerID)) {
|
||||
Controller.triggerHapticPulse(_HAPTIC_STRENGTH, _HAPTIC_DURATION, rightHand);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ public:
|
|||
|
||||
const PickRay getMathematicalPick() const override;
|
||||
|
||||
bool isLeftHand() const override { return (_jointName == "_CONTROLLER_LEFTHAND") || (_jointName == "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"); }
|
||||
bool isRightHand() const override { return (_jointName == "_CONTROLLER_RIGHTHAND") || (_jointName == "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"); }
|
||||
|
||||
private:
|
||||
std::string _jointName;
|
||||
glm::vec3 _posOffset;
|
||||
|
|
|
@ -20,7 +20,7 @@ class LaserPointerScriptingInterface : public QObject, public Dependency {
|
|||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public slots:
|
||||
public:
|
||||
Q_INVOKABLE unsigned int createLaserPointer(const QVariant& properties) const;
|
||||
Q_INVOKABLE void enableLaserPointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->enablePointer(uid); }
|
||||
Q_INVOKABLE void disableLaserPointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->disablePointer(uid); }
|
||||
|
@ -36,6 +36,10 @@ public slots:
|
|||
|
||||
Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get<PointerManager>()->setLockEndUUID(uid, objectID, isOverlay); }
|
||||
|
||||
Q_INVOKABLE bool isLeftHand(unsigned int uid) { return DependencyManager::get<PointerManager>()->isLeftHand(uid); }
|
||||
Q_INVOKABLE bool isRightHand(unsigned int uid) { return DependencyManager::get<PointerManager>()->isRightHand(uid); }
|
||||
Q_INVOKABLE bool isMouse(unsigned int uid) { return DependencyManager::get<PointerManager>()->isMouse(uid); }
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_LaserPointerScriptingInterface_h
|
||||
|
|
|
@ -19,6 +19,8 @@ public:
|
|||
MouseRayPick(const PickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false);
|
||||
|
||||
const PickRay getMathematicalPick() const override;
|
||||
|
||||
bool isMouse() const override { return true; }
|
||||
};
|
||||
|
||||
#endif // hifi_MouseRayPick_h
|
||||
|
|
|
@ -109,6 +109,18 @@ void PickScriptingInterface::setIncludeItems(unsigned int uid, const QScriptValu
|
|||
DependencyManager::get<PickManager>()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
|
||||
}
|
||||
|
||||
bool PickScriptingInterface::isLeftHand(unsigned int uid) {
|
||||
return DependencyManager::get<PickManager>()->isLeftHand(uid);
|
||||
}
|
||||
|
||||
bool PickScriptingInterface::isRightHand(unsigned int uid) {
|
||||
return DependencyManager::get<PickManager>()->isRightHand(uid);
|
||||
}
|
||||
|
||||
bool PickScriptingInterface::isMouse(unsigned int uid) {
|
||||
return DependencyManager::get<PickManager>()->isMouse(uid);
|
||||
}
|
||||
|
||||
QScriptValue pickTypesToScriptValue(QScriptEngine* engine, const PickQuery::PickType& pickType) {
|
||||
return pickType;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ public:
|
|||
|
||||
void registerMetaTypes(QScriptEngine* engine);
|
||||
|
||||
public slots:
|
||||
Q_INVOKABLE unsigned int createPick(const PickQuery::PickType type, const QVariant& properties);
|
||||
Q_INVOKABLE void enablePick(unsigned int uid);
|
||||
Q_INVOKABLE void disablePick(unsigned int uid);
|
||||
|
@ -48,6 +47,11 @@ public slots:
|
|||
Q_INVOKABLE void setIgnoreItems(unsigned int uid, const QScriptValue& ignoreEntities);
|
||||
Q_INVOKABLE void setIncludeItems(unsigned int uid, const QScriptValue& includeEntities);
|
||||
|
||||
Q_INVOKABLE bool isLeftHand(unsigned int uid);
|
||||
Q_INVOKABLE bool isRightHand(unsigned int uid);
|
||||
Q_INVOKABLE bool isMouse(unsigned int uid);
|
||||
|
||||
public slots:
|
||||
static constexpr unsigned int PICK_NOTHING() { return 0; }
|
||||
static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); }
|
||||
static constexpr unsigned int PICK_OVERLAYS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_OVERLAYS); }
|
||||
|
|
|
@ -21,7 +21,6 @@ class PointerScriptingInterface : public QObject, public Dependency {
|
|||
public:
|
||||
unsigned int createLaserPointer(const QVariant& properties) const;
|
||||
|
||||
public slots:
|
||||
Q_INVOKABLE unsigned int createPointer(const PickQuery::PickType& type, const QVariant& properties) const;
|
||||
Q_INVOKABLE void enablePointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->enablePointer(uid); }
|
||||
Q_INVOKABLE void disablePointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->disablePointer(uid); }
|
||||
|
@ -37,6 +36,10 @@ public slots:
|
|||
|
||||
Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get<PointerManager>()->setLockEndUUID(uid, objectID, isOverlay); }
|
||||
|
||||
Q_INVOKABLE bool isLeftHand(unsigned int uid) { return DependencyManager::get<PointerManager>()->isLeftHand(uid); }
|
||||
Q_INVOKABLE bool isRightHand(unsigned int uid) { return DependencyManager::get<PointerManager>()->isRightHand(uid); }
|
||||
Q_INVOKABLE bool isMouse(unsigned int uid) { return DependencyManager::get<PointerManager>()->isMouse(uid); }
|
||||
|
||||
signals:
|
||||
void triggerBegin(const QUuid& id, const PointerEvent& pointerEvent);
|
||||
void triggerContinue(const QUuid& id, const PointerEvent& pointerEvent);
|
||||
|
|
|
@ -51,3 +51,15 @@ void RayPickScriptingInterface::setIgnoreItems(uint32_t uid, const QScriptValue&
|
|||
void RayPickScriptingInterface::setIncludeItems(uint32_t uid, const QScriptValue& includeItems) {
|
||||
DependencyManager::get<PickManager>()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
|
||||
}
|
||||
|
||||
bool RayPickScriptingInterface::isLeftHand(unsigned int uid) {
|
||||
return DependencyManager::get<PickManager>()->isLeftHand(uid);
|
||||
}
|
||||
|
||||
bool RayPickScriptingInterface::isRightHand(unsigned int uid) {
|
||||
return DependencyManager::get<PickManager>()->isRightHand(uid);
|
||||
}
|
||||
|
||||
bool RayPickScriptingInterface::isMouse(unsigned int uid) {
|
||||
return DependencyManager::get<PickManager>()->isMouse(uid);
|
||||
}
|
|
@ -36,7 +36,7 @@ class RayPickScriptingInterface : public QObject, public Dependency {
|
|||
Q_PROPERTY(unsigned int INTERSECTED_HUD READ INTERSECTED_HUD CONSTANT)
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public slots:
|
||||
public:
|
||||
Q_INVOKABLE unsigned int createRayPick(const QVariant& properties);
|
||||
Q_INVOKABLE void enableRayPick(unsigned int uid);
|
||||
Q_INVOKABLE void disableRayPick(unsigned int uid);
|
||||
|
@ -47,6 +47,11 @@ public slots:
|
|||
Q_INVOKABLE void setIgnoreItems(unsigned int uid, const QScriptValue& ignoreEntities);
|
||||
Q_INVOKABLE void setIncludeItems(unsigned int uid, const QScriptValue& includeEntities);
|
||||
|
||||
Q_INVOKABLE bool isLeftHand(unsigned int uid);
|
||||
Q_INVOKABLE bool isRightHand(unsigned int uid);
|
||||
Q_INVOKABLE bool isMouse(unsigned int uid);
|
||||
|
||||
public slots:
|
||||
static unsigned int PICK_NOTHING() { return PickScriptingInterface::PICK_NOTHING(); }
|
||||
static unsigned int PICK_ENTITIES() { return PickScriptingInterface::PICK_ENTITIES(); }
|
||||
static unsigned int PICK_OVERLAYS() { return PickScriptingInterface::PICK_OVERLAYS(); }
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <QtNetwork/QNetworkReply>
|
||||
#include <commerce/Ledger.h>
|
||||
|
||||
#include <pointers/PointerManager.h>
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
@ -79,8 +81,6 @@ ContextOverlayInterface::ContextOverlayInterface() {
|
|||
_challengeOwnershipTimeoutTimer.setSingleShot(true);
|
||||
}
|
||||
|
||||
static const uint32_t MOUSE_HW_ID = 0;
|
||||
static const uint32_t LEFT_HAND_HW_ID = 1;
|
||||
static const xColor CONTEXT_OVERLAY_COLOR = { 255, 255, 255 };
|
||||
static const float CONTEXT_OVERLAY_INSIDE_DISTANCE = 1.0f; // in meters
|
||||
static const float CONTEXT_OVERLAY_SIZE = 0.09f; // in meters, same x and y dims
|
||||
|
@ -100,7 +100,7 @@ void ContextOverlayInterface::setEnabled(bool enabled) {
|
|||
bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) {
|
||||
if (_enabled && event.getButton() == PointerEvent::SecondaryButton) {
|
||||
if (contextOverlayFilterPassed(entityItemID)) {
|
||||
if (event.getID() == MOUSE_HW_ID) {
|
||||
if (event.getID() == PointerManager::MOUSE_POINTER_ID || DependencyManager::get<PointerManager>()->isMouse(event.getID())) {
|
||||
enableEntityHighlight(entityItemID);
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID&
|
|||
glm::vec3 normal;
|
||||
boundingBox.findRayIntersection(cameraPosition, direction, distance, face, normal);
|
||||
float offsetAngle = -CONTEXT_OVERLAY_OFFSET_ANGLE;
|
||||
if (event.getID() == LEFT_HAND_HW_ID) {
|
||||
if (DependencyManager::get<PointerManager>()->isLeftHand(event.getID())) {
|
||||
offsetAngle *= -1.0f;
|
||||
}
|
||||
contextOverlayPosition = cameraPosition +
|
||||
|
@ -253,13 +253,15 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveOverlay(const OverlayID&
|
|||
}
|
||||
|
||||
void ContextOverlayInterface::contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event) {
|
||||
if (contextOverlayFilterPassed(entityID) && _enabled && event.getID() != MOUSE_HW_ID) {
|
||||
bool isMouse = event.getID() == PointerManager::MOUSE_POINTER_ID || DependencyManager::get<PointerManager>()->isMouse(event.getID());
|
||||
if (contextOverlayFilterPassed(entityID) && _enabled && !isMouse) {
|
||||
enableEntityHighlight(entityID);
|
||||
}
|
||||
}
|
||||
|
||||
void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemID& entityID, const PointerEvent& event) {
|
||||
if (_currentEntityWithContextOverlay != entityID && _enabled && event.getID() != MOUSE_HW_ID) {
|
||||
bool isMouse = event.getID() == PointerManager::MOUSE_POINTER_ID || DependencyManager::get<PointerManager>()->isMouse(event.getID());
|
||||
if (_currentEntityWithContextOverlay != entityID && _enabled && !isMouse) {
|
||||
disableEntityHighlight(entityID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -784,8 +784,6 @@ float Overlays::height() {
|
|||
return offscreenUi->getWindow()->size().height();
|
||||
}
|
||||
|
||||
static const uint32_t MOUSE_POINTER_ID = 0;
|
||||
|
||||
static glm::vec2 projectOntoOverlayXYPlane(glm::vec3 position, glm::quat rotation, glm::vec2 dimensions, const PickRay& pickRay,
|
||||
const RayToOverlayIntersectionResult& rayPickResult) {
|
||||
|
||||
|
@ -846,7 +844,7 @@ PointerEvent Overlays::calculateOverlayPointerEvent(OverlayID overlayID, PickRay
|
|||
|
||||
glm::vec2 pos2D = projectOntoOverlayXYPlane(position, rotation, dimensions, ray, rayPickResult);
|
||||
|
||||
PointerEvent pointerEvent(eventType, MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal,
|
||||
PointerEvent pointerEvent(eventType, PointerManager::MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal,
|
||||
ray.direction, toPointerButton(*event), toPointerButtons(*event), event->modifiers());
|
||||
|
||||
return pointerEvent;
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
#include "ui/Snapshot.h"
|
||||
#include "SoundCache.h"
|
||||
|
||||
#include "raypick/PointerScriptingInterface.h"
|
||||
|
||||
static const float DPI = 30.47f;
|
||||
static const float INCHES_TO_METERS = 1.0f / 39.3701f;
|
||||
static const float METERS_TO_INCHES = 39.3701f;
|
||||
|
@ -216,6 +218,7 @@ void Web3DOverlay::setupQmlSurface() {
|
|||
_webSurface->getSurfaceContext()->setContextProperty("Settings", SettingsScriptingInterface::getInstance());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Render", AbstractViewStateInterface::instance()->getRenderEngine()->getConfiguration().get());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Controller", DependencyManager::get<controller::ScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Pointers", DependencyManager::get<PointerScriptingInterface>().data());
|
||||
_webSurface->getSurfaceContext()->setContextProperty("Web3DOverlay", this);
|
||||
|
||||
_webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../");
|
||||
|
@ -245,18 +248,12 @@ void Web3DOverlay::onResizeWebSurface() {
|
|||
_webSurface->resize(QSize(_resolution.x, _resolution.y));
|
||||
}
|
||||
|
||||
const int INVALID_DEVICE_ID = -1;
|
||||
|
||||
Q_INVOKABLE int Web3DOverlay::deviceIdByTouchPoint(qreal x, qreal y) {
|
||||
auto mapped = _webSurface->getRootItem()->mapFromGlobal(QPoint(x, y));
|
||||
|
||||
for (auto pair : _activeTouchPoints) {
|
||||
if (mapped.x() == (int)pair.second.pos().x() && mapped.y() == (int)pair.second.pos().y()) {
|
||||
return pair.first;
|
||||
}
|
||||
unsigned int Web3DOverlay::deviceIdByTouchPoint(qreal x, qreal y) {
|
||||
if (_webSurface) {
|
||||
return _webSurface->deviceIdByTouchPoint(x, y);
|
||||
} else {
|
||||
return PointerEvent::INVALID_POINTER_ID;
|
||||
}
|
||||
|
||||
return INVALID_DEVICE_ID;
|
||||
}
|
||||
|
||||
void Web3DOverlay::render(RenderArgs* args) {
|
||||
|
@ -341,13 +338,15 @@ void Web3DOverlay::setProxyWindow(QWindow* proxyWindow) {
|
|||
}
|
||||
|
||||
void Web3DOverlay::hoverLeaveOverlay(const PointerEvent& event) {
|
||||
if ((_pressed || (!_activeTouchPoints.empty() && _touchBeginAccepted)) && event.sendReleaseOnHoverLeave()) {
|
||||
if (_inputMode == Mouse) {
|
||||
PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(),
|
||||
event.getButton(), event.getButtons(), event.getKeyboardModifiers());
|
||||
handlePointerEvent(endEvent);
|
||||
// QML onReleased is only triggered if a click has happened first. We need to send this "fake" mouse move event to properly trigger an onExited.
|
||||
PointerEvent endMoveEvent(PointerEvent::Move, event.getID());
|
||||
handlePointerEvent(endMoveEvent);
|
||||
} else if (_webSurface) {
|
||||
_webSurface->hoverEndEvent(event, _touchDevice);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,93 +365,11 @@ void Web3DOverlay::handlePointerEvent(const PointerEvent& event) {
|
|||
}
|
||||
|
||||
void Web3DOverlay::handlePointerEventAsTouch(const PointerEvent& event) {
|
||||
if (!_webSurface) {
|
||||
return;
|
||||
if (_webSurface) {
|
||||
PointerEvent webEvent = event;
|
||||
webEvent.setPos2D(event.getPos2D() * (METERS_TO_INCHES * _dpi));
|
||||
_webSurface->handlePointerEvent(webEvent, _touchDevice);
|
||||
}
|
||||
|
||||
glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _dpi);
|
||||
QPointF windowPoint(windowPos.x, windowPos.y);
|
||||
|
||||
Qt::TouchPointState state = Qt::TouchPointStationary;
|
||||
if (event.getType() == PointerEvent::Press && event.getButton() == PointerEvent::PrimaryButton) {
|
||||
state = Qt::TouchPointPressed;
|
||||
} else if (event.getType() == PointerEvent::Release) {
|
||||
state = Qt::TouchPointReleased;
|
||||
} else if (_activeTouchPoints.count(event.getID()) && windowPoint != _activeTouchPoints[event.getID()].pos()) {
|
||||
state = Qt::TouchPointMoved;
|
||||
}
|
||||
|
||||
QEvent::Type touchType = QEvent::TouchUpdate;
|
||||
if (_activeTouchPoints.empty()) {
|
||||
// If the first active touch point is being created, send a begin
|
||||
touchType = QEvent::TouchBegin;
|
||||
} if (state == Qt::TouchPointReleased && _activeTouchPoints.size() == 1 && _activeTouchPoints.count(event.getID())) {
|
||||
// If the last active touch point is being released, send an end
|
||||
touchType = QEvent::TouchEnd;
|
||||
}
|
||||
|
||||
{
|
||||
QTouchEvent::TouchPoint point;
|
||||
point.setId(event.getID());
|
||||
point.setState(state);
|
||||
point.setPos(windowPoint);
|
||||
point.setScreenPos(windowPoint);
|
||||
_activeTouchPoints[event.getID()] = point;
|
||||
}
|
||||
|
||||
QTouchEvent touchEvent(touchType, &_touchDevice, event.getKeyboardModifiers());
|
||||
{
|
||||
QList<QTouchEvent::TouchPoint> touchPoints;
|
||||
Qt::TouchPointStates touchPointStates;
|
||||
for (const auto& entry : _activeTouchPoints) {
|
||||
touchPointStates |= entry.second.state();
|
||||
touchPoints.push_back(entry.second);
|
||||
}
|
||||
|
||||
touchEvent.setWindow(_webSurface->getWindow());
|
||||
touchEvent.setDevice(&_touchDevice);
|
||||
touchEvent.setTarget(_webSurface->getRootItem());
|
||||
touchEvent.setTouchPoints(touchPoints);
|
||||
touchEvent.setTouchPointStates(touchPointStates);
|
||||
}
|
||||
|
||||
// Send mouse events to the Web surface so that HTML dialog elements work with mouse press and hover.
|
||||
//
|
||||
// In Qt 5.9 mouse events must be sent before touch events to make sure some QtQuick components will
|
||||
// receive mouse events
|
||||
Qt::MouseButton button = Qt::NoButton;
|
||||
Qt::MouseButtons buttons = Qt::NoButton;
|
||||
if (event.getButton() == PointerEvent::PrimaryButton) {
|
||||
button = Qt::LeftButton;
|
||||
}
|
||||
if (event.getButtons() & PointerEvent::PrimaryButton) {
|
||||
buttons |= Qt::LeftButton;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||
if (event.getType() == PointerEvent::Move) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, event.getKeyboardModifiers());
|
||||
QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (touchType == QEvent::TouchBegin) {
|
||||
_touchBeginAccepted = QCoreApplication::sendEvent(_webSurface->getWindow(), &touchEvent);
|
||||
} else if (_touchBeginAccepted) {
|
||||
QCoreApplication::sendEvent(_webSurface->getWindow(), &touchEvent);
|
||||
}
|
||||
|
||||
// If this was a release event, remove the point from the active touch points
|
||||
if (state == Qt::TouchPointReleased) {
|
||||
_activeTouchPoints.erase(event.getID());
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 9, 0)
|
||||
if (event.getType() == PointerEvent::Move) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, event.getKeyboardModifiers());
|
||||
QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Web3DOverlay::handlePointerEventAsMouse(const PointerEvent& event) {
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
void destroyWebSurface();
|
||||
void onResizeWebSurface();
|
||||
|
||||
Q_INVOKABLE int deviceIdByTouchPoint(qreal x, qreal y);
|
||||
Q_INVOKABLE unsigned int deviceIdByTouchPoint(qreal x, qreal y);
|
||||
|
||||
public slots:
|
||||
void emitScriptEvent(const QVariant& scriptMessage);
|
||||
|
@ -98,8 +98,6 @@ private:
|
|||
bool _showKeyboardFocusHighlight{ true };
|
||||
|
||||
bool _pressed{ false };
|
||||
bool _touchBeginAccepted { false };
|
||||
std::map<uint32_t, QTouchEvent::TouchPoint> _activeTouchPoints;
|
||||
QTouchDevice _touchDevice;
|
||||
|
||||
uint8_t _desiredMaxFPS { 10 };
|
||||
|
|
|
@ -571,8 +571,6 @@ static PointerEvent::Button toPointerButton(const QMouseEvent& event) {
|
|||
}
|
||||
}
|
||||
|
||||
static const uint32_t MOUSE_POINTER_ID = 0;
|
||||
|
||||
void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
|
||||
// If we don't have a tree, or we're in the process of shutting down, then don't
|
||||
// process these events.
|
||||
|
@ -593,7 +591,7 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Press, MOUSE_POINTER_ID,
|
||||
PointerEvent pointerEvent(PointerEvent::Press, PointerManager::MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
|
@ -625,7 +623,7 @@ void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) {
|
|||
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
||||
if (rayPickResult.intersects && rayPickResult.entity) {
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Press, MOUSE_POINTER_ID,
|
||||
PointerEvent pointerEvent(PointerEvent::Press, PointerManager::MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event), Qt::NoModifier);
|
||||
|
@ -657,7 +655,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
|||
//qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID;
|
||||
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Release, MOUSE_POINTER_ID,
|
||||
PointerEvent pointerEvent(PointerEvent::Release, PointerManager::MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
|
@ -673,7 +671,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
|||
// we're releasing the button, then this is considered a clickReleaseOn event
|
||||
if (!_currentClickingOnEntityID.isInvalidID()) {
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Release, MOUSE_POINTER_ID,
|
||||
PointerEvent pointerEvent(PointerEvent::Release, PointerManager::MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
|
@ -699,7 +697,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
||||
if (rayPickResult.intersects && rayPickResult.entity) {
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID,
|
||||
PointerEvent pointerEvent(PointerEvent::Move, PointerManager::MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
|
@ -713,7 +711,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
// then we need to send the hover leave.
|
||||
if (!_currentHoverOverEntityID.isInvalidID() && rayPickResult.entityID != _currentHoverOverEntityID) {
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID,
|
||||
PointerEvent pointerEvent(PointerEvent::Move, PointerManager::MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
|
@ -744,7 +742,7 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
|
|||
// send the hover leave for our previous entity
|
||||
if (!_currentHoverOverEntityID.isInvalidID()) {
|
||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||
PointerEvent pointerEvent(PointerEvent::Move, MOUSE_POINTER_ID,
|
||||
PointerEvent pointerEvent(PointerEvent::Move, PointerManager::MOUSE_POINTER_ID,
|
||||
pos2D, rayPickResult.intersection,
|
||||
rayPickResult.surfaceNormal, ray.direction,
|
||||
toPointerButton(*event), toPointerButtons(*event),
|
||||
|
|
|
@ -182,6 +182,10 @@ public:
|
|||
void setIgnoreItems(const QVector<QUuid>& items);
|
||||
void setIncludeItems(const QVector<QUuid>& items);
|
||||
|
||||
virtual bool isLeftHand() const { return false; }
|
||||
virtual bool isRightHand() const { return false; }
|
||||
virtual bool isMouse() const { return false; }
|
||||
|
||||
private:
|
||||
PickFilter _filter;
|
||||
const float _maxDistance;
|
||||
|
|
|
@ -96,4 +96,28 @@ void PickManager::update() {
|
|||
|
||||
bool shouldPickHUD = _shouldPickHUDOperator();
|
||||
_rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], shouldPickHUD);
|
||||
}
|
||||
|
||||
bool PickManager::isLeftHand(unsigned int uid) {
|
||||
auto pick = findPick(uid);
|
||||
if (pick) {
|
||||
return pick->isLeftHand();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PickManager::isRightHand(unsigned int uid) {
|
||||
auto pick = findPick(uid);
|
||||
if (pick) {
|
||||
return pick->isRightHand();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PickManager::isMouse(unsigned int uid) {
|
||||
auto pick = findPick(uid);
|
||||
if (pick) {
|
||||
return pick->isMouse();
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -33,6 +33,10 @@ public:
|
|||
void setIgnoreItems(unsigned int uid, const QVector<QUuid>& ignore) const;
|
||||
void setIncludeItems(unsigned int uid, const QVector<QUuid>& include) const;
|
||||
|
||||
bool isLeftHand(unsigned int uid);
|
||||
bool isRightHand(unsigned int uid);
|
||||
bool isMouse(unsigned int uid);
|
||||
|
||||
void setShouldPickHUDOperator(std::function<bool()> shouldPickHUDOperator) { _shouldPickHUDOperator = shouldPickHUDOperator; }
|
||||
void setCalculatePos2DFromHUDOperator(std::function<glm::vec2(const glm::vec3&)> calculatePos2DFromHUDOperator) { _calculatePos2DFromHUDOperator = calculatePos2DFromHUDOperator; }
|
||||
glm::vec2 calculatePos2DFromHUD(const glm::vec3& intersection) { return _calculatePos2DFromHUDOperator(intersection); }
|
||||
|
|
|
@ -46,6 +46,18 @@ void Pointer::setIncludeItems(const QVector<QUuid>& includeItems) const {
|
|||
DependencyManager::get<PickManager>()->setIncludeItems(_pickUID, includeItems);
|
||||
}
|
||||
|
||||
bool Pointer::isLeftHand() const {
|
||||
return DependencyManager::get<PickManager>()->isLeftHand(_pickUID);
|
||||
}
|
||||
|
||||
bool Pointer::isRightHand() const {
|
||||
return DependencyManager::get<PickManager>()->isRightHand(_pickUID);
|
||||
}
|
||||
|
||||
bool Pointer::isMouse() const {
|
||||
return DependencyManager::get<PickManager>()->isMouse(_pickUID);
|
||||
}
|
||||
|
||||
void Pointer::update(unsigned int pointerID) {
|
||||
// This only needs to be a read lock because update won't change any of the properties that can be modified from scripts
|
||||
withReadLock([&] {
|
||||
|
|
|
@ -53,6 +53,10 @@ public:
|
|||
virtual void setIgnoreItems(const QVector<QUuid>& ignoreItems) const;
|
||||
virtual void setIncludeItems(const QVector<QUuid>& includeItems) const;
|
||||
|
||||
bool isLeftHand() const;
|
||||
bool isRightHand() const;
|
||||
bool isMouse() const;
|
||||
|
||||
// Pointers can choose to implement these
|
||||
virtual void setLength(float length) {}
|
||||
virtual void setLockEndUUID(const QUuid& objectID, bool isOverlay) {}
|
||||
|
|
|
@ -120,3 +120,27 @@ void PointerManager::setLockEndUUID(unsigned int uid, const QUuid& objectID, boo
|
|||
pointer->setLockEndUUID(objectID, isOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
bool PointerManager::isLeftHand(unsigned int uid) {
|
||||
auto pointer = find(uid);
|
||||
if (pointer) {
|
||||
return pointer->isLeftHand();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PointerManager::isRightHand(unsigned int uid) {
|
||||
auto pointer = find(uid);
|
||||
if (pointer) {
|
||||
return pointer->isRightHand();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PointerManager::isMouse(unsigned int uid) {
|
||||
auto pointer = find(uid);
|
||||
if (pointer) {
|
||||
return pointer->isMouse();
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -40,6 +40,10 @@ public:
|
|||
|
||||
void update();
|
||||
|
||||
bool isLeftHand(unsigned int uid);
|
||||
bool isRightHand(unsigned int uid);
|
||||
bool isMouse(unsigned int uid);
|
||||
|
||||
static const unsigned int MOUSE_POINTER_ID { PointerEvent::INVALID_POINTER_ID + 1 };
|
||||
|
||||
private:
|
||||
|
|
|
@ -927,6 +927,18 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even
|
|||
return false;
|
||||
}
|
||||
|
||||
unsigned int OffscreenQmlSurface::deviceIdByTouchPoint(qreal x, qreal y) {
|
||||
auto mapped = _rootItem->mapFromGlobal(QPoint(x, y));
|
||||
|
||||
for (auto pair : _activeTouchPoints) {
|
||||
if (mapped.x() == (int)pair.second.pos().x() && mapped.y() == (int)pair.second.pos().y()) {
|
||||
return pair.first;
|
||||
}
|
||||
}
|
||||
|
||||
return PointerEvent::INVALID_POINTER_ID;
|
||||
}
|
||||
|
||||
PointerEvent::EventType OffscreenQmlSurface::choosePointerEventType(QEvent::Type type) {
|
||||
switch (type) {
|
||||
case QEvent::MouseButtonDblClick:
|
||||
|
|
|
@ -100,6 +100,8 @@ public:
|
|||
|
||||
PointerEvent::EventType choosePointerEventType(QEvent::Type type);
|
||||
|
||||
unsigned int deviceIdByTouchPoint(qreal x, qreal y);
|
||||
|
||||
signals:
|
||||
void focusObjectChanged(QObject* newFocus);
|
||||
void focusTextChanged(bool focusText);
|
||||
|
|
Loading…
Reference in a new issue