From f664421fe07ddb4603cccbf36ba862fc44141d59 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 31 Oct 2018 17:44:20 -0700 Subject: [PATCH] addressing code review feedback --- interface/src/Menu.cpp | 2 +- .../src/raypick/PointerScriptingInterface.cpp | 10 +- interface/src/raypick/RayPick.cpp | 6 +- interface/src/raypick/StylusPick.cpp | 4 +- interface/src/raypick/StylusPick.h | 3 - interface/src/raypick/StylusPointer.cpp | 4 +- interface/src/ui/Keyboard.cpp | 262 +++++++++--------- interface/src/ui/Keyboard.h | 4 +- interface/src/ui/overlays/Overlays.cpp | 7 +- libraries/shared/src/RegisteredMetaTypes.h | 10 +- 10 files changed, 160 insertions(+), 152 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 2ca997a1fc..1fc1e0c033 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -356,7 +356,7 @@ Menu::Menu() { qApp->setHmdTabletBecomesToolbarSetting(action->isChecked()); }); - addCheckableActionToQMenuAndActionHash(uiOptionsMenu, MenuOption::Use3DKeyboard, 0, false); + addCheckableActionToQMenuAndActionHash(uiOptionsMenu, MenuOption::Use3DKeyboard, 0, true); // Developer > Render >>> MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render"); diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp index f0edb4d9ef..1893132917 100644 --- a/interface/src/raypick/PointerScriptingInterface.cpp +++ b/interface/src/raypick/PointerScriptingInterface.cpp @@ -56,8 +56,16 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType& * @property {boolean} [hover=false] If this pointer should generate hover events. * @property {boolean} [enabled=false] * @property {Vec3} [tipOffset] The specified offset of the from the joint index. - * @property {object} [model] Data to replace the default model url, positionOffset and rotationOffset. + * @property {Pointers.StylusPointerProperties.model} [model] Data to replace the default model url, positionOffset and rotationOffset. {@link Pointers.StylusPointerProperties.model} */ + /**jsdoc + * properties defining stylus pick model that can be included to {@link Pointers.StylusPointerProperties} + * @typedef {object} Pointers.StylusPointerProperties.model + * @property {string} [url] url to the model + * @property {Vec3} [dimensions] the dimensions of the model + * @property {Vec3} [positionOffset] the position offset of the model from the parent joint index + * @property {Vec3} [rotationOffset] the rotation offset of the model from the parent joint index + */ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties) const { QVariantMap propertyMap = properties.toMap(); diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index b6adba4a12..a48d858504 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -10,7 +10,6 @@ #include "Application.h" #include "EntityScriptingInterface.h" #include "ui/overlays/Overlays.h" -#include "ui/Keyboard.h" #include "avatar/AvatarManager.h" #include "scripting/HMDScriptingInterface.h" #include "DependencyManager.h" @@ -41,12 +40,9 @@ PickResultPointer RayPick::getEntityIntersection(const PickRay& pick) { PickResultPointer RayPick::getOverlayIntersection(const PickRay& pick) { bool precisionPicking = !(getFilter().doesPickCoarse() || DependencyManager::get()->getForceCoarsePicking()); - auto keyboard = DependencyManager::get(); - QVector ignoreItems = keyboard->getKeysID(); - ignoreItems.append(getIgnoreItemsAs()); RayToOverlayIntersectionResult overlayRes = qApp->getOverlays().findRayIntersectionVector(pick, precisionPicking, - getIncludeItemsAs(), ignoreItems, !getFilter().doesPickInvisible(), !getFilter().doesPickNonCollidable()); + getIncludeItemsAs(), getIgnoreItemsAs(), !getFilter().doesPickInvisible(), !getFilter().doesPickNonCollidable()); if (overlayRes.intersects) { return std::make_shared(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, pick, overlayRes.surfaceNormal, overlayRes.extraInfo); } else { diff --git a/interface/src/raypick/StylusPick.cpp b/interface/src/raypick/StylusPick.cpp index 0416563272..0a76180be8 100644 --- a/interface/src/raypick/StylusPick.cpp +++ b/interface/src/raypick/StylusPick.cpp @@ -61,7 +61,7 @@ bool StylusPickResult::checkOrFilterAgainstMaxDistance(float maxDistance) { } StylusPick::StylusPick(Side side, const PickFilter& filter, float maxDistance, bool enabled, const glm::vec3& tipOffset) : - Pick(StylusTip(side), filter, maxDistance, enabled), _tipOffset(tipOffset) + Pick(StylusTip(side, tipOffset), filter, maxDistance, enabled) { } @@ -127,7 +127,7 @@ StylusTip StylusPick::getMathematicalPick() const { if (qApp->getPreferAvatarFingerOverStylus()) { result = getFingerWorldLocation(_mathPick.side); } else { - result = getControllerWorldLocation(_mathPick.side, _tipOffset); + result = getControllerWorldLocation(_mathPick.side, _mathPick.tipOffset); } return result; } diff --git a/interface/src/raypick/StylusPick.h b/interface/src/raypick/StylusPick.h index 3e0ee452e9..14821c0ce5 100644 --- a/interface/src/raypick/StylusPick.h +++ b/interface/src/raypick/StylusPick.h @@ -73,9 +73,6 @@ public: bool isMouse() const override { return false; } static float WEB_STYLUS_LENGTH; - -private: - glm::vec3 _tipOffset; }; #endif // hifi_StylusPick_h diff --git a/interface/src/raypick/StylusPointer.cpp b/interface/src/raypick/StylusPointer.cpp index caa3151cc5..5595c54b71 100644 --- a/interface/src/raypick/StylusPointer.cpp +++ b/interface/src/raypick/StylusPointer.cpp @@ -45,7 +45,7 @@ StylusPointer::~StylusPointer() { OverlayID StylusPointer::buildStylusOverlay(const QVariantMap& properties) { QVariantMap overlayProperties; - // TODO: make these configurable per pointe + QString modelUrl = DEFAULT_STYLUS_MODEL_URL; if (properties["model"].isValid()) { @@ -55,7 +55,7 @@ OverlayID StylusPointer::buildStylusOverlay(const QVariantMap& properties) { modelUrl = modelData["url"].toString(); } } - + // TODO: make these configurable per pointer overlayProperties["name"] = "stylus"; overlayProperties["url"] = modelUrl; overlayProperties["loadPriority"] = 10.0f; diff --git a/interface/src/ui/Keyboard.cpp b/interface/src/ui/Keyboard.cpp index 677d384a17..c00ea007f0 100644 --- a/interface/src/ui/Keyboard.cpp +++ b/interface/src/ui/Keyboard.cpp @@ -316,8 +316,8 @@ void Keyboard::scaleKeyboard(float sensorToWorldScale) { } for (auto& keyboardLayer: _keyboardLayers) { - for (auto& key: keyboardLayer) { - key.scaleKey(sensorToWorldScale); + for (auto iter = keyboardLayer.begin(); iter != keyboardLayer.end(); iter++) { + iter.value().scaleKey(sensorToWorldScale); } } @@ -354,8 +354,9 @@ void Keyboard::raiseKeyboard(bool raise) const { return; } Overlays& overlays = qApp->getOverlays(); - for (const auto& key: _keyboardLayers[_layerIndex]) { - auto base3DOverlay = std::dynamic_pointer_cast(overlays.getOverlay(key.getID())); + const auto& keyboardLayer = _keyboardLayers[_layerIndex]; + for (auto iter = keyboardLayer.begin(); iter != keyboardLayer.end(); iter++) { + auto base3DOverlay = std::dynamic_pointer_cast(overlays.getOverlay(iter.key())); if (base3DOverlay) { base3DOverlay->setVisible(raise); } @@ -419,87 +420,90 @@ void Keyboard::handleTriggerBegin(const OverlayID& overlayID, const PointerEvent auto pointerID = event.getID(); auto buttonType = event.getButton(); - for (auto index = _keyboardLayers[_layerIndex].begin(); index != _keyboardLayers[_layerIndex].end(); index++) { - Key& key = *index; - if (key.getID() == overlayID && (pointerID == _leftHandStylus || pointerID == _rightHandStylus) && - buttonType == PointerEvent::PrimaryButton) { + if ((pointerID != _leftHandStylus && pointerID != _rightHandStylus) || buttonType != PointerEvent::PrimaryButton) { + return; + } + auto& keyboardLayer = _keyboardLayers[_layerIndex]; + auto search = keyboardLayer.find(overlayID); - if (key.timerFinished()) { + if (search == keyboardLayer.end()) { + return; + } - auto handIndex = (pointerID == _leftHandStylus) ? controller::Hand::LEFT : controller::Hand::RIGHT; - auto userInputMapper = DependencyManager::get(); - userInputMapper->triggerHapticPulse(PULSE_STRENGTH, PULSE_DURATION, handIndex); + Key& key = search.value(); - Overlays& overlays = qApp->getOverlays(); - auto base3DOverlay = std::dynamic_pointer_cast(overlays.getOverlay(overlayID)); + if (key.timerFinished()) { - glm::vec3 keyWorldPosition; - if (base3DOverlay) { - keyWorldPosition = base3DOverlay->getWorldPosition(); - } + auto handIndex = (pointerID == _leftHandStylus) ? controller::Hand::LEFT : controller::Hand::RIGHT; + auto userInputMapper = DependencyManager::get(); + userInputMapper->triggerHapticPulse(PULSE_STRENGTH, PULSE_DURATION, handIndex); - AudioInjectorOptions audioOptions; - audioOptions.localOnly = true; - audioOptions.position = keyWorldPosition; - audioOptions.volume = 0.4f; + Overlays& overlays = qApp->getOverlays(); + auto base3DOverlay = std::dynamic_pointer_cast(overlays.getOverlay(overlayID)); - AudioInjector::playSound(_keySound->getByteArray(), audioOptions); - - int scanCode = key.getScanCode(_capsEnabled); - QString keyString = key.getKeyString(_capsEnabled); - - auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); - - switch (key.getKeyType()) { - case Key::Type::CLOSE: - setRaised(false); - tablet->unfocus(); - return; - - case Key::Type::CAPS: - _capsEnabled = !_capsEnabled; - switchToLayer(key.getSwitchToLayerIndex()); - return; - case Key::Type::LAYER: - _capsEnabled = false; - switchToLayer(key.getSwitchToLayerIndex()); - return; - case Key::Type::BACKSPACE: - scanCode = Qt::Key_Backspace; - keyString = "\x08"; - _typedCharacters = _typedCharacters.left(_typedCharacters.length() -1); - updateTextDisplay(); - break; - case Key::Type::ENTER: - scanCode = Qt::Key_Return; - keyString = "\x0d"; - _typedCharacters.clear(); - updateTextDisplay(); - break; - case Key::Type::CHARACTER: - if (keyString != " ") { - _typedCharacters.push_back((_password ? "*" : keyString)); - } else { - _typedCharacters.clear(); - } - updateTextDisplay(); - break; - - default: - break; - } - - QKeyEvent* pressEvent = new QKeyEvent(QEvent::KeyPress, scanCode, Qt::NoModifier, keyString); - QKeyEvent* releaseEvent = new QKeyEvent(QEvent::KeyRelease, scanCode, Qt::NoModifier, keyString); - QCoreApplication::postEvent(QCoreApplication::instance(), pressEvent); - QCoreApplication::postEvent(QCoreApplication::instance(), releaseEvent); - - key.startTimer(KEY_PRESS_TIMEOUT_MS); - } - - break; + glm::vec3 keyWorldPosition; + if (base3DOverlay) { + keyWorldPosition = base3DOverlay->getWorldPosition(); } + + AudioInjectorOptions audioOptions; + audioOptions.localOnly = true; + audioOptions.position = keyWorldPosition; + audioOptions.volume = 0.4f; + + AudioInjector::playSound(_keySound->getByteArray(), audioOptions); + + int scanCode = key.getScanCode(_capsEnabled); + QString keyString = key.getKeyString(_capsEnabled); + + auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); + + switch (key.getKeyType()) { + case Key::Type::CLOSE: + setRaised(false); + tablet->unfocus(); + return; + + case Key::Type::CAPS: + _capsEnabled = !_capsEnabled; + switchToLayer(key.getSwitchToLayerIndex()); + return; + case Key::Type::LAYER: + _capsEnabled = false; + switchToLayer(key.getSwitchToLayerIndex()); + return; + case Key::Type::BACKSPACE: + scanCode = Qt::Key_Backspace; + keyString = "\x08"; + _typedCharacters = _typedCharacters.left(_typedCharacters.length() -1); + updateTextDisplay(); + break; + case Key::Type::ENTER: + scanCode = Qt::Key_Return; + keyString = "\x0d"; + _typedCharacters.clear(); + updateTextDisplay(); + break; + case Key::Type::CHARACTER: + if (keyString != " ") { + _typedCharacters.push_back((_password ? "*" : keyString)); + } else { + _typedCharacters.clear(); + } + updateTextDisplay(); + break; + + default: + break; + } + + QKeyEvent* pressEvent = new QKeyEvent(QEvent::KeyPress, scanCode, Qt::NoModifier, keyString); + QKeyEvent* releaseEvent = new QKeyEvent(QEvent::KeyRelease, scanCode, Qt::NoModifier, keyString); + QCoreApplication::postEvent(QCoreApplication::instance(), pressEvent); + QCoreApplication::postEvent(QCoreApplication::instance(), releaseEvent); + + key.startTimer(KEY_PRESS_TIMEOUT_MS); } } @@ -509,27 +513,29 @@ void Keyboard::handleTriggerEnd(const OverlayID& overlayID, const PointerEvent& } auto pointerID = event.getID(); - - for (auto index = _keyboardLayers[_layerIndex].begin(); index != _keyboardLayers[_layerIndex].end(); index++) { - Key& key = *index; - - if (key.getID() == overlayID && (pointerID == _leftHandStylus || pointerID == _rightHandStylus)) { - Overlays& overlays = qApp->getOverlays(); - - auto base3DOverlay = std::dynamic_pointer_cast(overlays.getOverlay(overlayID)); - - if (base3DOverlay) { - base3DOverlay->setLocalPosition(key.getCurrentLocalPosition()); - } - - key.setIsPressed(false); - if (key.timerFinished()) { - key.startTimer(KEY_PRESS_TIMEOUT_MS); - } - break; - } + if (pointerID != _leftHandStylus && pointerID != _rightHandStylus) { + return; } + auto& keyboardLayer = _keyboardLayers[_layerIndex]; + auto search = keyboardLayer.find(overlayID); + + if (search == keyboardLayer.end()) { + return; + } + + Key& key = search.value();; + Overlays& overlays = qApp->getOverlays(); + auto base3DOverlay = std::dynamic_pointer_cast(overlays.getOverlay(overlayID)); + + if (base3DOverlay) { + base3DOverlay->setLocalPosition(key.getCurrentLocalPosition()); + } + + key.setIsPressed(false); + if (key.timerFinished()) { + key.startTimer(KEY_PRESS_TIMEOUT_MS); + } } void Keyboard::handleTriggerContinue(const OverlayID& overlayID, const PointerEvent& event) { @@ -539,44 +545,40 @@ void Keyboard::handleTriggerContinue(const OverlayID& overlayID, const PointerEv auto pointerID = event.getID(); - for (auto index = _keyboardLayers[_layerIndex].begin(); index != _keyboardLayers[_layerIndex].end(); index++) { - Key& key = *index; + if (pointerID != _leftHandStylus && pointerID != _rightHandStylus) { + return; + } - if (key.getID() == overlayID && (pointerID == _leftHandStylus || pointerID == _rightHandStylus)) { - Overlays& overlays = qApp->getOverlays(); + auto& keyboardLayer = _keyboardLayers[_layerIndex]; + auto search = keyboardLayer.find(overlayID); - if (!key.isPressed()) { - auto pointerManager = DependencyManager::get(); - auto pickResult = pointerManager->getPrevPickResult(pointerID); + if (search == keyboardLayer.end()) { + return; + } - auto base3DOverlay = std::dynamic_pointer_cast(overlays.getOverlay(overlayID)); + Key& key = search.value(); + Overlays& overlays = qApp->getOverlays(); - if (base3DOverlay) { - auto pickResultVariant = pickResult->toVariantMap(); - auto stylusTipVariant = pickResultVariant["stylusTip"]; - auto stylusTipPositionVariant = stylusTipVariant.toMap()["position"]; - glm::vec3 stylusTipPosition = vec3FromVariant(stylusTipPositionVariant); + if (!key.isPressed()) { + auto base3DOverlay = std::dynamic_pointer_cast(overlays.getOverlay(overlayID)); - glm::quat overlayOrientation = base3DOverlay->getWorldOrientation(); - glm::vec3 overlayPosition = base3DOverlay->getWorldPosition(); + if (base3DOverlay) { + auto pointerManager = DependencyManager::get(); + auto pickResult = pointerManager->getPrevPickResult(pointerID); + auto pickResultVariant = pickResult->toVariantMap(); - glm::mat4 overlayWorldMat = createMatFromQuatAndPos(overlayOrientation, overlayPosition); - glm::mat4 overlayWorldToLocalMat = glm::inverse(overlayWorldMat); + float distance = pickResultVariant["distance"].toFloat(); - glm::vec3 stylusTipInOverlaySpace = transformPoint(overlayWorldToLocalMat, stylusTipPosition); - - static const float PENATRATION_THRESHOLD = 0.025f; - if (stylusTipInOverlaySpace.z < PENATRATION_THRESHOLD) { - static const float Z_OFFSET = 0.002f; - glm::vec3 overlayYAxis = overlayOrientation * Z_AXIS; - glm::vec3 overlayYOffset = overlayYAxis * Z_OFFSET; - glm::vec3 localPosition = key.getCurrentLocalPosition() - overlayYOffset; - base3DOverlay->setLocalPosition(localPosition); - key.setIsPressed(true); - } - } + static const float PENATRATION_THRESHOLD = 0.025f; + if (distance < PENATRATION_THRESHOLD) { + static const float Z_OFFSET = 0.002f; + glm::quat overlayOrientation = base3DOverlay->getWorldOrientation(); + glm::vec3 overlayYAxis = overlayOrientation * Z_AXIS; + glm::vec3 overlayYOffset = overlayYAxis * Z_OFFSET; + glm::vec3 localPosition = key.getCurrentLocalPosition() - overlayYOffset; + base3DOverlay->setLocalPosition(localPosition); + key.setIsPressed(true); } - break; } } } @@ -666,7 +668,7 @@ void Keyboard::loadKeyboardFile(const QString& keyboardFile) { for (int keyboardLayerIndex = 0; keyboardLayerIndex < keyboardLayerCount; keyboardLayerIndex++) { const QJsonValue& keyboardLayer = keyboardLayers[keyboardLayerIndex].toArray(); - std::vector keyboardLayerKeys; + QHash keyboardLayerKeys; foreach (const QJsonValue& keyboardKeyValue, keyboardLayer.toArray()) { QVariantMap textureMap; @@ -718,7 +720,7 @@ void Keyboard::loadKeyboardFile(const QString& keyboardFile) { includeItems.append(key.getID()); _itemsToIgnore.append(key.getID()); - keyboardLayerKeys.push_back(key); + keyboardLayerKeys.insert(overlayID, key); } _keyboardLayers.push_back(keyboardLayerKeys); @@ -774,8 +776,8 @@ void Keyboard::clearKeyboardKeys() { Overlays& overlays = qApp->getOverlays(); for (const auto& keyboardLayer: _keyboardLayers) { - for (const Key& key: keyboardLayer) { - overlays.deleteOverlay(key.getID()); + for (auto iter = keyboardLayer.begin(); iter != keyboardLayer.end(); iter++) { + overlays.deleteOverlay(iter.key()); } } diff --git a/interface/src/ui/Keyboard.h b/interface/src/ui/Keyboard.h index 662a51c2da..2a29a12961 100644 --- a/interface/src/ui/Keyboard.h +++ b/interface/src/ui/Keyboard.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -43,7 +44,6 @@ public: ENTER }; - static Key::Type getKeyTypeFromString(const QString& keyTypeString); OverlayID getID() const { return _keyID; } @@ -146,7 +146,7 @@ private: mutable ReadWriteLockable _ignoreItemsLock; QVector _itemsToIgnore; - std::vector> _keyboardLayers; + std::vector> _keyboardLayers; }; #endif diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 35228c6247..7593e12e07 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -583,7 +583,7 @@ ParabolaToOverlayIntersectionResult Overlays::findParabolaIntersectionVector(con bool visibleOnly, bool collidableOnly) { float bestDistance = std::numeric_limits::max(); bool bestIsFront = false; - + const QVector keyboardKeysToDiscard = DependencyManager::get()->getKeysID(); QMutexLocker locker(&_mutex); ParabolaToOverlayIntersectionResult result; QMapIterator i(_overlaysWorld); @@ -593,7 +593,8 @@ ParabolaToOverlayIntersectionResult Overlays::findParabolaIntersectionVector(con auto thisOverlay = std::dynamic_pointer_cast(i.value()); if ((overlaysToDiscard.size() > 0 && overlaysToDiscard.contains(thisID)) || - (overlaysToInclude.size() > 0 && !overlaysToInclude.contains(thisID))) { + (overlaysToInclude.size() > 0 && !overlaysToInclude.contains(thisID)) || + (keyboardKeysToDiscard.size() > 0 && keyboardKeysToDiscard.contains(thisID))) { continue; } @@ -1061,7 +1062,7 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { i.next(); OverlayID thisID = i.key(); auto overlay = std::dynamic_pointer_cast(i.value()); - // FIXME: this ignores overlays with ignorePickIntersection == true, which seems wrong + if (overlay && overlay->getVisible() && overlay->isLoaded()) { // get AABox in frame of overlay glm::vec3 dimensions = overlay->getDimensions(); diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 64a874f63d..18c1339223 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -269,6 +269,7 @@ void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay); * * @typedef {object} StylusTip * @property {number} side - The hand the tip is attached to: 0 for left, 1 for right. + * @property {Vec3} tipOffset - the position offset of the stylus tip. * @property {Vec3} position - The position of the stylus tip. * @property {Quat} orientation - The orientation of the stylus tip. * @property {Vec3} velocity - The velocity of the stylus tip. @@ -276,12 +277,14 @@ void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay); class StylusTip : public MathPick { public: StylusTip() : position(NAN), velocity(NAN) {} - StylusTip(const bilateral::Side& side, const glm::vec3& position = Vectors::ZERO, const glm::quat& orientation = Quaternions::IDENTITY, const glm::vec3& velocity = Vectors::ZERO) : - side(side), position(position), orientation(orientation), velocity(velocity) {} + StylusTip(const bilateral::Side& side, const glm::vec3& tipOffset = Vectors::ZERO ,const glm::vec3& position = Vectors::ZERO, + const glm::quat& orientation = Quaternions::IDENTITY, const glm::vec3& velocity = Vectors::ZERO) : + side(side), tipOffset(tipOffset), position(position), orientation(orientation), velocity(velocity) {} StylusTip(const QVariantMap& pickVariant) : side(bilateral::Side(pickVariant["side"].toInt())), position(vec3FromVariant(pickVariant["position"])), orientation(quatFromVariant(pickVariant["orientation"])), velocity(vec3FromVariant(pickVariant["velocity"])) {} bilateral::Side side { bilateral::Side::Invalid }; + glm::vec3 tipOffset; glm::vec3 position; glm::quat orientation; glm::vec3 velocity; @@ -289,12 +292,13 @@ public: operator bool() const override { return side != bilateral::Side::Invalid; } bool operator==(const StylusTip& other) const { - return (side == other.side && position == other.position && orientation == other.orientation && velocity == other.velocity); + return (side == other.side && tipOffset == other.tipOffset && position == other.position && orientation == other.orientation && velocity == other.velocity); } QVariantMap toVariantMap() const override { QVariantMap stylusTip; stylusTip["side"] = (int)side; + stylusTip["tipOffset"] = vec3toVariant(tipOffset); stylusTip["position"] = vec3toVariant(position); stylusTip["orientation"] = quatToVariant(orientation); stylusTip["velocity"] = vec3toVariant(velocity);