From 3f99e70af0698cd21ecb8d925a3b8821e53e977c Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 16 Oct 2017 14:20:31 -0700 Subject: [PATCH] C++ cleanup for pointers / picking --- interface/CMakeLists.txt | 1 + interface/src/raypick/JointRayPick.cpp | 1 - interface/src/raypick/JointRayPick.h | 2 +- interface/src/raypick/LaserPointer.cpp | 126 ++++++-------- interface/src/raypick/LaserPointer.h | 22 +-- interface/src/raypick/LaserPointerManager.cpp | 160 +++++++---------- interface/src/raypick/LaserPointerManager.h | 34 ++-- .../LaserPointerScriptingInterface.cpp | 19 +- .../raypick/LaserPointerScriptingInterface.h | 30 ++-- interface/src/raypick/MouseRayPick.h | 2 +- interface/src/raypick/RayPick.cpp | 62 ------- interface/src/raypick/RayPickManager.cpp | 162 ++++++++---------- interface/src/raypick/RayPickManager.h | 35 ++-- .../src/raypick/RayPickScriptingInterface.cpp | 34 +--- .../src/raypick/RayPickScriptingInterface.h | 29 ++-- libraries/pointers/CMakeLists.txt | 5 + .../pointers/src/pointers/PointerManager.cpp | 1 + .../pointers/src/pointers/PointerManager.h | 29 ++++ .../pointers/src/pointers/rays/RayPick.cpp | 75 ++++++++ .../pointers/src/pointers/rays}/RayPick.h | 103 ++++++----- .../src/pointers/rays}/StaticRayPick.cpp | 3 - .../src/pointers/rays}/StaticRayPick.h | 3 - 22 files changed, 454 insertions(+), 484 deletions(-) delete mode 100644 interface/src/raypick/RayPick.cpp create mode 100644 libraries/pointers/CMakeLists.txt create mode 100644 libraries/pointers/src/pointers/PointerManager.cpp create mode 100644 libraries/pointers/src/pointers/PointerManager.h create mode 100644 libraries/pointers/src/pointers/rays/RayPick.cpp rename {interface/src/raypick => libraries/pointers/src/pointers/rays}/RayPick.h (63%) rename {interface/src/raypick => libraries/pointers/src/pointers/rays}/StaticRayPick.cpp (92%) rename {interface/src/raypick => libraries/pointers/src/pointers/rays}/StaticRayPick.h (92%) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index b16ad58431..764e5ef201 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -198,6 +198,7 @@ endif() # link required hifi libraries link_hifi_libraries( shared octree ktx gpu gl gpu-gl procedural model render + pointers recording fbx networking model-networking entities avatars trackers audio audio-client animation script-engine physics render-utils entities-renderer avatars-renderer ui auto-updater midi diff --git a/interface/src/raypick/JointRayPick.cpp b/interface/src/raypick/JointRayPick.cpp index b4f0dde687..cf3f380ca0 100644 --- a/interface/src/raypick/JointRayPick.cpp +++ b/interface/src/raypick/JointRayPick.cpp @@ -10,7 +10,6 @@ // #include "JointRayPick.h" -#include "DependencyManager.h" #include "avatar/AvatarManager.h" JointRayPick::JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) : diff --git a/interface/src/raypick/JointRayPick.h b/interface/src/raypick/JointRayPick.h index 3cd622fbbe..e3e5670e20 100644 --- a/interface/src/raypick/JointRayPick.h +++ b/interface/src/raypick/JointRayPick.h @@ -11,7 +11,7 @@ #ifndef hifi_JointRayPick_h #define hifi_JointRayPick_h -#include "RayPick.h" +#include class JointRayPick : public RayPick { diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 0e0f13cd6c..7fa5eaed5f 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -11,8 +11,8 @@ #include "LaserPointer.h" #include "Application.h" -#include "ui/overlays/Overlay.h" #include "avatar/AvatarManager.h" +#include "RayPickScriptingInterface.h" LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) : @@ -21,9 +21,10 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende _defaultRenderStates(defaultRenderStates), _faceAvatar(faceAvatar), _centerEndY(centerEndY), - _lockEnd(lockEnd) + _lockEnd(lockEnd), + _rayPickUID(DependencyManager::get()->createRayPick(rayProps)) { - _rayPickUID = DependencyManager::get()->createRayPick(rayProps); + for (auto& state : _renderStates) { if (!enabled || state.first != _currentRenderState) { @@ -38,7 +39,7 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende } LaserPointer::~LaserPointer() { - DependencyManager::get()->removeRayPick(_rayPickUID); + qApp->getRayPickManager().removeRayPick(_rayPickUID); for (auto& renderState : _renderStates) { renderState.second.deleteOverlays(); @@ -49,43 +50,47 @@ LaserPointer::~LaserPointer() { } void LaserPointer::enable() { - QWriteLocker lock(getLock()); - DependencyManager::get()->enableRayPick(_rayPickUID); - _renderingEnabled = true; + qApp->getRayPickManager().enableRayPick(_rayPickUID); + withWriteLock([&] { + _renderingEnabled = true; + }); } void LaserPointer::disable() { - QWriteLocker lock(getLock()); - DependencyManager::get()->disableRayPick(_rayPickUID); + qApp->getRayPickManager().disableRayPick(_rayPickUID); _renderingEnabled = false; - if (!_currentRenderState.empty()) { - if (_renderStates.find(_currentRenderState) != _renderStates.end()) { - disableRenderState(_renderStates[_currentRenderState]); + withWriteLock([&] { + if (!_currentRenderState.empty()) { + if (_renderStates.find(_currentRenderState) != _renderStates.end()) { + disableRenderState(_renderStates[_currentRenderState]); + } + if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { + disableRenderState(_defaultRenderStates[_currentRenderState].second); + } } - if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { - disableRenderState(_defaultRenderStates[_currentRenderState].second); - } - } + }); } void LaserPointer::setRenderState(const std::string& state) { - QWriteLocker lock(getLock()); - if (!_currentRenderState.empty() && state != _currentRenderState) { - if (_renderStates.find(_currentRenderState) != _renderStates.end()) { - disableRenderState(_renderStates[_currentRenderState]); + withWriteLock([&] { + if (!_currentRenderState.empty() && state != _currentRenderState) { + if (_renderStates.find(_currentRenderState) != _renderStates.end()) { + disableRenderState(_renderStates[_currentRenderState]); + } + if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { + disableRenderState(_defaultRenderStates[_currentRenderState].second); + } } - if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { - disableRenderState(_defaultRenderStates[_currentRenderState].second); - } - } - _currentRenderState = state; + _currentRenderState = state; + }); } void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { - QWriteLocker lock(getLock()); - updateRenderStateOverlay(_renderStates[state].getStartID(), startProps); - updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps); - updateRenderStateOverlay(_renderStates[state].getEndID(), endProps); + withWriteLock([&] { + updateRenderStateOverlay(_renderStates[state].getStartID(), startProps); + updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps); + updateRenderStateOverlay(_renderStates[state].getEndID(), endProps); + }); } void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& props) { @@ -97,7 +102,6 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& } const RayPickResult LaserPointer::getPrevRayPickResult() { - QReadLocker lock(getLock()); return DependencyManager::get()->getPrevRayPickResult(_rayPickUID); } @@ -193,65 +197,41 @@ void LaserPointer::disableRenderState(const RenderState& renderState) { void LaserPointer::update() { // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts - QReadLocker lock(getLock()); - RayPickResult prevRayPickResult = DependencyManager::get()->getPrevRayPickResult(_rayPickUID); - if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && + withReadLock([&] { + RayPickResult prevRayPickResult = qApp->getRayPickManager().getPrevRayPickResult(_rayPickUID); + if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && (prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) { - float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult.distance; - updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false); - disableRenderState(_defaultRenderStates[_currentRenderState].second); - } else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { - disableRenderState(_renderStates[_currentRenderState]); - updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), prevRayPickResult.searchRay, true); - } else if (!_currentRenderState.empty()) { - disableRenderState(_renderStates[_currentRenderState]); - disableRenderState(_defaultRenderStates[_currentRenderState].second); - } + float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult.distance; + updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false); + disableRenderState(_defaultRenderStates[_currentRenderState].second); + } else if (_renderingEnabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { + disableRenderState(_renderStates[_currentRenderState]); + updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), prevRayPickResult.searchRay, true); + } else if (!_currentRenderState.empty()) { + disableRenderState(_renderStates[_currentRenderState]); + disableRenderState(_defaultRenderStates[_currentRenderState].second); + } + }); } void LaserPointer::setPrecisionPicking(const bool precisionPicking) { - QWriteLocker lock(getLock()); - DependencyManager::get()->setPrecisionPicking(_rayPickUID, precisionPicking); + qApp->getRayPickManager().setPrecisionPicking(_rayPickUID, precisionPicking); } void LaserPointer::setLaserLength(const float laserLength) { - QWriteLocker lock(getLock()); _laserLength = laserLength; } void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) { - QWriteLocker lock(getLock()); _objectLockEnd = std::pair(objectID, isOverlay); } -void LaserPointer::setIgnoreEntities(const QScriptValue& ignoreEntities) { - QWriteLocker lock(getLock()); - DependencyManager::get()->setIgnoreEntities(_rayPickUID, ignoreEntities); +void LaserPointer::setIgnoreItems(const QVector& ignoreItems) const { + qApp->getRayPickManager().setIgnoreItems(_rayPickUID, ignoreItems); } -void LaserPointer::setIncludeEntities(const QScriptValue& includeEntities) { - QWriteLocker lock(getLock()); - DependencyManager::get()->setIncludeEntities(_rayPickUID, includeEntities); -} - -void LaserPointer::setIgnoreOverlays(const QScriptValue& ignoreOverlays) { - QWriteLocker lock(getLock()); - DependencyManager::get()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); -} - -void LaserPointer::setIncludeOverlays(const QScriptValue& includeOverlays) { - QWriteLocker lock(getLock()); - DependencyManager::get()->setIncludeOverlays(_rayPickUID, includeOverlays); -} - -void LaserPointer::setIgnoreAvatars(const QScriptValue& ignoreAvatars) { - QWriteLocker lock(getLock()); - DependencyManager::get()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); -} - -void LaserPointer::setIncludeAvatars(const QScriptValue& includeAvatars) { - QWriteLocker lock(getLock()); - DependencyManager::get()->setIncludeAvatars(_rayPickUID, includeAvatars); +void LaserPointer::setIncludeItems(const QVector& includeItems) const { + qApp->getRayPickManager().setIncludeItems(_rayPickUID, includeItems); } RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) : diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 01dfe01cfd..20ea824f50 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -12,10 +12,12 @@ #define hifi_LaserPointer_h #include -#include "glm/glm.hpp" +#include #include -#include "raypick/RayPickScriptingInterface.h" +#include + +#include "ui/overlays/Overlay.h" class RayPickResult; @@ -44,9 +46,10 @@ private: }; -class LaserPointer { +class LaserPointer : public ReadWriteLockable { public: + using Pointer = std::shared_ptr; typedef std::unordered_map RenderStateMap; typedef std::unordered_map> DefaultRenderStateMap; @@ -68,14 +71,8 @@ public: void setLaserLength(const float laserLength); void setLockEndUUID(QUuid objectID, const bool isOverlay); - void setIgnoreEntities(const QScriptValue& ignoreEntities); - void setIncludeEntities(const QScriptValue& includeEntities); - void setIgnoreOverlays(const QScriptValue& ignoreOverlays); - void setIncludeOverlays(const QScriptValue& includeOverlays); - void setIgnoreAvatars(const QScriptValue& ignoreAvatars); - void setIncludeAvatars(const QScriptValue& includeAvatars); - - QReadWriteLock* getLock() { return &_lock; } + void setIgnoreItems(const QVector& ignoreItems) const; + void setIncludeItems(const QVector& includeItems) const; void update(); @@ -90,8 +87,7 @@ private: bool _lockEnd; std::pair _objectLockEnd { std::pair(QUuid(), false)}; - QUuid _rayPickUID; - QReadWriteLock _lock; + const QUuid _rayPickUID; void updateRenderStateOverlay(const OverlayID& id, const QVariant& props); void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState); diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index 8615a96c3f..f65a8a1a84 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -12,138 +12,110 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) { + QUuid result; std::shared_ptr laserPointer = std::make_shared(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled); if (!laserPointer->getRayUID().isNull()) { - QWriteLocker containsLock(&_containsLock); - QUuid id = QUuid::createUuid(); - _laserPointers[id] = laserPointer; - return id; + result = QUuid::createUuid(); + withWriteLock([&] { _laserPointers[result] = laserPointer; }); } - return QUuid(); + return result; } -void LaserPointerManager::removeLaserPointer(const QUuid uid) { - QWriteLocker lock(&_containsLock); - _laserPointers.remove(uid); + +LaserPointer::Pointer LaserPointerManager::find(const QUuid& uid) const { + return resultWithReadLock([&] { + auto itr = _laserPointers.find(uid); + if (itr != _laserPointers.end()) { + return *itr; + } + return LaserPointer::Pointer(); + }); } -void LaserPointerManager::enableLaserPointer(const QUuid uid) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->enable(); + +void LaserPointerManager::removeLaserPointer(const QUuid& uid) { + withWriteLock([&] { + _laserPointers.remove(uid); + }); +} + +void LaserPointerManager::enableLaserPointer(const QUuid& uid) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->enable(); } } -void LaserPointerManager::disableLaserPointer(const QUuid uid) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->disable(); +void LaserPointerManager::disableLaserPointer(const QUuid& uid) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->disable(); } } -void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setRenderState(renderState); +void LaserPointerManager::setRenderState(const QUuid& uid, const std::string& renderState) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->setRenderState(renderState); } } -void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->editRenderState(state, startProps, pathProps, endProps); +void LaserPointerManager::editRenderState(const QUuid& uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->editRenderState(state, startProps, pathProps, endProps); } } -const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - return laserPointer.value()->getPrevRayPickResult(); +const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid& uid) const { + auto laserPointer = find(uid); + if (laserPointer) { + return laserPointer->getPrevRayPickResult(); } return RayPickResult(); } void LaserPointerManager::update() { - QReadLocker lock(&_containsLock); - for (QUuid& uid : _laserPointers.keys()) { - auto laserPointer = _laserPointers.find(uid); - laserPointer.value()->update(); + auto cachedLaserPointers = resultWithReadLock>>([&] { + return _laserPointers.values(); + }); + + for (const auto& laserPointer : cachedLaserPointers) { + laserPointer->update(); } } -void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setPrecisionPicking(precisionPicking); +void LaserPointerManager::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->setPrecisionPicking(precisionPicking); } } -void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setLaserLength(laserLength); +void LaserPointerManager::setLaserLength(const QUuid& uid, const float laserLength) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->setLaserLength(laserLength); } } -void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setIgnoreEntities(ignoreEntities); +void LaserPointerManager::setIgnoreItems(const QUuid& uid, const QVector& ignoreEntities) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->setIgnoreItems(ignoreEntities); } } -void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setIncludeEntities(includeEntities); +void LaserPointerManager::setIncludeItems(const QUuid& uid, const QVector& includeEntities) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->setIncludeItems(includeEntities); } } -void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setIgnoreOverlays(ignoreOverlays); - } -} - -void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setIncludeOverlays(includeOverlays); - } -} - -void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setIgnoreAvatars(ignoreAvatars); - } -} - -void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setIncludeAvatars(includeAvatars); - } -} - -void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) { - QReadLocker lock(&_containsLock); - auto laserPointer = _laserPointers.find(uid); - if (laserPointer != _laserPointers.end()) { - laserPointer.value()->setLockEndUUID(objectID, isOverlay); +void LaserPointerManager::setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const { + auto laserPointer = find(uid); + if (laserPointer) { + laserPointer->setLockEndUUID(objectID, isOverlay); } } diff --git a/interface/src/raypick/LaserPointerManager.h b/interface/src/raypick/LaserPointerManager.h index b841877578..a4689cf16d 100644 --- a/interface/src/raypick/LaserPointerManager.h +++ b/interface/src/raypick/LaserPointerManager.h @@ -14,39 +14,37 @@ #include #include +#include + #include "LaserPointer.h" class RayPickResult; -class LaserPointerManager { + +class LaserPointerManager : protected ReadWriteLockable { public: QUuid createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled); - void removeLaserPointer(const QUuid uid); - void enableLaserPointer(const QUuid uid); - void disableLaserPointer(const QUuid uid); - void setRenderState(QUuid uid, const std::string& renderState); - void editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps); - const RayPickResult getPrevRayPickResult(const QUuid uid); + void removeLaserPointer(const QUuid& uid); + void enableLaserPointer(const QUuid& uid) const; + void disableLaserPointer(const QUuid& uid) const; + void setRenderState(const QUuid& uid, const std::string& renderState) const; + void editRenderState(const QUuid& uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const; + const RayPickResult getPrevRayPickResult(const QUuid& uid) const; - void setPrecisionPicking(QUuid uid, const bool precisionPicking); - void setLaserLength(QUuid uid, const float laserLength); - void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities); - void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities); - void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays); - void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays); - void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars); - void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars); + void setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const; + void setLaserLength(const QUuid& uid, const float laserLength) const; + void setIgnoreItems(const QUuid& uid, const QVector& ignoreEntities) const; + void setIncludeItems(const QUuid& uid, const QVector& includeEntities) const; - void setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay); + void setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const; void update(); private: + LaserPointer::Pointer find(const QUuid& uid) const; QHash> _laserPointers; - QReadWriteLock _containsLock; - }; #endif // hifi_LaserPointerManager_h diff --git a/interface/src/raypick/LaserPointerScriptingInterface.cpp b/interface/src/raypick/LaserPointerScriptingInterface.cpp index d5e435f490..96839160fa 100644 --- a/interface/src/raypick/LaserPointerScriptingInterface.cpp +++ b/interface/src/raypick/LaserPointerScriptingInterface.cpp @@ -11,10 +11,19 @@ #include "LaserPointerScriptingInterface.h" -#include -#include "GLMHelpers.h" +#include -QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) { +#include +#include + +void LaserPointerScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) const { + qApp->getLaserPointerManager().setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); +} +void LaserPointerScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) const { + qApp->getLaserPointerManager().setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems)); +} + +QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) const { QVariantMap propertyMap = properties.toMap(); bool faceAvatar = false; @@ -69,7 +78,7 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled); } -void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& renderState, const QVariant& properties) { +void LaserPointerScriptingInterface::editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const { QVariantMap propMap = properties.toMap(); QVariant startProps; @@ -90,7 +99,7 @@ void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& r qApp->getLaserPointerManager().editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps); } -const RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) { +RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) { QUuid startID; if (propMap["start"].isValid()) { QVariantMap startMap = propMap["start"].toMap(); diff --git a/interface/src/raypick/LaserPointerScriptingInterface.h b/interface/src/raypick/LaserPointerScriptingInterface.h index 2f6da87b5f..19262e6e5d 100644 --- a/interface/src/raypick/LaserPointerScriptingInterface.h +++ b/interface/src/raypick/LaserPointerScriptingInterface.h @@ -22,27 +22,23 @@ class LaserPointerScriptingInterface : public QObject, public Dependency { SINGLETON_DEPENDENCY public slots: - Q_INVOKABLE QUuid createLaserPointer(const QVariant& properties); - Q_INVOKABLE void enableLaserPointer(QUuid uid) { qApp->getLaserPointerManager().enableLaserPointer(uid); } - Q_INVOKABLE void disableLaserPointer(QUuid uid) { qApp->getLaserPointerManager().disableLaserPointer(uid); } - Q_INVOKABLE void removeLaserPointer(QUuid uid) { qApp->getLaserPointerManager().removeLaserPointer(uid); } - Q_INVOKABLE void editRenderState(QUuid uid, const QString& renderState, const QVariant& properties); - Q_INVOKABLE void setRenderState(QUuid uid, const QString& renderState) { qApp->getLaserPointerManager().setRenderState(uid, renderState.toStdString()); } - Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid) { return qApp->getLaserPointerManager().getPrevRayPickResult(uid); } + Q_INVOKABLE QUuid createLaserPointer(const QVariant& properties) const; + Q_INVOKABLE void enableLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().enableLaserPointer(uid); } + Q_INVOKABLE void disableLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().disableLaserPointer(uid); } + Q_INVOKABLE void removeLaserPointer(const QUuid& uid) const { qApp->getLaserPointerManager().removeLaserPointer(uid); } + Q_INVOKABLE void editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const; + Q_INVOKABLE void setRenderState(const QUuid& uid, const QString& renderState) const { qApp->getLaserPointerManager().setRenderState(uid, renderState.toStdString()); } + Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid) const { return qApp->getLaserPointerManager().getPrevRayPickResult(uid); } - Q_INVOKABLE void setPrecisionPicking(QUuid uid, const bool precisionPicking) { qApp->getLaserPointerManager().setPrecisionPicking(uid, precisionPicking); } - Q_INVOKABLE void setLaserLength(QUuid uid, const float laserLength) { qApp->getLaserPointerManager().setLaserLength(uid, laserLength); } - Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { qApp->getLaserPointerManager().setIgnoreEntities(uid, ignoreEntities); } - Q_INVOKABLE void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { qApp->getLaserPointerManager().setIncludeEntities(uid, includeEntities); } - Q_INVOKABLE void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { qApp->getLaserPointerManager().setIgnoreOverlays(uid, ignoreOverlays); } - Q_INVOKABLE void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { qApp->getLaserPointerManager().setIncludeOverlays(uid, includeOverlays); } - Q_INVOKABLE void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { qApp->getLaserPointerManager().setIgnoreAvatars(uid, ignoreAvatars); } - Q_INVOKABLE void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { qApp->getLaserPointerManager().setIncludeAvatars(uid, includeAvatars); } + Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { qApp->getLaserPointerManager().setPrecisionPicking(uid, precisionPicking); } + Q_INVOKABLE void setLaserLength(const QUuid& uid, float laserLength) const { qApp->getLaserPointerManager().setLaserLength(uid, laserLength); } + Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities) const; + Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities) const; - Q_INVOKABLE void setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); } + Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); } private: - const RenderState buildRenderState(const QVariantMap& propMap); + static RenderState buildRenderState(const QVariantMap& propMap); }; diff --git a/interface/src/raypick/MouseRayPick.h b/interface/src/raypick/MouseRayPick.h index 848a5de336..47f9404f3a 100644 --- a/interface/src/raypick/MouseRayPick.h +++ b/interface/src/raypick/MouseRayPick.h @@ -11,7 +11,7 @@ #ifndef hifi_MouseRayPick_h #define hifi_MouseRayPick_h -#include "RayPick.h" +#include class MouseRayPick : public RayPick { diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp deleted file mode 100644 index a5b1299210..0000000000 --- a/interface/src/raypick/RayPick.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// RayPick.cpp -// interface/src/raypick -// -// Created by Sam Gondelman 7/11/2017 -// Copyright 2017 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 "RayPick.h" - -RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) : - _filter(filter), - _maxDistance(maxDistance), - _enabled(enabled) -{ -} -void RayPick::enable() { - QWriteLocker lock(getLock()); - _enabled = true; -} - -void RayPick::disable() { - QWriteLocker lock(getLock()); - _enabled = false; -} - -const RayPickResult& RayPick::getPrevRayPickResult() { - QReadLocker lock(getLock()); - return _prevResult; -} - -void RayPick::setIgnoreEntities(const QScriptValue& ignoreEntities) { - QWriteLocker lock(getLock()); - _ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities); -} - -void RayPick::setIncludeEntities(const QScriptValue& includeEntities) { - QWriteLocker lock(getLock()); - _includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities); -} - -void RayPick::setIgnoreOverlays(const QScriptValue& ignoreOverlays) { - QWriteLocker lock(getLock()); - _ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays); -} - -void RayPick::setIncludeOverlays(const QScriptValue& includeOverlays) { - QWriteLocker lock(getLock()); - _includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays); -} - -void RayPick::setIgnoreAvatars(const QScriptValue& ignoreAvatars) { - QWriteLocker lock(getLock()); - _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); -} - -void RayPick::setIncludeAvatars(const QScriptValue& includeAvatars) { - QWriteLocker lock(getLock()); - _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); -} \ No newline at end of file diff --git a/interface/src/raypick/RayPickManager.cpp b/interface/src/raypick/RayPickManager.cpp index 1728ecd01a..f3425a2b28 100644 --- a/interface/src/raypick/RayPickManager.cpp +++ b/interface/src/raypick/RayPickManager.cpp @@ -10,6 +10,8 @@ // #include "RayPickManager.h" +#include + #include "Application.h" #include "EntityScriptingInterface.h" #include "ui/overlays/Overlays.h" @@ -18,7 +20,6 @@ #include "DependencyManager.h" #include "JointRayPick.h" -#include "StaticRayPick.h" #include "MouseRayPick.h" bool RayPickManager::checkAndCompareCachedResults(QPair& ray, RayPickCache& cache, RayPickResult& res, const RayPickFilter::Flags& mask) { @@ -43,20 +44,26 @@ void RayPickManager::cacheResult(const bool intersects, const RayPickResult& res } void RayPickManager::update() { - QReadLocker lock(&_containsLock); RayPickCache results; - for (auto& uid : _rayPicks.keys()) { - std::shared_ptr rayPick = _rayPicks[uid]; - QWriteLocker lock(rayPick->getLock()); + QHash cachedRayPicks; + withReadLock([&] { + cachedRayPicks = _rayPicks; + }); + + for (const auto& uid : cachedRayPicks.keys()) { + std::shared_ptr rayPick = cachedRayPicks[uid]; if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) { continue; } - bool valid; - PickRay ray = rayPick->getPickRay(valid); + PickRay ray; - if (!valid) { - continue; + { + bool valid; + ray = rayPick->getPickRay(valid); + if (!valid) { + continue; + } } QPair rayKey = QPair(ray.origin, ray.direction); @@ -69,8 +76,8 @@ void RayPickManager::update() { bool nonCollidable = rayPick->getFilter().doesPickNonCollidable(); RayPickFilter::Flags entityMask = rayPick->getFilter().getEntityFlags(); if (!checkAndCompareCachedResults(rayKey, results, res, entityMask)) { - entityRes = DependencyManager::get()->findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCourse(), - rayPick->getIncludeEntites(), rayPick->getIgnoreEntites(), !invisible, !nonCollidable); + entityRes = DependencyManager::get()->findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCoarse(), + rayPick->getIncludeItemsAs(), rayPick->getIgnoreItemsAs(), !invisible, !nonCollidable); fromCache = false; } @@ -87,8 +94,8 @@ void RayPickManager::update() { bool nonCollidable = rayPick->getFilter().doesPickNonCollidable(); RayPickFilter::Flags overlayMask = rayPick->getFilter().getOverlayFlags(); if (!checkAndCompareCachedResults(rayKey, results, res, overlayMask)) { - overlayRes = qApp->getOverlays().findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCourse(), - rayPick->getIncludeOverlays(), rayPick->getIgnoreOverlays(), !invisible, !nonCollidable); + overlayRes = qApp->getOverlays().findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCoarse(), + rayPick->getIncludeItemsAs(), rayPick->getIgnoreItemsAs(), !invisible, !nonCollidable); fromCache = false; } @@ -101,7 +108,8 @@ void RayPickManager::update() { if (rayPick->getFilter().doesPickAvatars()) { RayPickFilter::Flags avatarMask = rayPick->getFilter().getAvatarFlags(); if (!checkAndCompareCachedResults(rayKey, results, res, avatarMask)) { - RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(ray, rayPick->getIncludeAvatars(), rayPick->getIgnoreAvatars()); + RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(ray, + rayPick->getIncludeItemsAs(), rayPick->getIgnoreItemsAs()); cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, ray), avatarMask, res, rayKey, results); } } @@ -123,109 +131,87 @@ void RayPickManager::update() { } } -QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled) { - QWriteLocker lock(&_containsLock); +QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, float maxDistance, bool enabled) { + auto newRayPick = std::make_shared(jointName, posOffset, dirOffset, filter, maxDistance, enabled); QUuid id = QUuid::createUuid(); - _rayPicks[id] = std::make_shared(jointName, posOffset, dirOffset, filter, maxDistance, enabled); + withWriteLock([&] { + _rayPicks[id] = newRayPick; + }); return id; } -QUuid RayPickManager::createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) { - QWriteLocker lock(&_containsLock); +QUuid RayPickManager::createRayPick(const RayPickFilter& filter, float maxDistance, bool enabled) { QUuid id = QUuid::createUuid(); - _rayPicks[id] = std::make_shared(filter, maxDistance, enabled); + auto newRayPick = std::make_shared(filter, maxDistance, enabled); + withWriteLock([&] { + _rayPicks[id] = newRayPick; + }); return id; } -QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled) { - QWriteLocker lock(&_containsLock); +QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, float maxDistance, bool enabled) { QUuid id = QUuid::createUuid(); - _rayPicks[id] = std::make_shared(position, direction, filter, maxDistance, enabled); + auto newRayPick = std::make_shared(position, direction, filter, maxDistance, enabled); + withWriteLock([&] { + _rayPicks[id] = newRayPick; + }); return id; } -void RayPickManager::removeRayPick(const QUuid uid) { - QWriteLocker lock(&_containsLock); - _rayPicks.remove(uid); +void RayPickManager::removeRayPick(const QUuid& uid) { + withWriteLock([&] { + _rayPicks.remove(uid); + }); } -void RayPickManager::enableRayPick(const QUuid uid) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->enable(); +RayPick::Pointer RayPickManager::findRayPick(const QUuid& uid) const { + return resultWithReadLock([&] { + if (_rayPicks.contains(uid)) { + return _rayPicks[uid]; + } + return RayPick::Pointer(); + }); +} + +void RayPickManager::enableRayPick(const QUuid& uid) const { + auto rayPick = findRayPick(uid); + if (rayPick) { + rayPick->enable(); } } -void RayPickManager::disableRayPick(const QUuid uid) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->disable(); +void RayPickManager::disableRayPick(const QUuid& uid) const { + auto rayPick = findRayPick(uid); + if (rayPick) { + rayPick->disable(); } } -const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - return rayPick.value()->getPrevRayPickResult(); +RayPickResult RayPickManager::getPrevRayPickResult(const QUuid& uid) const { + auto rayPick = findRayPick(uid); + if (rayPick) { + return rayPick->getPrevRayPickResult(); } return RayPickResult(); } -void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->setPrecisionPicking(precisionPicking); +void RayPickManager::setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { + auto rayPick = findRayPick(uid); + if (rayPick) { + rayPick->setPrecisionPicking(precisionPicking); } } -void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->setIgnoreEntities(ignoreEntities); +void RayPickManager::setIgnoreItems(const QUuid& uid, const QVector& ignore) const { + auto rayPick = findRayPick(uid); + if (rayPick) { + rayPick->setIgnoreItems(ignore); } } -void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->setIncludeEntities(includeEntities); +void RayPickManager::setIncludeItems(const QUuid& uid, const QVector& include) const { + auto rayPick = findRayPick(uid); + if (rayPick) { + rayPick->setIncludeItems(include); } } - -void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->setIgnoreOverlays(ignoreOverlays); - } -} - -void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->setIncludeOverlays(includeOverlays); - } -} - -void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->setIgnoreAvatars(ignoreAvatars); - } -} - -void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { - QReadLocker containsLock(&_containsLock); - auto rayPick = _rayPicks.find(uid); - if (rayPick != _rayPicks.end()) { - rayPick.value()->setIncludeAvatars(includeAvatars); - } -} \ No newline at end of file diff --git a/interface/src/raypick/RayPickManager.h b/interface/src/raypick/RayPickManager.h index 974022eb4d..8c6c28ceab 100644 --- a/interface/src/raypick/RayPickManager.h +++ b/interface/src/raypick/RayPickManager.h @@ -11,19 +11,20 @@ #ifndef hifi_RayPickManager_h #define hifi_RayPickManager_h -#include "RayPick.h" #include -#include - -#include "RegisteredMetaTypes.h" - #include #include +#include + +#include +#include + + class RayPickResult; -class RayPickManager { +class RayPickManager : protected ReadWriteLockable { public: void update(); @@ -31,22 +32,18 @@ public: QUuid createRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance, const bool enabled); QUuid createRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled); QUuid createRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled); - void removeRayPick(const QUuid uid); - void enableRayPick(const QUuid uid); - void disableRayPick(const QUuid uid); - const RayPickResult getPrevRayPickResult(const QUuid uid); + void removeRayPick(const QUuid& uid); + void enableRayPick(const QUuid& uid) const; + void disableRayPick(const QUuid& uid) const; + RayPickResult getPrevRayPickResult(const QUuid& uid) const; - void setPrecisionPicking(QUuid uid, const bool precisionPicking); - void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities); - void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities); - void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays); - void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays); - void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars); - void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars); + void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const; + void setIgnoreItems(const QUuid& uid, const QVector& ignore) const; + void setIncludeItems(const QUuid& uid, const QVector& include) const; private: - QHash> _rayPicks; - QReadWriteLock _containsLock; + RayPick::Pointer findRayPick(const QUuid& uid) const; + QHash _rayPicks; typedef QHash, std::unordered_map> RayPickCache; diff --git a/interface/src/raypick/RayPickScriptingInterface.cpp b/interface/src/raypick/RayPickScriptingInterface.cpp index cb2b3e4471..621ae9b738 100644 --- a/interface/src/raypick/RayPickScriptingInterface.cpp +++ b/interface/src/raypick/RayPickScriptingInterface.cpp @@ -66,46 +66,30 @@ QUuid RayPickScriptingInterface::createRayPick(const QVariant& properties) { return QUuid(); } -void RayPickScriptingInterface::enableRayPick(QUuid uid) { +void RayPickScriptingInterface::enableRayPick(const QUuid& uid) { qApp->getRayPickManager().enableRayPick(uid); } -void RayPickScriptingInterface::disableRayPick(QUuid uid) { +void RayPickScriptingInterface::disableRayPick(const QUuid& uid) { qApp->getRayPickManager().disableRayPick(uid); } -void RayPickScriptingInterface::removeRayPick(QUuid uid) { +void RayPickScriptingInterface::removeRayPick(const QUuid& uid) { qApp->getRayPickManager().removeRayPick(uid); } -RayPickResult RayPickScriptingInterface::getPrevRayPickResult(QUuid uid) { +RayPickResult RayPickScriptingInterface::getPrevRayPickResult(const QUuid& uid) { return qApp->getRayPickManager().getPrevRayPickResult(uid); } -void RayPickScriptingInterface::setPrecisionPicking(QUuid uid, const bool precisionPicking) { +void RayPickScriptingInterface::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) { qApp->getRayPickManager().setPrecisionPicking(uid, precisionPicking); } -void RayPickScriptingInterface::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { - qApp->getRayPickManager().setIgnoreEntities(uid, ignoreEntities); +void RayPickScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) { + qApp->getRayPickManager().setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); } -void RayPickScriptingInterface::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { - qApp->getRayPickManager().setIncludeEntities(uid, includeEntities); -} - -void RayPickScriptingInterface::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { - qApp->getRayPickManager().setIgnoreOverlays(uid, ignoreOverlays); -} - -void RayPickScriptingInterface::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { - qApp->getRayPickManager().setIncludeOverlays(uid, includeOverlays); -} - -void RayPickScriptingInterface::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { - qApp->getRayPickManager().setIgnoreAvatars(uid, ignoreAvatars); -} - -void RayPickScriptingInterface::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { - qApp->getRayPickManager().setIncludeAvatars(uid, includeAvatars); +void RayPickScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) { + qApp->getRayPickManager().setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems)); } diff --git a/interface/src/raypick/RayPickScriptingInterface.h b/interface/src/raypick/RayPickScriptingInterface.h index f7ed2e6fa6..59c5804d72 100644 --- a/interface/src/raypick/RayPickScriptingInterface.h +++ b/interface/src/raypick/RayPickScriptingInterface.h @@ -13,10 +13,9 @@ #include -#include "RegisteredMetaTypes.h" -#include "DependencyManager.h" - -#include "RayPick.h" +#include +#include +#include class RayPickScriptingInterface : public QObject, public Dependency { Q_OBJECT @@ -38,25 +37,21 @@ class RayPickScriptingInterface : public QObject, public Dependency { public slots: Q_INVOKABLE QUuid createRayPick(const QVariant& properties); - Q_INVOKABLE void enableRayPick(QUuid uid); - Q_INVOKABLE void disableRayPick(QUuid uid); - Q_INVOKABLE void removeRayPick(QUuid uid); - Q_INVOKABLE RayPickResult getPrevRayPickResult(QUuid uid); + Q_INVOKABLE void enableRayPick(const QUuid& uid); + Q_INVOKABLE void disableRayPick(const QUuid& uid); + Q_INVOKABLE void removeRayPick(const QUuid& uid); + Q_INVOKABLE RayPickResult getPrevRayPickResult(const QUuid& uid); - Q_INVOKABLE void setPrecisionPicking(QUuid uid, const bool precisionPicking); - Q_INVOKABLE void setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities); - Q_INVOKABLE void setIncludeEntities(QUuid uid, const QScriptValue& includeEntities); - Q_INVOKABLE void setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays); - Q_INVOKABLE void setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays); - Q_INVOKABLE void setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars); - Q_INVOKABLE void setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars); + Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, const bool precisionPicking); + Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities); + Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities); - unsigned int PICK_NOTHING() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_NOTHING); } + unsigned int PICK_NOTHING() { return 0; } unsigned int PICK_ENTITIES() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ENTITIES); } unsigned int PICK_OVERLAYS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_OVERLAYS); } unsigned int PICK_AVATARS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_AVATARS); } unsigned int PICK_HUD() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_HUD); } - unsigned int PICK_COURSE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_COURSE); } + unsigned int PICK_COARSE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_COARSE); } unsigned int PICK_INCLUDE_INVISIBLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); } unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); } unsigned int PICK_ALL_INTERSECTIONS() { return RayPickFilter::getBitMask(RayPickFilter::FlagBit::PICK_ALL_INTERSECTIONS); } diff --git a/libraries/pointers/CMakeLists.txt b/libraries/pointers/CMakeLists.txt new file mode 100644 index 0000000000..504484574c --- /dev/null +++ b/libraries/pointers/CMakeLists.txt @@ -0,0 +1,5 @@ +set(TARGET_NAME pointers) +setup_hifi_library() +GroupSources(src) +link_hifi_libraries(shared) + diff --git a/libraries/pointers/src/pointers/PointerManager.cpp b/libraries/pointers/src/pointers/PointerManager.cpp new file mode 100644 index 0000000000..dddc84279b --- /dev/null +++ b/libraries/pointers/src/pointers/PointerManager.cpp @@ -0,0 +1 @@ +#include "PointerManager.h" diff --git a/libraries/pointers/src/pointers/PointerManager.h b/libraries/pointers/src/pointers/PointerManager.h new file mode 100644 index 0000000000..0a045997c2 --- /dev/null +++ b/libraries/pointers/src/pointers/PointerManager.h @@ -0,0 +1,29 @@ +// +// Created by Bradley Austin Davis on 2017/10/16 +// Copyright 2013-2017 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_pointers_PointerManager_h +#define hifi_pointers_PointerManager_h + +#include +#include + +class PointerManager : public QObject, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY +public: + +signals: + void triggerBegin(const QUuid& id, const PointerEvent& pointerEvent); + void triggerContinue(const QUuid& id, const PointerEvent& pointerEvent); + void triggerEnd(const QUuid& id, const PointerEvent& pointerEvent); + + void hoverEnter(const QUuid& id, const PointerEvent& pointerEvent); + void hoverOver(const QUuid& id, const PointerEvent& pointerEvent); + void hoverLeave(const QUuid& id, const PointerEvent& pointerEvent); +}; + +#endif // hifi_RayPick_h diff --git a/libraries/pointers/src/pointers/rays/RayPick.cpp b/libraries/pointers/src/pointers/rays/RayPick.cpp new file mode 100644 index 0000000000..36756cdb79 --- /dev/null +++ b/libraries/pointers/src/pointers/rays/RayPick.cpp @@ -0,0 +1,75 @@ +// +// Created by Sam Gondelman 7/11/2017 +// Copyright 2017 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 "RayPick.h" + +const RayPickFilter RayPickFilter::NOTHING; + +RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) : + _filter(filter), + _maxDistance(maxDistance), + _enabled(enabled) +{ +} + +void RayPick::enable(bool enabled) { + withWriteLock([&] { + _enabled = enabled; + }); +} + +RayPickFilter RayPick::getFilter() const { + return resultWithReadLock([&] { + return _filter; + }); +} + +float RayPick::getMaxDistance() const { + return _maxDistance; +} + +bool RayPick::isEnabled() const { + return _enabled; +} + +void RayPick::setPrecisionPicking(bool precisionPicking) { + withWriteLock([&]{ + _filter.setFlag(RayPickFilter::PICK_COARSE, !precisionPicking); + }); +} + +void RayPick::setRayPickResult(const RayPickResult& rayPickResult) { + withWriteLock([&] { + _prevResult = rayPickResult; + }); +} + +QVector RayPick::getIgnoreItems() const { + return _ignoreItems; +} + +QVector RayPick::getIncludeItems() const { + return _includeItems; +} + +RayPickResult RayPick::getPrevRayPickResult() const { + return resultWithReadLock([&] { + return _prevResult; + }); +} + +void RayPick::setIgnoreItems(const QVector& ignoreItems) { + withWriteLock([&] { + _ignoreItems = ignoreItems; + }); +} + +void RayPick::setIncludeItems(const QVector& includeItems) { + withWriteLock([&] { + _includeItems = includeItems; + }); +} diff --git a/interface/src/raypick/RayPick.h b/libraries/pointers/src/pointers/rays/RayPick.h similarity index 63% rename from interface/src/raypick/RayPick.h rename to libraries/pointers/src/pointers/rays/RayPick.h index 6dacc084b4..3691ac9985 100644 --- a/interface/src/raypick/RayPick.h +++ b/libraries/pointers/src/pointers/rays/RayPick.h @@ -1,7 +1,4 @@ // -// RayPick.h -// interface/src/raypick -// // Created by Sam Gondelman 7/11/2017 // Copyright 2017 High Fidelity, Inc. // @@ -12,22 +9,22 @@ #define hifi_RayPick_h #include -#include "RegisteredMetaTypes.h" +#include -#include "EntityItemID.h" -#include "ui/overlays/Overlay.h" -#include +#include + +#include +#include class RayPickFilter { public: enum FlagBit { - PICK_NOTHING = 0, - PICK_ENTITIES, + PICK_ENTITIES = 0, PICK_OVERLAYS, PICK_AVATARS, PICK_HUD, - PICK_COURSE, // if not set, does precise intersection, otherwise, doesn't + PICK_COARSE, // if not set, does precise intersection, otherwise, doesn't PICK_INCLUDE_INVISIBLE, // if not set, will not intersect invisible elements, otherwise, intersects both visible and invisible elements PICK_INCLUDE_NONCOLLIDABLE, // if not set, will not intersect noncollidable elements, otherwise, intersects both collidable and noncollidable elements @@ -42,7 +39,7 @@ public: // The key is the Flags Flags _flags; - RayPickFilter() : _flags(getBitMask(PICK_NOTHING)) {} + RayPickFilter() {} RayPickFilter(const Flags& flags) : _flags(flags) {} bool operator== (const RayPickFilter& rhs) const { return _flags == rhs._flags; } @@ -50,13 +47,13 @@ public: void setFlag(FlagBit flag, bool value) { _flags[flag] = value; } - bool doesPickNothing() const { return _flags[PICK_NOTHING]; } + bool doesPickNothing() const { return _flags == NOTHING._flags; } bool doesPickEntities() const { return _flags[PICK_ENTITIES]; } bool doesPickOverlays() const { return _flags[PICK_OVERLAYS]; } bool doesPickAvatars() const { return _flags[PICK_AVATARS]; } bool doesPickHUD() const { return _flags[PICK_HUD]; } - bool doesPickCourse() const { return _flags[PICK_COURSE]; } + bool doesPickCoarse() const { return _flags[PICK_COARSE]; } bool doesPickInvisible() const { return _flags[PICK_INCLUDE_INVISIBLE]; } bool doesPickNonCollidable() const { return _flags[PICK_INCLUDE_NONCOLLIDABLE]; } @@ -71,8 +68,8 @@ public: if (doesPickNonCollidable()) { toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE); } - if (doesPickCourse()) { - toReturn |= getBitMask(PICK_COURSE); + if (doesPickCoarse()) { + toReturn |= getBitMask(PICK_COARSE); } return Flags(toReturn); } @@ -84,66 +81,84 @@ public: if (doesPickNonCollidable()) { toReturn |= getBitMask(PICK_INCLUDE_NONCOLLIDABLE); } - if (doesPickCourse()) { - toReturn |= getBitMask(PICK_COURSE); + if (doesPickCoarse()) { + toReturn |= getBitMask(PICK_COARSE); } return Flags(toReturn); } Flags getAvatarFlags() const { return Flags(getBitMask(PICK_AVATARS)); } Flags getHUDFlags() const { return Flags(getBitMask(PICK_HUD)); } - static unsigned int getBitMask(FlagBit bit) { return 1 << bit; } + static constexpr unsigned int getBitMask(FlagBit bit) { return 1 << bit; } + static const RayPickFilter NOTHING; }; -class RayPick { +class RayPick : protected ReadWriteLockable { public: + using Pointer = std::shared_ptr; + RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled); virtual const PickRay getPickRay(bool& valid) const = 0; - void enable(); - void disable(); + void enable(bool enabled = true); + void disable() { enable(false); } - const RayPickFilter& getFilter() { return _filter; } - float getMaxDistance() { return _maxDistance; } - bool isEnabled() { return _enabled; } - const RayPickResult& getPrevRayPickResult(); + RayPickFilter getFilter() const; + float getMaxDistance() const; + bool isEnabled() const; + RayPickResult getPrevRayPickResult() const; - void setPrecisionPicking(bool precisionPicking) { _filter.setFlag(RayPickFilter::PICK_COURSE, !precisionPicking); } + void setPrecisionPicking(bool precisionPicking); - void setRayPickResult(const RayPickResult& rayPickResult) { _prevResult = rayPickResult; } + void setRayPickResult(const RayPickResult& rayPickResult); - const QVector& getIgnoreEntites() { return _ignoreEntities; } - const QVector& getIncludeEntites() { return _includeEntities; } - const QVector& getIgnoreOverlays() { return _ignoreOverlays; } - const QVector& getIncludeOverlays() { return _includeOverlays; } - const QVector& getIgnoreAvatars() { return _ignoreAvatars; } - const QVector& getIncludeAvatars() { return _includeAvatars; } + QVector getIgnoreItems() const; + QVector getIncludeItems() const; + + template + QVector getIgnoreItemsAs() const { + QVector result; + withReadLock([&] { + for (const auto& uid : _ignoreItems) { + result.push_back(uid); + } + }); + return result; + } + + template + QVector getIncludeItemsAs() const { + QVector result; + withReadLock([&] { + for (const auto& uid : _includeItems) { + result.push_back(uid); + } + }); + return result; + } + + void setIgnoreItems(const QVector& items); + void setIncludeItems(const QVector& items); +#if 0 void setIgnoreEntities(const QScriptValue& ignoreEntities); void setIncludeEntities(const QScriptValue& includeEntities); void setIgnoreOverlays(const QScriptValue& ignoreOverlays); void setIncludeOverlays(const QScriptValue& includeOverlays); void setIgnoreAvatars(const QScriptValue& ignoreAvatars); void setIncludeAvatars(const QScriptValue& includeAvatars); - - QReadWriteLock* getLock() { return &_lock; } +#endif private: RayPickFilter _filter; - float _maxDistance; + const float _maxDistance; bool _enabled; RayPickResult _prevResult; - QVector _ignoreEntities; - QVector _includeEntities; - QVector _ignoreOverlays; - QVector _includeOverlays; - QVector _ignoreAvatars; - QVector _includeAvatars; - - QReadWriteLock _lock; + QVector _ignoreItems; + QVector _includeItems; }; #endif // hifi_RayPick_h diff --git a/interface/src/raypick/StaticRayPick.cpp b/libraries/pointers/src/pointers/rays/StaticRayPick.cpp similarity index 92% rename from interface/src/raypick/StaticRayPick.cpp rename to libraries/pointers/src/pointers/rays/StaticRayPick.cpp index 89bcddb3df..e507341021 100644 --- a/interface/src/raypick/StaticRayPick.cpp +++ b/libraries/pointers/src/pointers/rays/StaticRayPick.cpp @@ -1,7 +1,4 @@ // -// StaticRayPick.cpp -// interface/src/raypick -// // Created by Sam Gondelman 7/11/2017 // Copyright 2017 High Fidelity, Inc. // diff --git a/interface/src/raypick/StaticRayPick.h b/libraries/pointers/src/pointers/rays/StaticRayPick.h similarity index 92% rename from interface/src/raypick/StaticRayPick.h rename to libraries/pointers/src/pointers/rays/StaticRayPick.h index fc09ee6a27..de5ec234a5 100644 --- a/interface/src/raypick/StaticRayPick.h +++ b/libraries/pointers/src/pointers/rays/StaticRayPick.h @@ -1,7 +1,4 @@ // -// StaticRayPick.h -// interface/src/raypick -// // Created by Sam Gondelman 7/11/2017 // Copyright 2017 High Fidelity, Inc. //