diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f9ad6ec7ff..013e5c90a6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -193,8 +193,13 @@ #include #include +#include +#include #include #include +#include +#include +#include #include @@ -698,8 +703,12 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -804,7 +813,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif - + _logger = new FileLogger(this); qInstallMessageHandler(messageHandler); @@ -1826,25 +1835,29 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); + DependencyManager::get()->setShouldPickHUDOperator([&]() { return DependencyManager::get()->isHMDMode(); }); + // Setup the mouse ray pick and related operators - DependencyManager::get()->setMouseRayPickID(_rayPickManager.createRayPick( - RayPickFilter(DependencyManager::get()->PICK_ENTITIES() | DependencyManager::get()->PICK_INCLUDE_NONCOLLIDABLE()), - 0.0f, true)); + DependencyManager::get()->setMouseRayPickID(DependencyManager::get()->addPick(PickQuery::Ray, std::make_shared( + PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true))); DependencyManager::get()->setMouseRayPickResultOperator([&](QUuid rayPickID) { RayToEntityIntersectionResult entityResult; - RayPickResult result = _rayPickManager.getPrevRayPickResult(rayPickID); - entityResult.intersects = result.type != DependencyManager::get()->INTERSECTED_NONE(); - if (entityResult.intersects) { - entityResult.intersection = result.intersection; - entityResult.distance = result.distance; - entityResult.surfaceNormal = result.surfaceNormal; - entityResult.entityID = result.objectID; - entityResult.entity = DependencyManager::get()->getTree()->findEntityByID(entityResult.entityID); + entityResult.intersects = false; + QVariantMap result = DependencyManager::get()->getPrevPickResult(rayPickID); + if (result["type"].isValid()) { + entityResult.intersects = result["type"] != PickScriptingInterface::INTERSECTED_NONE(); + if (entityResult.intersects) { + entityResult.intersection = vec3FromVariant(result["intersection"]); + entityResult.distance = result["distance"].toFloat(); + entityResult.surfaceNormal = vec3FromVariant(result["surfaceNormal"]); + entityResult.entityID = result["objectID"].toUuid(); + entityResult.entity = DependencyManager::get()->getTree()->findEntityByID(entityResult.entityID); + } } return entityResult; }); DependencyManager::get()->setSetPrecisionPickingOperator([&](QUuid rayPickID, bool value) { - _rayPickManager.setPrecisionPicking(rayPickID, value); + DependencyManager::get()->setPrecisionPicking(rayPickID, value); }); qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); @@ -4950,13 +4963,13 @@ void Application::update(float deltaTime) { // TODO: break these out into distinct perfTimers when they prove interesting { - PROFILE_RANGE(app, "RayPickManager"); - _rayPickManager.update(); + PROFILE_RANGE(app, "PickManager"); + DependencyManager::get()->update(); } { - PROFILE_RANGE(app, "LaserPointerManager"); - _laserPointerManager.update(); + PROFILE_RANGE(app, "PointerManager"); + DependencyManager::get()->update(); } { @@ -5832,6 +5845,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerGlobalObject("RayPick", DependencyManager::get().data()); scriptEngine->registerGlobalObject("LaserPointers", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("Picks", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("Pointers", DependencyManager::get().data()); // Caches scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get().data()); diff --git a/interface/src/Application.h b/interface/src/Application.h index b6c09bbd87..93a8abe6a1 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -70,9 +70,6 @@ #include "ui/overlays/Overlays.h" #include "UndoStackScriptingInterface.h" -#include "raypick/RayPickManager.h" -#include "raypick/LaserPointerManager.h" - #include #include #include @@ -298,9 +295,6 @@ public: QUrl getAvatarOverrideUrl() { return _avatarOverrideUrl; } bool getSaveAvatarOverrideUrl() { return _saveAvatarOverrideUrl; } - LaserPointerManager& getLaserPointerManager() { return _laserPointerManager; } - RayPickManager& getRayPickManager() { return _rayPickManager; } - signals: void svoImportRequested(const QString& url); @@ -713,9 +707,6 @@ private: bool _saveAvatarOverrideUrl { false }; QObject* _renderEventHandler{ nullptr }; - RayPickManager _rayPickManager; - LaserPointerManager _laserPointerManager; - friend class RenderEventHandler; std::atomic _pendingIdleEvent { false }; diff --git a/interface/src/raypick/JointRayPick.cpp b/interface/src/raypick/JointRayPick.cpp index cf3f380ca0..c2a7fb11e5 100644 --- a/interface/src/raypick/JointRayPick.cpp +++ b/interface/src/raypick/JointRayPick.cpp @@ -12,7 +12,7 @@ #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) : +JointRayPick::JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const PickFilter& filter, const float maxDistance, const bool enabled) : RayPick(filter, maxDistance, enabled), _jointName(jointName), _posOffset(posOffset), @@ -20,7 +20,7 @@ JointRayPick::JointRayPick(const std::string& jointName, const glm::vec3& posOff { } -const PickRay JointRayPick::getPickRay(bool& valid) const { +const PickRay JointRayPick::getMathematicalPick() const { auto myAvatar = DependencyManager::get()->getMyAvatar(); int jointIndex = myAvatar->getJointIndex(QString::fromStdString(_jointName)); bool useAvatarHead = _jointName == "Avatar"; @@ -38,10 +38,8 @@ const PickRay JointRayPick::getPickRay(bool& valid) const { pos = pos + (rot * (myAvatar->getSensorToWorldScale() * _posOffset)); glm::vec3 dir = rot * glm::normalize(_dirOffset); - valid = true; return PickRay(pos, dir); } - valid = false; return PickRay(); } diff --git a/interface/src/raypick/JointRayPick.h b/interface/src/raypick/JointRayPick.h index e3e5670e20..ab44bf67c8 100644 --- a/interface/src/raypick/JointRayPick.h +++ b/interface/src/raypick/JointRayPick.h @@ -11,14 +11,14 @@ #ifndef hifi_JointRayPick_h #define hifi_JointRayPick_h -#include +#include "RayPick.h" class JointRayPick : public RayPick { public: - JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const RayPickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false); + JointRayPick(const std::string& jointName, const glm::vec3& posOffset, const glm::vec3& dirOffset, const PickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false); - const PickRay getPickRay(bool& valid) const override; + const PickRay getMathematicalPick() const override; private: std::string _jointName; diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 75b43a251b..32c67be884 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -12,21 +12,22 @@ #include "Application.h" #include "avatar/AvatarManager.h" -#include "RayPickScriptingInterface.h" + +#include +#include +#include "PickScriptingInterface.h" LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) : + Pointer(DependencyManager::get()->createRayPick(rayProps)), _renderingEnabled(enabled), _renderStates(renderStates), _defaultRenderStates(defaultRenderStates), _faceAvatar(faceAvatar), _centerEndY(centerEndY), _lockEnd(lockEnd), - _distanceScaleEnd(distanceScaleEnd), - _rayPickUID(DependencyManager::get()->createRayPick(rayProps)) + _distanceScaleEnd(distanceScaleEnd) { - - for (auto& state : _renderStates) { if (!enabled || state.first != _currentRenderState) { disableRenderState(state.second); @@ -40,8 +41,6 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende } LaserPointer::~LaserPointer() { - qApp->getRayPickManager().removeRayPick(_rayPickUID); - for (auto& renderState : _renderStates) { renderState.second.deleteOverlays(); } @@ -51,14 +50,14 @@ LaserPointer::~LaserPointer() { } void LaserPointer::enable() { - qApp->getRayPickManager().enableRayPick(_rayPickUID); + Pointer::enable(); withWriteLock([&] { _renderingEnabled = true; }); } void LaserPointer::disable() { - qApp->getRayPickManager().disableRayPick(_rayPickUID); + Pointer::disable(); withWriteLock([&] { _renderingEnabled = false; if (!_currentRenderState.empty()) { @@ -106,10 +105,6 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& } } -const RayPickResult LaserPointer::getPrevRayPickResult() { - return qApp->getRayPickManager().getPrevRayPickResult(_rayPickUID); -} - void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) { if (!renderState.getStartID().isNull()) { QVariantMap startProps; @@ -207,15 +202,18 @@ 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 withReadLock([&] { - RayPickResult prevRayPickResult = qApp->getRayPickManager().getPrevRayPickResult(_rayPickUID); + QVariantMap prevRayPickResult = DependencyManager::get()->getPrevPickResult(_pickUID); + IntersectionType type = IntersectionType(prevRayPickResult["type"].toInt()); + PickRay pickRay = PickRay(prevRayPickResult["searchRay"].toMap()); + QUuid uid = prevRayPickResult["objectID"].toUuid(); 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); + (type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) { + float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult["distance"].toFloat(); + updateRenderState(_renderStates[_currentRenderState], type, distance, uid, pickRay, 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); + updateRenderState(_defaultRenderStates[_currentRenderState].second, IntersectionType::NONE, _defaultRenderStates[_currentRenderState].first, QUuid(), pickRay, true); } else if (!_currentRenderState.empty()) { disableRenderState(_renderStates[_currentRenderState]); disableRenderState(_defaultRenderStates[_currentRenderState].second); @@ -223,13 +221,9 @@ void LaserPointer::update() { }); } -void LaserPointer::setPrecisionPicking(const bool precisionPicking) { - qApp->getRayPickManager().setPrecisionPicking(_rayPickUID, precisionPicking); -} - -void LaserPointer::setLaserLength(const float laserLength) { +void LaserPointer::setLength(const float length) { withWriteLock([&] { - _laserLength = laserLength; + _laserLength = length; }); } @@ -239,14 +233,6 @@ void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) { }); } -void LaserPointer::setIgnoreItems(const QVector& ignoreItems) const { - qApp->getRayPickManager().setIgnoreItems(_rayPickUID, ignoreItems); -} - -void LaserPointer::setIncludeItems(const QVector& includeItems) const { - qApp->getRayPickManager().setIncludeItems(_rayPickUID, includeItems); -} - RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) : _startID(startID), _pathID(pathID), _endID(endID) { @@ -273,3 +259,35 @@ void RenderState::deleteOverlays() { qApp->getOverlays().deleteOverlay(_endID); } } + +RenderState LaserPointer::buildRenderState(const QVariantMap& propMap) { + QUuid startID; + if (propMap["start"].isValid()) { + QVariantMap startMap = propMap["start"].toMap(); + if (startMap["type"].isValid()) { + startMap.remove("visible"); + startID = qApp->getOverlays().addOverlay(startMap["type"].toString(), startMap); + } + } + + QUuid pathID; + if (propMap["path"].isValid()) { + QVariantMap pathMap = propMap["path"].toMap(); + // right now paths must be line3ds + if (pathMap["type"].isValid() && pathMap["type"].toString() == "line3d") { + pathMap.remove("visible"); + pathID = qApp->getOverlays().addOverlay(pathMap["type"].toString(), pathMap); + } + } + + QUuid endID; + if (propMap["end"].isValid()) { + QVariantMap endMap = propMap["end"].toMap(); + if (endMap["type"].isValid()) { + endMap.remove("visible"); + endID = qApp->getOverlays().addOverlay(endMap["type"].toString(), endMap); + } + } + + return RenderState(startID, pathID, endID); +} \ No newline at end of file diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index f2350c7199..dd1ee6de57 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -14,12 +14,10 @@ #include #include -#include -#include - #include "ui/overlays/Overlay.h" -class RayPickResult; +#include +#include class RenderState { @@ -50,12 +48,9 @@ private: glm::vec3 _endDim; }; - -class LaserPointer : public ReadWriteLockable { +class LaserPointer : public Pointer { public: - using Pointer = std::shared_ptr; - typedef std::unordered_map RenderStateMap; typedef std::unordered_map> DefaultRenderStateMap; @@ -63,23 +58,19 @@ public: const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled); ~LaserPointer(); - QUuid getRayUID() { return _rayPickUID; } - void enable(); - void disable(); - const RayPickResult getPrevRayPickResult(); + void enable() override; + void disable() override; - void setRenderState(const std::string& state); + void setRenderState(const std::string& state) override; // You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays. - void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps); + void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) override; - void setPrecisionPicking(const bool precisionPicking); - void setLaserLength(const float laserLength); - void setLockEndUUID(QUuid objectID, const bool isOverlay); + void setLength(const float length) override; + void setLockEndUUID(QUuid objectID, const bool isOverlay) override; - void setIgnoreItems(const QVector& ignoreItems) const; - void setIncludeItems(const QVector& includeItems) const; + void update() override; - void update(); + static RenderState buildRenderState(const QVariantMap& propMap); private: bool _renderingEnabled; @@ -93,8 +84,6 @@ private: bool _distanceScaleEnd; std::pair _objectLockEnd { std::pair(QUuid(), false)}; - 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); void disableRenderState(const RenderState& renderState); diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp deleted file mode 100644 index 9d58cc2587..0000000000 --- a/interface/src/raypick/LaserPointerManager.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// -// LaserPointerManager.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 "LaserPointerManager.h" - -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 distanceScaleEnd, const bool enabled) { - QUuid result; - std::shared_ptr laserPointer = std::make_shared(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled); - if (!laserPointer->getRayUID().isNull()) { - result = QUuid::createUuid(); - withWriteLock([&] { _laserPointers[result] = laserPointer; }); - } - return result; -} - - -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::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) const { - auto laserPointer = find(uid); - if (laserPointer) { - laserPointer->disable(); - } -} - -void LaserPointerManager::setRenderState(const QUuid& uid, const std::string& renderState) const { - auto laserPointer = find(uid); - if (laserPointer) { - laserPointer->setRenderState(renderState); - } -} - -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) const { - auto laserPointer = find(uid); - if (laserPointer) { - return laserPointer->getPrevRayPickResult(); - } - return RayPickResult(); -} - -void LaserPointerManager::update() { - auto cachedLaserPointers = resultWithReadLock>>([&] { - return _laserPointers.values(); - }); - - for (const auto& laserPointer : cachedLaserPointers) { - laserPointer->update(); - } -} - -void LaserPointerManager::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const { - auto laserPointer = find(uid); - if (laserPointer) { - laserPointer->setPrecisionPicking(precisionPicking); - } -} - -void LaserPointerManager::setLaserLength(const QUuid& uid, const float laserLength) const { - auto laserPointer = find(uid); - if (laserPointer) { - laserPointer->setLaserLength(laserLength); - } -} - -void LaserPointerManager::setIgnoreItems(const QUuid& uid, const QVector& ignoreEntities) const { - auto laserPointer = find(uid); - if (laserPointer) { - laserPointer->setIgnoreItems(ignoreEntities); - } -} - -void LaserPointerManager::setIncludeItems(const QUuid& uid, const QVector& includeEntities) const { - auto laserPointer = find(uid); - if (laserPointer) { - laserPointer->setIncludeItems(includeEntities); - } -} - -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 deleted file mode 100644 index e302318483..0000000000 --- a/interface/src/raypick/LaserPointerManager.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// LaserPointerManager.h -// 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 -// -#ifndef hifi_LaserPointerManager_h -#define hifi_LaserPointerManager_h - -#include -#include - -#include - -#include "LaserPointer.h" - -class RayPickResult; - - -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 distanceScaleEnd, const bool enabled); - - 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(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(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const; - - void update(); - -private: - LaserPointer::Pointer find(const QUuid& uid) const; - QHash> _laserPointers; -}; - -#endif // hifi_LaserPointerManager_h diff --git a/interface/src/raypick/LaserPointerScriptingInterface.cpp b/interface/src/raypick/LaserPointerScriptingInterface.cpp index e8d28bfab2..533dffafb9 100644 --- a/interface/src/raypick/LaserPointerScriptingInterface.cpp +++ b/interface/src/raypick/LaserPointerScriptingInterface.cpp @@ -11,127 +11,20 @@ #include "LaserPointerScriptingInterface.h" -#include - -#include -#include +#include "RegisteredMetaTypes.h" +#include "PointerScriptingInterface.h" void LaserPointerScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) const { - qApp->getLaserPointerManager().setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); + DependencyManager::get()->setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); } void LaserPointerScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) const { - qApp->getLaserPointerManager().setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems)); + DependencyManager::get()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems)); } QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) const { - QVariantMap propertyMap = properties.toMap(); - - bool faceAvatar = false; - if (propertyMap["faceAvatar"].isValid()) { - faceAvatar = propertyMap["faceAvatar"].toBool(); - } - - bool centerEndY = true; - if (propertyMap["centerEndY"].isValid()) { - centerEndY = propertyMap["centerEndY"].toBool(); - } - - bool lockEnd = false; - if (propertyMap["lockEnd"].isValid()) { - lockEnd = propertyMap["lockEnd"].toBool(); - } - - bool distanceScaleEnd = false; - if (propertyMap["distanceScaleEnd"].isValid()) { - distanceScaleEnd = propertyMap["distanceScaleEnd"].toBool(); - } - - bool enabled = false; - if (propertyMap["enabled"].isValid()) { - enabled = propertyMap["enabled"].toBool(); - } - - LaserPointer::RenderStateMap renderStates; - if (propertyMap["renderStates"].isValid()) { - QList renderStateVariants = propertyMap["renderStates"].toList(); - for (QVariant& renderStateVariant : renderStateVariants) { - if (renderStateVariant.isValid()) { - QVariantMap renderStateMap = renderStateVariant.toMap(); - if (renderStateMap["name"].isValid()) { - std::string name = renderStateMap["name"].toString().toStdString(); - renderStates[name] = buildRenderState(renderStateMap); - } - } - } - } - - LaserPointer::DefaultRenderStateMap defaultRenderStates; - if (propertyMap["defaultRenderStates"].isValid()) { - QList renderStateVariants = propertyMap["defaultRenderStates"].toList(); - for (QVariant& renderStateVariant : renderStateVariants) { - if (renderStateVariant.isValid()) { - QVariantMap renderStateMap = renderStateVariant.toMap(); - if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) { - std::string name = renderStateMap["name"].toString().toStdString(); - float distance = renderStateMap["distance"].toFloat(); - defaultRenderStates[name] = std::pair(distance, buildRenderState(renderStateMap)); - } - } - } - } - - return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled); + return DependencyManager::get()->createLaserPointer(properties); } void LaserPointerScriptingInterface::editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const { - QVariantMap propMap = properties.toMap(); - - QVariant startProps; - if (propMap["start"].isValid()) { - startProps = propMap["start"]; - } - - QVariant pathProps; - if (propMap["path"].isValid()) { - pathProps = propMap["path"]; - } - - QVariant endProps; - if (propMap["end"].isValid()) { - endProps = propMap["end"]; - } - - qApp->getLaserPointerManager().editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps); -} - -RenderState LaserPointerScriptingInterface::buildRenderState(const QVariantMap& propMap) { - QUuid startID; - if (propMap["start"].isValid()) { - QVariantMap startMap = propMap["start"].toMap(); - if (startMap["type"].isValid()) { - startMap.remove("visible"); - startID = qApp->getOverlays().addOverlay(startMap["type"].toString(), startMap); - } - } - - QUuid pathID; - if (propMap["path"].isValid()) { - QVariantMap pathMap = propMap["path"].toMap(); - // right now paths must be line3ds - if (pathMap["type"].isValid() && pathMap["type"].toString() == "line3d") { - pathMap.remove("visible"); - pathID = qApp->getOverlays().addOverlay(pathMap["type"].toString(), pathMap); - } - } - - QUuid endID; - if (propMap["end"].isValid()) { - QVariantMap endMap = propMap["end"].toMap(); - if (endMap["type"].isValid()) { - endMap.remove("visible"); - endID = qApp->getOverlays().addOverlay(endMap["type"].toString(), endMap); - } - } - - return RenderState(startID, pathID, endID); + DependencyManager::get()->editRenderState(uid, renderState, properties); } \ No newline at end of file diff --git a/interface/src/raypick/LaserPointerScriptingInterface.h b/interface/src/raypick/LaserPointerScriptingInterface.h index 19262e6e5d..1116da1528 100644 --- a/interface/src/raypick/LaserPointerScriptingInterface.h +++ b/interface/src/raypick/LaserPointerScriptingInterface.h @@ -13,9 +13,8 @@ #include -#include "RegisteredMetaTypes.h" #include "DependencyManager.h" -#include "Application.h" +#include class LaserPointerScriptingInterface : public QObject, public Dependency { Q_OBJECT @@ -23,22 +22,19 @@ class LaserPointerScriptingInterface : public QObject, public Dependency { public slots: 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 enableLaserPointer(const QUuid& uid) const { DependencyManager::get()->enablePointer(uid); } + Q_INVOKABLE void disableLaserPointer(const QUuid& uid) const { DependencyManager::get()->disablePointer(uid); } + Q_INVOKABLE void removeLaserPointer(const QUuid& uid) const { DependencyManager::get()->removePointer(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 setRenderState(const QUuid& uid, const QString& renderState) const { DependencyManager::get()->setRenderState(uid, renderState.toStdString()); } + Q_INVOKABLE QVariantMap getPrevRayPickResult(QUuid uid) const { return DependencyManager::get()->getPrevPickResult(uid); } - 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 setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { DependencyManager::get()->setPrecisionPicking(uid, precisionPicking); } + Q_INVOKABLE void setLaserLength(const QUuid& uid, float laserLength) const { DependencyManager::get()->setLength(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(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); } - -private: - static RenderState buildRenderState(const QVariantMap& propMap); + Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay); } }; diff --git a/interface/src/raypick/MouseRayPick.cpp b/interface/src/raypick/MouseRayPick.cpp index de59fde88d..f691dafc01 100644 --- a/interface/src/raypick/MouseRayPick.cpp +++ b/interface/src/raypick/MouseRayPick.cpp @@ -10,23 +10,20 @@ // #include "MouseRayPick.h" -#include "DependencyManager.h" #include "Application.h" #include "display-plugins/CompositorHelper.h" -MouseRayPick::MouseRayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled) : +MouseRayPick::MouseRayPick(const PickFilter& filter, const float maxDistance, const bool enabled) : RayPick(filter, maxDistance, enabled) { } -const PickRay MouseRayPick::getPickRay(bool& valid) const { +const PickRay MouseRayPick::getMathematicalPick() const { QVariant position = qApp->getApplicationCompositor().getReticleInterface()->getPosition(); if (position.isValid()) { QVariantMap posMap = position.toMap(); - valid = true; return qApp->getCamera().computePickRay(posMap["x"].toFloat(), posMap["y"].toFloat()); } - valid = false; return PickRay(); } diff --git a/interface/src/raypick/MouseRayPick.h b/interface/src/raypick/MouseRayPick.h index 47f9404f3a..e9eb3ccabf 100644 --- a/interface/src/raypick/MouseRayPick.h +++ b/interface/src/raypick/MouseRayPick.h @@ -11,14 +11,14 @@ #ifndef hifi_MouseRayPick_h #define hifi_MouseRayPick_h -#include +#include "RayPick.h" class MouseRayPick : public RayPick { public: - MouseRayPick(const RayPickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false); + MouseRayPick(const PickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false); - const PickRay getPickRay(bool& valid) const override; + const PickRay getMathematicalPick() const override; }; #endif // hifi_MouseRayPick_h diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp new file mode 100644 index 0000000000..99f7ac2515 --- /dev/null +++ b/interface/src/raypick/PickScriptingInterface.cpp @@ -0,0 +1,107 @@ +// +// Created by Sam Gondelman 10/20/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 "PickScriptingInterface.h" + +#include +#include "GLMHelpers.h" + +#include + +#include "StaticRayPick.h" +#include "JointRayPick.h" +#include "MouseRayPick.h" + +QUuid PickScriptingInterface::createPick(const PickQuery::PickType type, const QVariant& properties) { + switch (type) { + case PickQuery::PickType::Ray: + return createRayPick(properties); + default: + return QUuid(); + } +} + +QUuid PickScriptingInterface::createRayPick(const QVariant& properties) { + QVariantMap propMap = properties.toMap(); + + bool enabled = false; + if (propMap["enabled"].isValid()) { + enabled = propMap["enabled"].toBool(); + } + + PickFilter filter = PickFilter(); + if (propMap["filter"].isValid()) { + filter = PickFilter(propMap["filter"].toUInt()); + } + + float maxDistance = 0.0f; + if (propMap["maxDistance"].isValid()) { + maxDistance = propMap["maxDistance"].toFloat(); + } + + if (propMap["joint"].isValid()) { + std::string jointName = propMap["joint"].toString().toStdString(); + + if (jointName != "Mouse") { + // x = upward, y = forward, z = lateral + glm::vec3 posOffset = Vectors::ZERO; + if (propMap["posOffset"].isValid()) { + posOffset = vec3FromVariant(propMap["posOffset"]); + } + + glm::vec3 dirOffset = Vectors::UP; + if (propMap["dirOffset"].isValid()) { + dirOffset = vec3FromVariant(propMap["dirOffset"]); + } + + return DependencyManager::get()->addPick(PickQuery::Ray, std::make_shared(jointName, posOffset, dirOffset, filter, maxDistance, enabled)); + + } else { + return DependencyManager::get()->addPick(PickQuery::Ray, std::make_shared(filter, maxDistance, enabled)); + } + } else if (propMap["position"].isValid()) { + glm::vec3 position = vec3FromVariant(propMap["position"]); + + glm::vec3 direction = -Vectors::UP; + if (propMap["direction"].isValid()) { + direction = vec3FromVariant(propMap["direction"]); + } + + return DependencyManager::get()->addPick(PickQuery::Ray, std::make_shared(position, direction, filter, maxDistance, enabled)); + } + + return QUuid(); +} + +void PickScriptingInterface::enablePick(const QUuid& uid) { + DependencyManager::get()->enablePick(uid); +} + +void PickScriptingInterface::disablePick(const QUuid& uid) { + DependencyManager::get()->disablePick(uid); +} + +void PickScriptingInterface::removePick(const QUuid& uid) { + DependencyManager::get()->removePick(uid); +} + +QVariantMap PickScriptingInterface::getPrevPickResult(const QUuid& uid) { + return DependencyManager::get()->getPrevPickResult(uid); +} + +void PickScriptingInterface::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) { + DependencyManager::get()->setPrecisionPicking(uid, precisionPicking); +} + +void PickScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) { + DependencyManager::get()->setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); +} + +void PickScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) { + DependencyManager::get()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems)); +} diff --git a/interface/src/raypick/PickScriptingInterface.h b/interface/src/raypick/PickScriptingInterface.h new file mode 100644 index 0000000000..462b64dbd1 --- /dev/null +++ b/interface/src/raypick/PickScriptingInterface.h @@ -0,0 +1,65 @@ +// +// Created by Sam Gondelman 10/20/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 +// +#ifndef hifi_PickScriptingInterface_h +#define hifi_PickScriptingInterface_h + +#include + +#include +#include +#include + +class PickScriptingInterface : public QObject, public Dependency { + Q_OBJECT + Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT) + Q_PROPERTY(unsigned int PICK_ENTITIES READ PICK_ENTITIES CONSTANT) + Q_PROPERTY(unsigned int PICK_OVERLAYS READ PICK_OVERLAYS CONSTANT) + Q_PROPERTY(unsigned int PICK_AVATARS READ PICK_AVATARS CONSTANT) + Q_PROPERTY(unsigned int PICK_HUD READ PICK_HUD CONSTANT) + Q_PROPERTY(unsigned int PICK_COARSE READ PICK_COARSE CONSTANT) + Q_PROPERTY(unsigned int PICK_INCLUDE_INVISIBLE READ PICK_INCLUDE_INVISIBLE CONSTANT) + Q_PROPERTY(unsigned int PICK_INCLUDE_NONCOLLIDABLE READ PICK_INCLUDE_NONCOLLIDABLE CONSTANT) + Q_PROPERTY(unsigned int PICK_ALL_INTERSECTIONS READ PICK_ALL_INTERSECTIONS CONSTANT) + Q_PROPERTY(unsigned int INTERSECTED_NONE READ INTERSECTED_NONE CONSTANT) + Q_PROPERTY(unsigned int INTERSECTED_ENTITY READ INTERSECTED_ENTITY CONSTANT) + Q_PROPERTY(unsigned int INTERSECTED_OVERLAY READ INTERSECTED_OVERLAY CONSTANT) + Q_PROPERTY(unsigned int INTERSECTED_AVATAR READ INTERSECTED_AVATAR CONSTANT) + Q_PROPERTY(unsigned int INTERSECTED_HUD READ INTERSECTED_HUD CONSTANT) + SINGLETON_DEPENDENCY + +public: + QUuid createRayPick(const QVariant& properties); + +public slots: + Q_INVOKABLE QUuid createPick(const PickQuery::PickType type, const QVariant& properties); + Q_INVOKABLE void enablePick(const QUuid& uid); + Q_INVOKABLE void disablePick(const QUuid& uid); + Q_INVOKABLE void removePick(const QUuid& uid); + Q_INVOKABLE QVariantMap getPrevPickResult(const QUuid& uid); + + 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); + + 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); } + static constexpr unsigned int PICK_AVATARS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_AVATARS); } + static constexpr unsigned int PICK_HUD() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_HUD); } + static constexpr unsigned int PICK_COARSE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_COARSE); } + static constexpr unsigned int PICK_INCLUDE_INVISIBLE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); } + static constexpr unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); } + static constexpr unsigned int PICK_ALL_INTERSECTIONS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ALL_INTERSECTIONS); } + static constexpr unsigned int INTERSECTED_NONE() { return IntersectionType::NONE; } + static constexpr unsigned int INTERSECTED_ENTITY() { return IntersectionType::ENTITY; } + static constexpr unsigned int INTERSECTED_OVERLAY() { return IntersectionType::OVERLAY; } + static constexpr unsigned int INTERSECTED_AVATAR() { return IntersectionType::AVATAR; } + static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; } +}; + +#endif // hifi_PickScriptingInterface_h \ No newline at end of file diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp new file mode 100644 index 0000000000..8a87721ad9 --- /dev/null +++ b/interface/src/raypick/PointerScriptingInterface.cpp @@ -0,0 +1,112 @@ +// +// Created by Sam Gondelman 10/20/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 "PointerScriptingInterface.h" + +#include +#include + +#include "Application.h" +#include "LaserPointer.h" + +void PointerScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) const { + DependencyManager::get()->setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); +} +void PointerScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) const { + DependencyManager::get()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems)); +} + +QUuid PointerScriptingInterface::createPointer(const PickQuery::PickType type, const QVariant& properties) const { + switch (type) { + case PickQuery::PickType::Ray: + return createLaserPointer(properties); + default: + return QUuid(); + } +} + +QUuid PointerScriptingInterface::createLaserPointer(const QVariant& properties) const { + QVariantMap propertyMap = properties.toMap(); + + bool faceAvatar = false; + if (propertyMap["faceAvatar"].isValid()) { + faceAvatar = propertyMap["faceAvatar"].toBool(); + } + + bool centerEndY = true; + if (propertyMap["centerEndY"].isValid()) { + centerEndY = propertyMap["centerEndY"].toBool(); + } + + bool lockEnd = false; + if (propertyMap["lockEnd"].isValid()) { + lockEnd = propertyMap["lockEnd"].toBool(); + } + + bool distanceScaleEnd = false; + if (propertyMap["distanceScaleEnd"].isValid()) { + distanceScaleEnd = propertyMap["distanceScaleEnd"].toBool(); + } + + bool enabled = false; + if (propertyMap["enabled"].isValid()) { + enabled = propertyMap["enabled"].toBool(); + } + + LaserPointer::RenderStateMap renderStates; + if (propertyMap["renderStates"].isValid()) { + QList renderStateVariants = propertyMap["renderStates"].toList(); + for (QVariant& renderStateVariant : renderStateVariants) { + if (renderStateVariant.isValid()) { + QVariantMap renderStateMap = renderStateVariant.toMap(); + if (renderStateMap["name"].isValid()) { + std::string name = renderStateMap["name"].toString().toStdString(); + renderStates[name] = LaserPointer::buildRenderState(renderStateMap); + } + } + } + } + + LaserPointer::DefaultRenderStateMap defaultRenderStates; + if (propertyMap["defaultRenderStates"].isValid()) { + QList renderStateVariants = propertyMap["defaultRenderStates"].toList(); + for (QVariant& renderStateVariant : renderStateVariants) { + if (renderStateVariant.isValid()) { + QVariantMap renderStateMap = renderStateVariant.toMap(); + if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) { + std::string name = renderStateMap["name"].toString().toStdString(); + float distance = renderStateMap["distance"].toFloat(); + defaultRenderStates[name] = std::pair(distance, LaserPointer::buildRenderState(renderStateMap)); + } + } + } + } + + return DependencyManager::get()->addPointer(std::make_shared(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled)); +} + +void PointerScriptingInterface::editRenderState(const QUuid& uid, const QString& renderState, const QVariant& properties) const { + QVariantMap propMap = properties.toMap(); + + QVariant startProps; + if (propMap["start"].isValid()) { + startProps = propMap["start"]; + } + + QVariant pathProps; + if (propMap["path"].isValid()) { + pathProps = propMap["path"]; + } + + QVariant endProps; + if (propMap["end"].isValid()) { + endProps = propMap["end"]; + } + + DependencyManager::get()->editRenderState(uid, renderState.toStdString(), startProps, pathProps, endProps); +} \ No newline at end of file diff --git a/interface/src/raypick/PointerScriptingInterface.h b/interface/src/raypick/PointerScriptingInterface.h new file mode 100644 index 0000000000..de45826d48 --- /dev/null +++ b/interface/src/raypick/PointerScriptingInterface.h @@ -0,0 +1,42 @@ +// +// Created by Sam Gondelman 10/20/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 +// +#ifndef hifi_PointerScriptingInterface_h +#define hifi_PointerScriptingInterface_h + +#include + +#include "DependencyManager.h" +#include +#include + +class PointerScriptingInterface : public QObject, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + +public: + QUuid createLaserPointer(const QVariant& properties) const; + +public slots: + Q_INVOKABLE QUuid createPointer(const PickQuery::PickType type, const QVariant& properties) const; + Q_INVOKABLE void enablePointer(const QUuid& uid) const { DependencyManager::get()->enablePointer(uid); } + Q_INVOKABLE void disablePointer(const QUuid& uid) const { DependencyManager::get()->disablePointer(uid); } + Q_INVOKABLE void removePointer(const QUuid& uid) const { DependencyManager::get()->removePointer(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 { DependencyManager::get()->setRenderState(uid, renderState.toStdString()); } + Q_INVOKABLE QVariantMap getPrevPickResult(QUuid uid) const { return DependencyManager::get()->getPrevPickResult(uid); } + + Q_INVOKABLE void setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { DependencyManager::get()->setPrecisionPicking(uid, precisionPicking); } + Q_INVOKABLE void setLaserLength(const QUuid& uid, float laserLength) const { DependencyManager::get()->setLength(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(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay); } + +}; + +#endif // hifi_PointerScriptingInterface_h diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp new file mode 100644 index 0000000000..4e1e0386f1 --- /dev/null +++ b/interface/src/raypick/RayPick.cpp @@ -0,0 +1,51 @@ +// +// 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" + +#include "Application.h" +#include "EntityScriptingInterface.h" +#include "ui/overlays/Overlays.h" +#include "avatar/AvatarManager.h" +#include "scripting/HMDScriptingInterface.h" +#include "DependencyManager.h" + +PickResultPointer RayPick::getEntityIntersection(const PickRay& pick) { + RayToEntityIntersectionResult entityRes = + DependencyManager::get()->findRayIntersectionVector(pick, !getFilter().doesPickCoarse(), + getIncludeItemsAs(), getIgnoreItemsAs(), !getFilter().doesPickInvisible(), !getFilter().doesPickNonCollidable()); + if (entityRes.intersects) { + return std::make_shared(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, pick, entityRes.surfaceNormal); + } else { + return std::make_shared(pick.toVariantMap()); + } +} + +PickResultPointer RayPick::getOverlayIntersection(const PickRay& pick) { + RayToOverlayIntersectionResult overlayRes = + qApp->getOverlays().findRayIntersectionVector(pick, !getFilter().doesPickCoarse(), + getIncludeItemsAs(), getIgnoreItemsAs(), !getFilter().doesPickInvisible(), !getFilter().doesPickNonCollidable()); + if (overlayRes.intersects) { + return std::make_shared(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, pick, overlayRes.surfaceNormal); + } else { + return std::make_shared(pick.toVariantMap()); + } +} + +PickResultPointer RayPick::getAvatarIntersection(const PickRay& pick) { + RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(pick, getIncludeItemsAs(), getIgnoreItemsAs()); + if (avatarRes.intersects) { + return std::make_shared(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, pick); + } else { + return std::make_shared(pick.toVariantMap()); + } +} + +PickResultPointer RayPick::getHUDIntersection(const PickRay& pick) { + glm::vec3 hudRes = DependencyManager::get()->calculateRayUICollisionPoint(pick.origin, pick.direction); + return std::make_shared(IntersectionType::HUD, QUuid(), glm::distance(pick.origin, hudRes), hudRes, pick); +} \ No newline at end of file diff --git a/interface/src/raypick/RayPick.h b/interface/src/raypick/RayPick.h new file mode 100644 index 0000000000..b5d7ea7c3e --- /dev/null +++ b/interface/src/raypick/RayPick.h @@ -0,0 +1,79 @@ +// +// 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 +// +#ifndef hifi_RayPick_h +#define hifi_RayPick_h + +#include +#include + +class EntityItemID; +class OverlayID; + +class RayPickResult : public PickResult { +public: + RayPickResult() {} + RayPickResult(const QVariantMap& pickVariant) : PickResult(pickVariant) {} + RayPickResult(const IntersectionType type, const QUuid& objectID, const float distance, const glm::vec3& intersection, const PickRay& searchRay, const glm::vec3& surfaceNormal = glm::vec3(NAN)) : + PickResult(searchRay.toVariantMap()), type(type), intersects(type != NONE), objectID(objectID), distance(distance), intersection(intersection), surfaceNormal(surfaceNormal) { + } + + RayPickResult(const RayPickResult& rayPickResult) : PickResult(rayPickResult.pickVariant) { + type = rayPickResult.type; + intersects = rayPickResult.intersects; + objectID = rayPickResult.objectID; + distance = rayPickResult.distance; + intersection = rayPickResult.intersection; + surfaceNormal = rayPickResult.surfaceNormal; + } + + IntersectionType type { NONE }; + bool intersects { false }; + QUuid objectID; + float distance { FLT_MAX }; + glm::vec3 intersection { NAN }; + glm::vec3 surfaceNormal { NAN }; + + virtual QVariantMap toVariantMap() const override { + QVariantMap toReturn; + toReturn["type"] = type; + toReturn["intersects"] = intersects; + toReturn["objectID"] = objectID; + toReturn["distance"] = distance; + toReturn["intersection"] = vec3toVariant(intersection); + toReturn["surfaceNormal"] = vec3toVariant(surfaceNormal); + toReturn["searchRay"] = PickResult::toVariantMap(); + return toReturn; + } + + bool doesIntersect() const override { return intersects; } + bool checkOrFilterAgainstMaxDistance(float maxDistance) override { return distance < maxDistance; } + + PickResultPointer compareAndProcessNewResult(const PickResultPointer newRes) override { + auto newRayRes = std::static_pointer_cast(newRes); + if (newRayRes->distance < distance) { + return std::make_shared(*newRayRes); + } else { + return std::make_shared(*this); + } + } + +}; + +class RayPick : public Pick { + +public: + RayPick(const PickFilter& filter, const float maxDistance, const bool enabled) : Pick(filter, maxDistance, enabled) {} + + PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const override { return std::make_shared(pickVariant); } + PickResultPointer getEntityIntersection(const PickRay& pick) override; + PickResultPointer getOverlayIntersection(const PickRay& pick) override; + PickResultPointer getAvatarIntersection(const PickRay& pick) override; + PickResultPointer getHUDIntersection(const PickRay& pick) override; +}; + +#endif // hifi_RayPick_h diff --git a/interface/src/raypick/RayPickManager.cpp b/interface/src/raypick/RayPickManager.cpp deleted file mode 100644 index 15489ce93d..0000000000 --- a/interface/src/raypick/RayPickManager.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// -// RayPickManager.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 "RayPickManager.h" - -#include - -#include "Application.h" -#include "EntityScriptingInterface.h" -#include "ui/overlays/Overlays.h" -#include "avatar/AvatarManager.h" -#include "scripting/HMDScriptingInterface.h" -#include "DependencyManager.h" - -#include "JointRayPick.h" -#include "MouseRayPick.h" - -bool RayPickManager::checkAndCompareCachedResults(QPair& ray, RayPickCache& cache, RayPickResult& res, const RayCacheKey& key) { - if (cache.contains(ray) && cache[ray].find(key) != cache[ray].end()) { - if (cache[ray][key].distance < res.distance) { - res = cache[ray][key]; - } - return true; - } - return false; -} - -void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, const RayCacheKey& key, RayPickResult& res, QPair& ray, RayPickCache& cache) { - if (intersects) { - cache[ray][key] = resTemp; - if (resTemp.distance < res.distance) { - res = resTemp; - } - } else { - cache[ray][key] = RayPickResult(res.searchRay); - } -} - -void RayPickManager::update() { - RayPickCache results; - 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; - } - - PickRay ray; - - { - bool valid; - ray = rayPick->getPickRay(valid); - if (!valid) { - continue; - } - } - - QPair rayKey = QPair(ray.origin, ray.direction); - RayPickResult res = RayPickResult(ray); - - if (rayPick->getFilter().doesPickEntities()) { - RayToEntityIntersectionResult entityRes; - bool fromCache = true; - bool invisible = rayPick->getFilter().doesPickInvisible(); - bool nonCollidable = rayPick->getFilter().doesPickNonCollidable(); - RayCacheKey entityKey = { rayPick->getFilter().getEntityFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() }; - if (!checkAndCompareCachedResults(rayKey, results, res, entityKey)) { - entityRes = DependencyManager::get()->findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCoarse(), - rayPick->getIncludeItemsAs(), rayPick->getIgnoreItemsAs(), !invisible, !nonCollidable); - fromCache = false; - } - - if (!fromCache) { - cacheResult(entityRes.intersects, RayPickResult(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, ray, entityRes.surfaceNormal), - entityKey, res, rayKey, results); - } - } - - if (rayPick->getFilter().doesPickOverlays()) { - RayToOverlayIntersectionResult overlayRes; - bool fromCache = true; - bool invisible = rayPick->getFilter().doesPickInvisible(); - bool nonCollidable = rayPick->getFilter().doesPickNonCollidable(); - RayCacheKey overlayKey = { rayPick->getFilter().getOverlayFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() }; - if (!checkAndCompareCachedResults(rayKey, results, res, overlayKey)) { - overlayRes = qApp->getOverlays().findRayIntersectionVector(ray, !rayPick->getFilter().doesPickCoarse(), - rayPick->getIncludeItemsAs(), rayPick->getIgnoreItemsAs(), !invisible, !nonCollidable); - fromCache = false; - } - - if (!fromCache) { - cacheResult(overlayRes.intersects, RayPickResult(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, ray, overlayRes.surfaceNormal), - overlayKey, res, rayKey, results); - } - } - - if (rayPick->getFilter().doesPickAvatars()) { - RayCacheKey avatarKey = { rayPick->getFilter().getAvatarFlags(), rayPick->getIncludeItems(), rayPick->getIgnoreItems() }; - if (!checkAndCompareCachedResults(rayKey, results, res, avatarKey)) { - RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(ray, - rayPick->getIncludeItemsAs(), rayPick->getIgnoreItemsAs()); - cacheResult(avatarRes.intersects, RayPickResult(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, ray), avatarKey, res, rayKey, results); - } - } - - // Can't intersect with HUD in desktop mode - if (rayPick->getFilter().doesPickHUD() && DependencyManager::get()->isHMDMode()) { - RayCacheKey hudKey = { rayPick->getFilter().getHUDFlags(), QVector(), QVector() }; - if (!checkAndCompareCachedResults(rayKey, results, res, hudKey)) { - glm::vec3 hudRes = DependencyManager::get()->calculateRayUICollisionPoint(ray.origin, ray.direction); - cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes, ray), hudKey, res, rayKey, results); - } - } - - if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) { - rayPick->setRayPickResult(res); - } else { - rayPick->setRayPickResult(RayPickResult(ray)); - } - } -} - -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(); - withWriteLock([&] { - _rayPicks[id] = newRayPick; - }); - return id; -} - -QUuid RayPickManager::createRayPick(const RayPickFilter& filter, float maxDistance, bool enabled) { - QUuid id = QUuid::createUuid(); - 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, float maxDistance, bool enabled) { - QUuid id = QUuid::createUuid(); - auto newRayPick = std::make_shared(position, direction, filter, maxDistance, enabled); - withWriteLock([&] { - _rayPicks[id] = newRayPick; - }); - return id; -} - -void RayPickManager::removeRayPick(const QUuid& uid) { - withWriteLock([&] { - _rayPicks.remove(uid); - }); -} - -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) const { - auto rayPick = findRayPick(uid); - if (rayPick) { - rayPick->disable(); - } -} - -RayPickResult RayPickManager::getPrevRayPickResult(const QUuid& uid) const { - auto rayPick = findRayPick(uid); - if (rayPick) { - return rayPick->getPrevRayPickResult(); - } - return RayPickResult(); -} - -void RayPickManager::setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { - auto rayPick = findRayPick(uid); - if (rayPick) { - rayPick->setPrecisionPicking(precisionPicking); - } -} - -void RayPickManager::setIgnoreItems(const QUuid& uid, const QVector& ignore) const { - auto rayPick = findRayPick(uid); - if (rayPick) { - rayPick->setIgnoreItems(ignore); - } -} - -void RayPickManager::setIncludeItems(const QUuid& uid, const QVector& include) const { - auto rayPick = findRayPick(uid); - if (rayPick) { - rayPick->setIncludeItems(include); - } -} diff --git a/interface/src/raypick/RayPickManager.h b/interface/src/raypick/RayPickManager.h deleted file mode 100644 index fd2c6f4a6b..0000000000 --- a/interface/src/raypick/RayPickManager.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// RayPickManager.h -// 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 -// -#ifndef hifi_RayPickManager_h -#define hifi_RayPickManager_h - - -#include -#include -#include - -#include - -#include -#include - - -class RayPickResult; - -typedef struct RayCacheKey { - RayPickFilter::Flags mask; - QVector include; - QVector ignore; - - bool operator==(const RayCacheKey& other) const { - return (mask == other.mask && include == other.include && ignore == other.ignore); - } -} RayCacheKey; - -namespace std { - template <> - struct hash { - size_t operator()(const RayCacheKey& k) const { - return ((hash()(k.mask) ^ (qHash(k.include) << 1)) >> 1) ^ (qHash(k.ignore) << 1); - } - }; -} - -class RayPickManager : protected ReadWriteLockable { - -public: - void update(); - - 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) const; - void disableRayPick(const QUuid& uid) const; - RayPickResult getPrevRayPickResult(const QUuid& uid) const; - - 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: - RayPick::Pointer findRayPick(const QUuid& uid) const; - QHash _rayPicks; - - typedef QHash, std::unordered_map> RayPickCache; - - // Returns true if this ray exists in the cache, and if it does, update res if the cached result is closer - bool checkAndCompareCachedResults(QPair& ray, RayPickCache& cache, RayPickResult& res, const RayCacheKey& key); - void cacheResult(const bool intersects, const RayPickResult& resTemp, const RayCacheKey& key, RayPickResult& res, QPair& ray, RayPickCache& cache); -}; - -#endif // hifi_RayPickManager_h \ No newline at end of file diff --git a/interface/src/raypick/RayPickScriptingInterface.cpp b/interface/src/raypick/RayPickScriptingInterface.cpp index 621ae9b738..b89f89aab5 100644 --- a/interface/src/raypick/RayPickScriptingInterface.cpp +++ b/interface/src/raypick/RayPickScriptingInterface.cpp @@ -13,83 +13,42 @@ #include #include "GLMHelpers.h" -#include "Application.h" + +#include "PickScriptingInterface.h" +#include + +#include "StaticRayPick.h" +#include "JointRayPick.h" +#include "MouseRayPick.h" QUuid RayPickScriptingInterface::createRayPick(const QVariant& properties) { - QVariantMap propMap = properties.toMap(); - - bool enabled = false; - if (propMap["enabled"].isValid()) { - enabled = propMap["enabled"].toBool(); - } - - RayPickFilter filter = RayPickFilter(); - if (propMap["filter"].isValid()) { - filter = RayPickFilter(propMap["filter"].toUInt()); - } - - float maxDistance = 0.0f; - if (propMap["maxDistance"].isValid()) { - maxDistance = propMap["maxDistance"].toFloat(); - } - - if (propMap["joint"].isValid()) { - std::string jointName = propMap["joint"].toString().toStdString(); - - if (jointName != "Mouse") { - // x = upward, y = forward, z = lateral - glm::vec3 posOffset = Vectors::ZERO; - if (propMap["posOffset"].isValid()) { - posOffset = vec3FromVariant(propMap["posOffset"]); - } - - glm::vec3 dirOffset = Vectors::UP; - if (propMap["dirOffset"].isValid()) { - dirOffset = vec3FromVariant(propMap["dirOffset"]); - } - - return qApp->getRayPickManager().createRayPick(jointName, posOffset, dirOffset, filter, maxDistance, enabled); - } else { - return qApp->getRayPickManager().createRayPick(filter, maxDistance, enabled); - } - } else if (propMap["position"].isValid()) { - glm::vec3 position = vec3FromVariant(propMap["position"]); - - glm::vec3 direction = -Vectors::UP; - if (propMap["direction"].isValid()) { - direction = vec3FromVariant(propMap["direction"]); - } - - return qApp->getRayPickManager().createRayPick(position, direction, filter, maxDistance, enabled); - } - - return QUuid(); + return DependencyManager::get()->createRayPick(properties); } void RayPickScriptingInterface::enableRayPick(const QUuid& uid) { - qApp->getRayPickManager().enableRayPick(uid); + DependencyManager::get()->enablePick(uid); } void RayPickScriptingInterface::disableRayPick(const QUuid& uid) { - qApp->getRayPickManager().disableRayPick(uid); + DependencyManager::get()->disablePick(uid); } void RayPickScriptingInterface::removeRayPick(const QUuid& uid) { - qApp->getRayPickManager().removeRayPick(uid); + DependencyManager::get()->removePick(uid); } -RayPickResult RayPickScriptingInterface::getPrevRayPickResult(const QUuid& uid) { - return qApp->getRayPickManager().getPrevRayPickResult(uid); +QVariantMap RayPickScriptingInterface::getPrevRayPickResult(const QUuid& uid) { + return DependencyManager::get()->getPrevPickResult(uid); } void RayPickScriptingInterface::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) { - qApp->getRayPickManager().setPrecisionPicking(uid, precisionPicking); + DependencyManager::get()->setPrecisionPicking(uid, precisionPicking); } void RayPickScriptingInterface::setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreItems) { - qApp->getRayPickManager().setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); + DependencyManager::get()->setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); } void RayPickScriptingInterface::setIncludeItems(const QUuid& uid, const QScriptValue& includeItems) { - qApp->getRayPickManager().setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems)); + DependencyManager::get()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems)); } diff --git a/interface/src/raypick/RayPickScriptingInterface.h b/interface/src/raypick/RayPickScriptingInterface.h index 099103e4c5..e7c5dfd5dd 100644 --- a/interface/src/raypick/RayPickScriptingInterface.h +++ b/interface/src/raypick/RayPickScriptingInterface.h @@ -13,26 +13,11 @@ #include -#include +#include "RegisteredMetaTypes.h" #include -#include class RayPickScriptingInterface : public QObject, public Dependency { Q_OBJECT - Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT) - Q_PROPERTY(unsigned int PICK_ENTITIES READ PICK_ENTITIES CONSTANT) - Q_PROPERTY(unsigned int PICK_OVERLAYS READ PICK_OVERLAYS CONSTANT) - Q_PROPERTY(unsigned int PICK_AVATARS READ PICK_AVATARS CONSTANT) - Q_PROPERTY(unsigned int PICK_HUD READ PICK_HUD CONSTANT) - Q_PROPERTY(unsigned int PICK_COARSE READ PICK_COARSE CONSTANT) - Q_PROPERTY(unsigned int PICK_INCLUDE_INVISIBLE READ PICK_INCLUDE_INVISIBLE CONSTANT) - Q_PROPERTY(unsigned int PICK_INCLUDE_NONCOLLIDABLE READ PICK_INCLUDE_NONCOLLIDABLE CONSTANT) - Q_PROPERTY(unsigned int PICK_ALL_INTERSECTIONS READ PICK_ALL_INTERSECTIONS CONSTANT) - Q_PROPERTY(unsigned int INTERSECTED_NONE READ INTERSECTED_NONE CONSTANT) - Q_PROPERTY(unsigned int INTERSECTED_ENTITY READ INTERSECTED_ENTITY CONSTANT) - Q_PROPERTY(unsigned int INTERSECTED_OVERLAY READ INTERSECTED_OVERLAY CONSTANT) - Q_PROPERTY(unsigned int INTERSECTED_AVATAR READ INTERSECTED_AVATAR CONSTANT) - Q_PROPERTY(unsigned int INTERSECTED_HUD READ INTERSECTED_HUD CONSTANT) SINGLETON_DEPENDENCY public slots: @@ -40,26 +25,11 @@ public slots: 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 QVariantMap getPrevRayPickResult(const QUuid& uid); 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 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_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); } - unsigned int INTERSECTED_NONE() { return IntersectionType::NONE; } - unsigned int INTERSECTED_ENTITY() { return IntersectionType::ENTITY; } - unsigned int INTERSECTED_OVERLAY() { return IntersectionType::OVERLAY; } - unsigned int INTERSECTED_AVATAR() { return IntersectionType::AVATAR; } - unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; } }; #endif // hifi_RayPickScriptingInterface_h diff --git a/libraries/pointers/src/pointers/rays/StaticRayPick.cpp b/interface/src/raypick/StaticRayPick.cpp similarity index 70% rename from libraries/pointers/src/pointers/rays/StaticRayPick.cpp rename to interface/src/raypick/StaticRayPick.cpp index e507341021..f7803aade6 100644 --- a/libraries/pointers/src/pointers/rays/StaticRayPick.cpp +++ b/interface/src/raypick/StaticRayPick.cpp @@ -7,13 +7,12 @@ // #include "StaticRayPick.h" -StaticRayPick::StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance, const bool enabled) : +StaticRayPick::StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const PickFilter& filter, const float maxDistance, const bool enabled) : RayPick(filter, maxDistance, enabled), _pickRay(position, direction) { } -const PickRay StaticRayPick::getPickRay(bool& valid) const { - valid = true; +const PickRay StaticRayPick::getMathematicalPick() const { return _pickRay; } \ No newline at end of file diff --git a/libraries/pointers/src/pointers/rays/StaticRayPick.h b/interface/src/raypick/StaticRayPick.h similarity index 75% rename from libraries/pointers/src/pointers/rays/StaticRayPick.h rename to interface/src/raypick/StaticRayPick.h index de5ec234a5..6dc0a809ae 100644 --- a/libraries/pointers/src/pointers/rays/StaticRayPick.h +++ b/interface/src/raypick/StaticRayPick.h @@ -13,9 +13,9 @@ class StaticRayPick : public RayPick { public: - StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const RayPickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false); + StaticRayPick(const glm::vec3& position, const glm::vec3& direction, const PickFilter& filter, const float maxDistance = 0.0f, const bool enabled = false); - const PickRay getPickRay(bool& valid) const override; + const PickRay getMathematicalPick() const override; private: PickRay _pickRay; diff --git a/libraries/pointers/src/pointers/Pick.cpp b/libraries/pointers/src/pointers/Pick.cpp new file mode 100644 index 0000000000..4e48bc906b --- /dev/null +++ b/libraries/pointers/src/pointers/Pick.cpp @@ -0,0 +1,80 @@ +// +// Created by Sam Gondelman 10/17/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 "Pick.h" + +const PickFilter PickFilter::NOTHING; + +PickQuery::PickQuery(const PickFilter& filter, const float maxDistance, const bool enabled) : + _filter(filter), + _maxDistance(maxDistance), + _enabled(enabled) { +} + +void PickQuery::enable(bool enabled) { + withWriteLock([&] { + _enabled = enabled; + }); +} + +PickFilter PickQuery::getFilter() const { + return resultWithReadLock([&] { + return _filter; + }); +} + +float PickQuery::getMaxDistance() const { + return _maxDistance; +} + +bool PickQuery::isEnabled() const { + return resultWithReadLock([&] { + return _enabled; + }); +} + +void PickQuery::setPrecisionPicking(bool precisionPicking) { + withWriteLock([&] { + _filter.setFlag(PickFilter::PICK_COARSE, !precisionPicking); + }); +} + +void PickQuery::setPickResult(const PickResultPointer& pickResult) { + withWriteLock([&] { + _prevResult = pickResult; + }); +} + +QVector PickQuery::getIgnoreItems() const { + return resultWithReadLock>([&] { + return _ignoreItems; + }); +} + +QVector PickQuery::getIncludeItems() const { + return resultWithReadLock>([&] { + return _includeItems; + }); +} + +PickResultPointer PickQuery::getPrevPickResult() const { + return resultWithReadLock([&] { + return _prevResult; + }); +} + +void PickQuery::setIgnoreItems(const QVector& ignoreItems) { + withWriteLock([&] { + _ignoreItems = ignoreItems; + }); +} + +void PickQuery::setIncludeItems(const QVector& includeItems) { + withWriteLock([&] { + _includeItems = includeItems; + }); +} \ No newline at end of file diff --git a/libraries/pointers/src/pointers/rays/RayPick.h b/libraries/pointers/src/pointers/Pick.h similarity index 59% rename from libraries/pointers/src/pointers/rays/RayPick.h rename to libraries/pointers/src/pointers/Pick.h index 5a53891dc6..5dcaba2bb8 100644 --- a/libraries/pointers/src/pointers/rays/RayPick.h +++ b/libraries/pointers/src/pointers/Pick.h @@ -1,22 +1,32 @@ // -// Created by Sam Gondelman 7/11/2017 +// Created by Sam Gondelman 10/17/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 // -#ifndef hifi_RayPick_h -#define hifi_RayPick_h +#ifndef hifi_Pick_h +#define hifi_Pick_h +#include #include #include #include +#include +#include -#include #include -class RayPickFilter { +enum IntersectionType { + NONE = 0, + ENTITY, + OVERLAY, + AVATAR, + HUD +}; + +class PickFilter { public: enum FlagBit { PICK_ENTITIES = 0, @@ -39,11 +49,11 @@ public: // The key is the Flags Flags _flags; - RayPickFilter() {} - RayPickFilter(const Flags& flags) : _flags(flags) {} + PickFilter() {} + PickFilter(const Flags& flags) : _flags(flags) {} - bool operator== (const RayPickFilter& rhs) const { return _flags == rhs._flags; } - bool operator!= (const RayPickFilter& rhs) const { return _flags != rhs._flags; } + bool operator== (const PickFilter& rhs) const { return _flags == rhs._flags; } + bool operator!= (const PickFilter& rhs) const { return _flags != rhs._flags; } void setFlag(FlagBit flag, bool value) { _flags[flag] = value; } @@ -91,36 +101,63 @@ public: static constexpr unsigned int getBitMask(FlagBit bit) { return 1 << bit; } - static const RayPickFilter NOTHING; + static const PickFilter NOTHING; }; -class RayPick : protected ReadWriteLockable { - +class PickResult { public: - using Pointer = std::shared_ptr; + PickResult() {} + PickResult(const QVariantMap& pickVariant) : pickVariant(pickVariant) {} - RayPick(const RayPickFilter& filter, const float maxDistance, const bool enabled); + virtual QVariantMap toVariantMap() const { + return pickVariant; + } - virtual const PickRay getPickRay(bool& valid) const = 0; + virtual bool doesIntersect() const = 0; + + // for example: if we want the closest result, compare based on distance + // if we want all results, combine them + // must return a new pointer + virtual std::shared_ptr compareAndProcessNewResult(const std::shared_ptr newRes) = 0; + + // returns true if this result contains any valid results with distance < maxDistance + // can also filter out results with distance >= maxDistance + virtual bool checkOrFilterAgainstMaxDistance(float maxDistance) = 0; + + QVariantMap pickVariant; +}; + +using PickResultPointer = std::shared_ptr; + +class PickQuery : protected ReadWriteLockable { + Q_GADGET +public: + PickQuery(const PickFilter& filter, const float maxDistance, const bool enabled); + + enum PickType { + Ray = 0, + Stylus + }; + Q_ENUM(PickType) void enable(bool enabled = true); void disable() { enable(false); } - RayPickFilter getFilter() const; + PickFilter getFilter() const; float getMaxDistance() const; bool isEnabled() const; - RayPickResult getPrevRayPickResult() const; void setPrecisionPicking(bool precisionPicking); - void setRayPickResult(const RayPickResult& rayPickResult); + PickResultPointer getPrevPickResult() const; + void setPickResult(const PickResultPointer& pickResult); QVector getIgnoreItems() const; QVector getIncludeItems() const; - template - QVector getIgnoreItemsAs() const { - QVector result; + template + QVector getIgnoreItemsAs() const { + QVector result; withReadLock([&] { for (const auto& uid : _ignoreItems) { result.push_back(uid); @@ -129,9 +166,9 @@ public: return result; } - template - QVector getIncludeItemsAs() const { - QVector result; + template + QVector getIncludeItemsAs() const { + QVector result; withReadLock([&] { for (const auto& uid : _includeItems) { result.push_back(uid); @@ -144,13 +181,26 @@ public: void setIncludeItems(const QVector& items); private: - RayPickFilter _filter; + PickFilter _filter; const float _maxDistance; bool _enabled; - RayPickResult _prevResult; + PickResultPointer _prevResult; QVector _ignoreItems; QVector _includeItems; }; -#endif // hifi_RayPick_h +template +class Pick : public PickQuery { +public: + Pick(const PickFilter& filter, const float maxDistance, const bool enabled) : PickQuery(filter, maxDistance, enabled) {} + + virtual const T getMathematicalPick() const = 0; + virtual PickResultPointer getDefaultResult(const QVariantMap& pickVariant) const = 0; + virtual PickResultPointer getEntityIntersection(const T& pick) = 0; + virtual PickResultPointer getOverlayIntersection(const T& pick) = 0; + virtual PickResultPointer getAvatarIntersection(const T& pick) = 0; + virtual PickResultPointer getHUDIntersection(const T& pick) = 0; +}; + +#endif // hifi_Pick_h diff --git a/libraries/pointers/src/pointers/PickCacheOptimizer.h b/libraries/pointers/src/pointers/PickCacheOptimizer.h new file mode 100644 index 0000000000..c4bf96ab51 --- /dev/null +++ b/libraries/pointers/src/pointers/PickCacheOptimizer.h @@ -0,0 +1,127 @@ +// +// Created by Sam Gondelman 10/16/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 +// +#ifndef hifi_PickCacheOptimizer_h +#define hifi_PickCacheOptimizer_h + +#include + +#include "Pick.h" + +typedef struct PickCacheKey { + PickFilter::Flags mask; + QVector include; + QVector ignore; + + bool operator==(const PickCacheKey& other) const { + return (mask == other.mask && include == other.include && ignore == other.ignore); + } +} PickCacheKey; + +namespace std { + template <> + struct hash { + size_t operator()(const PickCacheKey& k) const { + return ((hash()(k.mask) ^ (qHash(k.include) << 1)) >> 1) ^ (qHash(k.ignore) << 1); + } + }; +} + +// T is a mathematical representation of a Pick (a MathPick) +// For example: RayPicks use T = PickRay +template +class PickCacheOptimizer { + +public: + void update(QHash>& picks, bool shouldPickHUD); + +protected: + typedef std::unordered_map> PickCache; + + // Returns true if this pick exists in the cache, and if it does, update res if the cached result is closer + bool checkAndCompareCachedResults(T& pick, PickCache& cache, PickResultPointer& res, const PickCacheKey& key); + void cacheResult(const bool intersects, const PickResultPointer& resTemp, const PickCacheKey& key, PickResultPointer& res, T& mathPick, PickCache& cache, const std::shared_ptr> pick); +}; + +template +bool PickCacheOptimizer::checkAndCompareCachedResults(T& pick, PickCache& cache, PickResultPointer& res, const PickCacheKey& key) { + if (cache.find(pick) != cache.end() && cache[pick].find(key) != cache[pick].end()) { + res = res->compareAndProcessNewResult(cache[pick][key]); + return true; + } + return false; +} + +template +void PickCacheOptimizer::cacheResult(const bool intersects, const PickResultPointer& resTemp, const PickCacheKey& key, PickResultPointer& res, T& mathPick, PickCache& cache, const std::shared_ptr> pick) { + if (intersects) { + cache[mathPick][key] = resTemp; + res = res->compareAndProcessNewResult(resTemp); + } else { + cache[mathPick][key] = pick->getDefaultResult(mathPick.toVariantMap()); + } +} + +template +void PickCacheOptimizer::update(QHash>& picks, bool shouldPickHUD) { + PickCache results; + for (const auto& uid : picks.keys()) { + std::shared_ptr> pick = std::static_pointer_cast>(picks[uid]); + if (!pick->isEnabled() || pick->getFilter().doesPickNothing() || pick->getMaxDistance() < 0.0f) { + continue; + } + + T mathematicalPick = pick->getMathematicalPick(); + + if (!mathematicalPick) { + continue; + } + + PickResultPointer res = pick->getDefaultResult(mathematicalPick.toVariantMap()); + + if (pick->getFilter().doesPickEntities()) { + PickCacheKey entityKey = { pick->getFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; + if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) { + PickResultPointer entityRes = pick->getEntityIntersection(mathematicalPick); + cacheResult(entityRes->doesIntersect(), entityRes, entityKey, res, mathematicalPick, results, pick); + } + } + + if (pick->getFilter().doesPickOverlays()) { + PickCacheKey overlayKey = { pick->getFilter().getOverlayFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; + if (!checkAndCompareCachedResults(mathematicalPick, results, res, overlayKey)) { + PickResultPointer overlayRes = pick->getOverlayIntersection(mathematicalPick); + cacheResult(overlayRes->doesIntersect(), overlayRes, overlayKey, res, mathematicalPick, results, pick); + } + } + + if (pick->getFilter().doesPickAvatars()) { + PickCacheKey avatarKey = { pick->getFilter().getAvatarFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; + if (!checkAndCompareCachedResults(mathematicalPick, results, res, avatarKey)) { + PickResultPointer avatarRes = pick->getAvatarIntersection(mathematicalPick); + cacheResult(avatarRes->doesIntersect(), avatarRes, avatarKey, res, mathematicalPick, results, pick); + } + } + + // Can't intersect with HUD in desktop mode + if (pick->getFilter().doesPickHUD() && shouldPickHUD) { + PickCacheKey hudKey = { pick->getFilter().getHUDFlags(), QVector(), QVector() }; + if (!checkAndCompareCachedResults(mathematicalPick, results, res, hudKey)) { + PickResultPointer hudRes = pick->getHUDIntersection(mathematicalPick); + cacheResult(true, hudRes, hudKey, res, mathematicalPick, results, pick); + } + } + + if (pick->getMaxDistance() == 0.0f || (pick->getMaxDistance() > 0.0f && res->checkOrFilterAgainstMaxDistance(pick->getMaxDistance()))) { + pick->setPickResult(res); + } else { + pick->setPickResult(pick->getDefaultResult(mathematicalPick.toVariantMap())); + } + } +} + +#endif // hifi_PickCacheOptimizer_h \ No newline at end of file diff --git a/libraries/pointers/src/pointers/PickManager.cpp b/libraries/pointers/src/pointers/PickManager.cpp new file mode 100644 index 0000000000..571f9f04cd --- /dev/null +++ b/libraries/pointers/src/pointers/PickManager.cpp @@ -0,0 +1,94 @@ +// +// Created by Sam Gondelman 10/19/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 "PickManager.h" + +PickManager::PickManager() { + setShouldPickHUDOperator([]() { return false; }); +} + +QUuid PickManager::addPick(PickQuery::PickType type, const std::shared_ptr pick) { + QUuid id = QUuid::createUuid(); + withWriteLock([&] { + _picks[type][id] = pick; + _typeMap[id] = type; + }); + return id; +} + +std::shared_ptr PickManager::findPick(const QUuid& uid) const { + return resultWithReadLock>([&] { + auto type = _typeMap.find(uid); + if (type != _typeMap.end()) { + return _picks[type.value()][uid]; + } + return std::shared_ptr(); + }); +} + +void PickManager::removePick(const QUuid& uid) { + withWriteLock([&] { + auto type = _typeMap.find(uid); + if (type != _typeMap.end()) { + _picks[type.value()].remove(uid); + _typeMap.remove(uid); + } + }); +} + +QVariantMap PickManager::getPrevPickResult(const QUuid& uid) const { + auto pick = findPick(uid); + if (pick && pick->getPrevPickResult()) { + return pick->getPrevPickResult()->toVariantMap(); + } + return QVariantMap(); +} + +void PickManager::enablePick(const QUuid& uid) const { + auto pick = findPick(uid); + if (pick) { + pick->enable(); + } +} + +void PickManager::disablePick(const QUuid& uid) const { + auto pick = findPick(uid); + if (pick) { + pick->disable(); + } +} + +void PickManager::setPrecisionPicking(const QUuid& uid, bool precisionPicking) const { + auto pick = findPick(uid); + if (pick) { + pick->setPrecisionPicking(precisionPicking); + } +} + +void PickManager::setIgnoreItems(const QUuid& uid, const QVector& ignore) const { + auto pick = findPick(uid); + if (pick) { + pick->setIgnoreItems(ignore); + } +} + +void PickManager::setIncludeItems(const QUuid& uid, const QVector& include) const { + auto pick = findPick(uid); + if (pick) { + pick->setIncludeItems(include); + } +} + +void PickManager::update() { + QHash>> cachedPicks; + withReadLock([&] { + cachedPicks = _picks; + }); + + bool shouldPickHUD = _shouldPickHUDOperator(); + _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], shouldPickHUD); +} \ No newline at end of file diff --git a/libraries/pointers/src/pointers/PickManager.h b/libraries/pointers/src/pointers/PickManager.h new file mode 100644 index 0000000000..b8abb077c7 --- /dev/null +++ b/libraries/pointers/src/pointers/PickManager.h @@ -0,0 +1,48 @@ +// +// Created by Sam Gondelman 10/16/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 +// +#ifndef hifi_PickManager_h +#define hifi_PickManager_h + +#include +#include "RegisteredMetaTypes.h" + +#include "Pick.h" +#include "PickCacheOptimizer.h" + +class PickManager : public Dependency, protected ReadWriteLockable { + SINGLETON_DEPENDENCY + +public: + PickManager(); + + void update(); + + QUuid addPick(PickQuery::PickType type, const std::shared_ptr pick); + void removePick(const QUuid& uid); + void enablePick(const QUuid& uid) const; + void disablePick(const QUuid& uid) const; + + QVariantMap getPrevPickResult(const QUuid& uid) const; + + 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; + + void setShouldPickHUDOperator(std::function shouldPickHUDOperator) { _shouldPickHUDOperator = shouldPickHUDOperator; } + +protected: + std::function _shouldPickHUDOperator; + + std::shared_ptr findPick(const QUuid& uid) const; + QHash>> _picks; + QHash _typeMap; + + PickCacheOptimizer _rayPickCacheOptimizer; +}; + +#endif // hifi_PickManager_h \ No newline at end of file diff --git a/libraries/pointers/src/pointers/Pointer.cpp b/libraries/pointers/src/pointers/Pointer.cpp new file mode 100644 index 0000000000..6ba8c6072c --- /dev/null +++ b/libraries/pointers/src/pointers/Pointer.cpp @@ -0,0 +1,39 @@ +// +// Created by Sam Gondelman 10/19/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 "Pointer.h" + +#include +#include "PickManager.h" + +Pointer::~Pointer() { + DependencyManager::get()->removePick(_pickUID); +} + +void Pointer::enable() { + DependencyManager::get()->enablePick(_pickUID); +} + +void Pointer::disable() { + DependencyManager::get()->disablePick(_pickUID); +} + +const QVariantMap Pointer::getPrevPickResult() { + return DependencyManager::get()->getPrevPickResult(_pickUID); +} + +void Pointer::setPrecisionPicking(const bool precisionPicking) { + DependencyManager::get()->setPrecisionPicking(_pickUID, precisionPicking); +} + +void Pointer::setIgnoreItems(const QVector& ignoreItems) const { + DependencyManager::get()->setIgnoreItems(_pickUID, ignoreItems); +} + +void Pointer::setIncludeItems(const QVector& includeItems) const { + DependencyManager::get()->setIncludeItems(_pickUID, includeItems); +} \ No newline at end of file diff --git a/libraries/pointers/src/pointers/Pointer.h b/libraries/pointers/src/pointers/Pointer.h new file mode 100644 index 0000000000..4a105f8a92 --- /dev/null +++ b/libraries/pointers/src/pointers/Pointer.h @@ -0,0 +1,46 @@ +// +// Created by Sam Gondelman 10/17/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 +// +#ifndef hifi_Pointer_h +#define hifi_Pointer_h + +#include +#include +#include + +#include + +class Pointer : protected ReadWriteLockable { +public: + Pointer(const QUuid& uid) : _pickUID(uid) {} + + virtual ~Pointer(); + + virtual void enable(); + virtual void disable(); + virtual const QVariantMap getPrevPickResult(); + + virtual void setRenderState(const std::string& state) = 0; + virtual void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) = 0; + + virtual void setPrecisionPicking(const bool precisionPicking); + virtual void setIgnoreItems(const QVector& ignoreItems) const; + virtual void setIncludeItems(const QVector& includeItems) const; + + // Pointers can choose to implement these + virtual void setLength(const float length) {} + virtual void setLockEndUUID(QUuid objectID, const bool isOverlay) {} + + virtual void update() = 0; + + QUuid getRayUID() { return _pickUID; } + +protected: + const QUuid _pickUID; +}; + +#endif // hifi_Pick_h diff --git a/libraries/pointers/src/pointers/PointerManager.cpp b/libraries/pointers/src/pointers/PointerManager.cpp index 63bd983420..a475ba4d83 100644 --- a/libraries/pointers/src/pointers/PointerManager.cpp +++ b/libraries/pointers/src/pointers/PointerManager.cpp @@ -1,6 +1,115 @@ +// +// 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 +// + #include "PointerManager.h" -PointerManager::PointerManager() { - +std::shared_ptr PointerManager::find(const QUuid& uid) const { + return resultWithReadLock>([&] { + auto itr = _pointers.find(uid); + if (itr != _pointers.end()) { + return *itr; + } + return std::shared_ptr(); + }); } +QUuid PointerManager::addPointer(std::shared_ptr pointer) { + QUuid result; + if (!pointer->getRayUID().isNull()) { + result = QUuid::createUuid(); + withWriteLock([&] { _pointers[result] = pointer; }); + } + return result; +} + +void PointerManager::removePointer(const QUuid& uid) { + withWriteLock([&] { + _pointers.remove(uid); + }); +} + +void PointerManager::enablePointer(const QUuid& uid) const { + auto pointer = find(uid); + if (pointer) { + pointer->enable(); + } +} + +void PointerManager::disablePointer(const QUuid& uid) const { + auto pointer = find(uid); + if (pointer) { + pointer->disable(); + } +} + +void PointerManager::setRenderState(const QUuid& uid, const std::string& renderState) const { + auto pointer = find(uid); + if (pointer) { + pointer->setRenderState(renderState); + } +} + +void PointerManager::editRenderState(const QUuid& uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) const { + auto pointer = find(uid); + if (pointer) { + pointer->editRenderState(state, startProps, pathProps, endProps); + } +} + +const QVariantMap PointerManager::getPrevPickResult(const QUuid& uid) const { + auto pointer = find(uid); + if (pointer) { + return pointer->getPrevPickResult(); + } + return QVariantMap(); +} + +void PointerManager::update() { + auto cachedPointers = resultWithReadLock>>([&] { + return _pointers.values(); + }); + + for (const auto& pointer : cachedPointers) { + pointer->update(); + } +} + +void PointerManager::setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const { + auto pointer = find(uid); + if (pointer) { + pointer->setPrecisionPicking(precisionPicking); + } +} + +void PointerManager::setIgnoreItems(const QUuid& uid, const QVector& ignoreEntities) const { + auto pointer = find(uid); + if (pointer) { + pointer->setIgnoreItems(ignoreEntities); + } +} + +void PointerManager::setIncludeItems(const QUuid& uid, const QVector& includeEntities) const { + auto pointer = find(uid); + if (pointer) { + pointer->setIncludeItems(includeEntities); + } +} + +void PointerManager::setLength(const QUuid& uid, const float length) const { + auto pointer = find(uid); + if (pointer) { + pointer->setLength(length); + } +} + +void PointerManager::setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const { + auto pointer = find(uid); + if (pointer) { + pointer->setLockEndUUID(objectID, isOverlay); + } +} diff --git a/libraries/pointers/src/pointers/PointerManager.h b/libraries/pointers/src/pointers/PointerManager.h index 16f854bff5..2ec5921e3c 100644 --- a/libraries/pointers/src/pointers/PointerManager.h +++ b/libraries/pointers/src/pointers/PointerManager.h @@ -11,11 +11,38 @@ #include #include -class PointerManager : public QObject, public Dependency { +#include + +#include + +#include "Pointer.h" + +class PointerManager : public QObject, public Dependency, protected ReadWriteLockable { Q_OBJECT SINGLETON_DEPENDENCY public: - PointerManager(); + PointerManager() {} + + QUuid addPointer(std::shared_ptr pointer); + void removePointer(const QUuid& uid); + void enablePointer(const QUuid& uid) const; + void disablePointer(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 QVariantMap getPrevPickResult(const QUuid& uid) const; + + void setPrecisionPicking(const QUuid& uid, const bool precisionPicking) const; + void setIgnoreItems(const QUuid& uid, const QVector& ignoreEntities) const; + void setIncludeItems(const QUuid& uid, const QVector& includeEntities) const; + + void setLength(const QUuid& uid, const float length) const; + void setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const; + + void update(); + +private: + std::shared_ptr find(const QUuid& uid) const; + QHash> _pointers; signals: void triggerBegin(const QUuid& id, const PointerEvent& pointerEvent); diff --git a/libraries/pointers/src/pointers/rays/RayPick.cpp b/libraries/pointers/src/pointers/rays/RayPick.cpp deleted file mode 100644 index bc3a05cd7a..0000000000 --- a/libraries/pointers/src/pointers/rays/RayPick.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// -// 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 resultWithReadLock([&] { - 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 resultWithReadLock>([&] { - return _ignoreItems; - }); -} - -QVector RayPick::getIncludeItems() const { - return resultWithReadLock>([&] { - 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/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 7d0df3ac78..b4d6ebaa7a 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -34,7 +34,6 @@ int vec2MetaTypeId = qRegisterMetaType(); int quatMetaTypeId = qRegisterMetaType(); int xColorMetaTypeId = qRegisterMetaType(); int pickRayMetaTypeId = qRegisterMetaType(); -int rayPickResultMetaTypeId = qRegisterMetaType(); int collisionMetaTypeId = qRegisterMetaType(); int qMapURLStringMetaTypeId = qRegisterMetaType>(); int socketErrorMetaTypeId = qRegisterMetaType(); @@ -57,7 +56,6 @@ void registerMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue); qScriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue); qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue); - qScriptRegisterMetaType(engine, rayPickResultToScriptValue, rayPickResultFromScriptValue); qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue); qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue); qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue); @@ -753,26 +751,6 @@ void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay) { } } -QScriptValue rayPickResultToScriptValue(QScriptEngine* engine, const RayPickResult& rayPickResult) { - QScriptValue obj = engine->newObject(); - obj.setProperty("type", rayPickResult.type); - QScriptValue objectID = quuidToScriptValue(engine, rayPickResult.objectID); - obj.setProperty("objectID", objectID); - obj.setProperty("distance", rayPickResult.distance); - QScriptValue intersection = vec3toScriptValue(engine, rayPickResult.intersection); - obj.setProperty("intersection", intersection); - obj.setProperty("intersects", rayPickResult.type != NONE); - QScriptValue searchRay = pickRayToScriptValue(engine, rayPickResult.searchRay); - obj.setProperty("searchRay", searchRay); - QScriptValue surfaceNormal = vec3toScriptValue(engine, rayPickResult.surfaceNormal); - obj.setProperty("surfaceNormal", surfaceNormal); - return obj; -} - -void rayPickResultFromScriptValue(const QScriptValue& object, RayPickResult& rayPickResult) { - // TODO: cannot currently accept RayPickResults from JS -} - QScriptValue collisionToScriptValue(QScriptEngine* engine, const Collision& collision) { QScriptValue obj = engine->newObject(); obj.setProperty("type", collision.type); diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 7b7d8d8f47..a716c9231e 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -125,42 +125,51 @@ QVector qVectorQUuidFromScriptValue(const QScriptValue& array); QScriptValue aaCubeToScriptValue(QScriptEngine* engine, const AACube& aaCube); void aaCubeFromScriptValue(const QScriptValue &object, AACube& aaCube); -class PickRay { +// MathPicks also have to overide operator== for their type +class MathPick { + virtual operator bool() const = 0; + virtual QVariantMap toVariantMap() const = 0; +}; + +class PickRay : public MathPick { public: - PickRay() : origin(0.0f), direction(0.0f) { } + PickRay() : origin(NAN), direction(NAN) { } + PickRay(const QVariantMap& pickVariant) : origin(vec3FromVariant(pickVariant["origin"])), direction(vec3FromVariant(pickVariant["direction"])) {} PickRay(const glm::vec3& origin, const glm::vec3 direction) : origin(origin), direction(direction) {} glm::vec3 origin; glm::vec3 direction; + + operator bool() const override { + return !(glm::any(glm::isnan(origin)) || glm::any(glm::isnan(direction))); + } + bool operator==(const PickRay& other) const { + return (origin == other.origin && direction == other.direction); + } + QVariantMap toVariantMap() const override { + QVariantMap pickRay; + pickRay["origin"] = vec3toVariant(origin); + pickRay["direction"] = vec3toVariant(direction); + return pickRay; + } }; +namespace std { + template <> + struct hash { + size_t operator()(const glm::vec3& a) const { + return ((hash()(a.x) ^ (hash()(a.y) << 1)) >> 1) ^ (hash()(a.z) << 1); + } + }; + template <> + struct hash { + size_t operator()(const PickRay& a) const { + return (hash()(a.origin) ^ (hash()(a.direction) << 1)); + } + }; +} Q_DECLARE_METATYPE(PickRay) QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay); void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay); -enum IntersectionType { - NONE = 0, - ENTITY, - OVERLAY, - AVATAR, - HUD -}; - -class RayPickResult { -public: - RayPickResult() {} - RayPickResult(const PickRay& searchRay) : searchRay(searchRay) {} - RayPickResult(const IntersectionType type, const QUuid& objectID, const float distance, const glm::vec3& intersection, const PickRay& searchRay, const glm::vec3& surfaceNormal = glm::vec3(NAN)) : - type(type), objectID(objectID), distance(distance), intersection(intersection), searchRay(searchRay), surfaceNormal(surfaceNormal) {} - IntersectionType type { NONE }; - QUuid objectID; - float distance { FLT_MAX }; - glm::vec3 intersection { NAN }; - PickRay searchRay; - glm::vec3 surfaceNormal { NAN }; -}; -Q_DECLARE_METATYPE(RayPickResult) -QScriptValue rayPickResultToScriptValue(QScriptEngine* engine, const RayPickResult& rayPickResult); -void rayPickResultFromScriptValue(const QScriptValue& object, RayPickResult& rayPickResult); - enum ContactEventType { CONTACT_EVENT_TYPE_START, CONTACT_EVENT_TYPE_CONTINUE, diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 2deef5f9fa..3bc423450e 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -252,7 +252,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); length: 1000 }; - if (rayPicks[h].type === RayPick.INTERSECTED_ENTITY) { + if (rayPicks[h].type === Picks.INTERSECTED_ENTITY) { // XXX check to make sure this one isn't already in nearbyEntityProperties? if (rayPicks[h].distance < NEAR_GRAB_PICK_RADIUS * sensorScaleFactor) { var nearEntityID = rayPicks[h].objectID; @@ -390,35 +390,35 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.leftControllerRayPick = RayPick.createRayPick({ joint: "_CONTROLLER_LEFTHAND", - filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, + filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS, enabled: true, maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE, posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand, true) }); this.leftControllerHudRayPick = RayPick.createRayPick({ joint: "_CONTROLLER_LEFTHAND", - filter: RayPick.PICK_HUD, + filter: Picks.PICK_HUD, enabled: true, maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE, posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand, true) }); this.rightControllerRayPick = RayPick.createRayPick({ joint: "_CONTROLLER_RIGHTHAND", - filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, + filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS, enabled: true, maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE, posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand, true) }); this.rightControllerHudRayPick = RayPick.createRayPick({ joint: "_CONTROLLER_RIGHTHAND", - filter: RayPick.PICK_HUD, + filter: Picks.PICK_HUD, enabled: true, maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE, posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand, true) }); this.mouseRayPick = RayPick.createRayPick({ joint: "Mouse", - filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, + filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS, enabled: true }); diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 3e980d7f16..7d2f62cc47 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -370,8 +370,8 @@ Script.include("/~/system/libraries/controllers.js"); var entityType = entityProperty.type; var hudRayPick = controllerData.hudRayPicks[this.hand]; var point2d = this.calculateNewReticlePosition(hudRayPick.intersection); - if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || - intersection.type === RayPick.INTERSECTED_OVERLAY || Window.isPointOnDesktopWindow(point2d)) { + if ((intersection.type === Picks.INTERSECTED_ENTITY && entityType === "Web") || + intersection.type === Picks.INTERSECTED_OVERLAY || Window.isPointOnDesktopWindow(point2d)) { return true; } return false; @@ -491,7 +491,7 @@ Script.include("/~/system/libraries/controllers.js"); } var rayPickInfo = controllerData.rayPicks[this.hand]; - if (rayPickInfo.type === RayPick.INTERSECTED_ENTITY) { + if (rayPickInfo.type === Picks.INTERSECTED_ENTITY) { if (controllerData.triggerClicks[this.hand]) { var entityID = rayPickInfo.objectID; var targetProps = Entities.getEntityProperties(entityID, [ @@ -573,7 +573,7 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPointer = LaserPointers.createLaserPointer({ joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", - filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, + filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS, maxDistance: PICK_MAX_DISTANCE, posOffset: getGrabPointSphereOffset(this.handToController(), true), renderStates: renderStates, diff --git a/scripts/system/controllers/controllerModules/farTrigger.js b/scripts/system/controllers/controllerModules/farTrigger.js index 84d4c4d307..a39124e76f 100644 --- a/scripts/system/controllers/controllerModules/farTrigger.js +++ b/scripts/system/controllers/controllerModules/farTrigger.js @@ -184,7 +184,7 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPointer = LaserPointers.createLaserPointer({ joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", - filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, + filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS, maxDistance: PICK_MAX_DISTANCE, posOffset: getGrabPointSphereOffset(this.handToController(), true), renderStates: renderStates, diff --git a/scripts/system/controllers/controllerModules/hudOverlayPointer.js b/scripts/system/controllers/controllerModules/hudOverlayPointer.js index 9576b3ecc9..875599fa47 100644 --- a/scripts/system/controllers/controllerModules/hudOverlayPointer.js +++ b/scripts/system/controllers/controllerModules/hudOverlayPointer.js @@ -207,7 +207,7 @@ this.laserPointer = LaserPointers.createLaserPointer({ joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND", - filter: RayPick.PICK_HUD, + filter: Picks.PICK_HUD, maxDistance: PICK_MAX_DISTANCE, posOffset: getGrabPointSphereOffset(this.handToController(), true), renderStates: renderStates, diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index 369204fbd3..e44c9f9848 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -146,12 +146,12 @@ Script.include("/~/system/libraries/utils.js"); this.sendPickData = function(controllerData) { if (controllerData.triggerClicks[this.hand] && !this.triggerClicked) { var intersection = controllerData.rayPicks[this.hand]; - if (intersection.type === RayPick.INTERSECTED_ENTITY) { + if (intersection.type === Picks.INTERSECTED_ENTITY) { Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({ method: "selectEntity", entityID: intersection.objectID })); - } else if (intersection.type === RayPick.INTERSECTED_OVERLAY) { + } else if (intersection.type === Picks.INTERSECTED_OVERLAY) { Messages.sendLocalMessage("entityToolUpdates", JSON.stringify({ method: "selectOverlay", overlayID: intersection.objectID @@ -232,7 +232,7 @@ Script.include("/~/system/libraries/utils.js"); this.laserPointer = LaserPointers.createLaserPointer({ joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND", - filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, + filter: Picks.PICK_ENTITIES | Picks.PICK_OVERLAYS, maxDistance: PICK_MAX_DISTANCE, posOffset: getGrabPointSphereOffset(this.handToController(), true), renderStates: renderStates, diff --git a/scripts/system/controllers/controllerModules/overlayLaserInput.js b/scripts/system/controllers/controllerModules/overlayLaserInput.js index 06eeb78a41..c517ab627e 100644 --- a/scripts/system/controllers/controllerModules/overlayLaserInput.js +++ b/scripts/system/controllers/controllerModules/overlayLaserInput.js @@ -294,7 +294,7 @@ Script.include("/~/system/libraries/controllers.js"); this.shouldExit = function(controllerData) { var intersection = controllerData.rayPicks[this.hand]; - var offOverlay = (intersection.type !== RayPick.INTERSECTED_OVERLAY); + var offOverlay = (intersection.type !== Picks.INTERSECTED_OVERLAY); var triggerOff = (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE); if (triggerOff) { this.deleteContextOverlay(); @@ -366,7 +366,7 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPointer = LaserPointers.createLaserPointer({ joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND", - filter: RayPick.PICK_OVERLAYS, + filter: Picks.PICK_OVERLAYS, maxDistance: PICK_MAX_DISTANCE, posOffset: getGrabPointSphereOffset(this.handToController(), true), renderStates: renderStates, diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 86ad9c56ca..1fb867675e 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -149,7 +149,7 @@ Script.include("/~/system/libraries/controllers.js"); this.teleportRayHandVisible = LaserPointers.createLaserPointer({ joint: (_this.hand === RIGHT_HAND) ? "RightHand" : "LeftHand", - filter: RayPick.PICK_ENTITIES, + filter: Picks.PICK_ENTITIES, faceAvatar: true, centerEndY: false, renderStates: teleportRenderStates, @@ -157,14 +157,14 @@ Script.include("/~/system/libraries/controllers.js"); }); this.teleportRayHandInvisible = LaserPointers.createLaserPointer({ joint: (_this.hand === RIGHT_HAND) ? "RightHand" : "LeftHand", - filter: RayPick.PICK_ENTITIES | RayPick.PICK_INCLUDE_INVISIBLE, + filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, faceAvatar: true, centerEndY: false, renderStates: teleportRenderStates }); this.teleportRayHeadVisible = LaserPointers.createLaserPointer({ joint: "Avatar", - filter: RayPick.PICK_ENTITIES, + filter: Picks.PICK_ENTITIES, faceAvatar: true, centerEndY: false, renderStates: teleportRenderStates, @@ -172,7 +172,7 @@ Script.include("/~/system/libraries/controllers.js"); }); this.teleportRayHeadInvisible = LaserPointers.createLaserPointer({ joint: "Avatar", - filter: RayPick.PICK_ENTITIES | RayPick.PICK_INCLUDE_INVISIBLE, + filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, faceAvatar: true, centerEndY: false, renderStates: teleportRenderStates @@ -397,7 +397,7 @@ Script.include("/~/system/libraries/controllers.js"); // you can't teleport there. var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70; function getTeleportTargetType(result) { - if (result.type === RayPick.INTERSECTED_NONE) { + if (result.type === Picks.INTERSECTED_NONE) { return TARGET.NONE; } diff --git a/scripts/system/controllers/controllerModules/webEntityLaserInput.js b/scripts/system/controllers/controllerModules/webEntityLaserInput.js index 62cb05f32f..32ff7cbf44 100644 --- a/scripts/system/controllers/controllerModules/webEntityLaserInput.js +++ b/scripts/system/controllers/controllerModules/webEntityLaserInput.js @@ -379,7 +379,7 @@ Script.include("/~/system/libraries/controllers.js"); var entityProperty = Entities.getEntityProperties(intersection.objectID); var entityType = entityProperty.type; - if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web")) { + if ((intersection.type === Picks.INTERSECTED_ENTITY && entityType === "Web")) { return true; } return false; @@ -447,7 +447,7 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPointer = LaserPointers.createLaserPointer({ joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND", - filter: RayPick.PICK_ENTITIES, + filter: Picks.PICK_ENTITIES, maxDistance: PICK_MAX_DISTANCE, posOffset: getGrabPointSphereOffset(this.handToController(), true), renderStates: renderStates, diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index a1846e7ad7..7e575e38b0 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -260,14 +260,14 @@ function Grabber() { this.mouseRayOverlays = RayPick.createRayPick({ joint: "Mouse", - filter: RayPick.PICK_OVERLAYS, + filter: Picks.PICK_OVERLAYS, enabled: true }); RayPick.setIncludeItems(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); var renderStates = [{name: "grabbed", end: beacon}]; this.mouseRayEntities = LaserPointers.createLaserPointer({ joint: "Mouse", - filter: RayPick.PICK_ENTITIES, + filter: Picks.PICK_ENTITIES, faceAvatar: true, enabled: true, renderStates: renderStates @@ -321,12 +321,12 @@ Grabber.prototype.pressEvent = function(event) { } var overlayResult = RayPick.getPrevRayPickResult(this.mouseRayOverlays); - if (overlayResult.type != RayPick.INTERSECTED_NONE) { + if (overlayResult.type != Picks.INTERSECTED_NONE) { return; } var pickResults = LaserPointers.getPrevRayPickResult(this.mouseRayEntities); - if (pickResults.type == RayPick.INTERSECTED_NONE) { + if (pickResults.type == Picks.INTERSECTED_NONE) { LaserPointers.setRenderState(this.mouseRayEntities, ""); return; } diff --git a/scripts/system/libraries/touchEventUtils.js b/scripts/system/libraries/touchEventUtils.js index fbd56e16ae..7d19181c2a 100644 --- a/scripts/system/libraries/touchEventUtils.js +++ b/scripts/system/libraries/touchEventUtils.js @@ -130,7 +130,7 @@ function sendTouchMoveEventToTouchTarget(hand, touchTarget) { } function composeTouchTargetFromIntersection(intersection) { - var isEntity = (intersection.type === RayPick.INTERSECTED_ENTITY); + var isEntity = (intersection.type === Picks.INTERSECTED_ENTITY); var objectID = intersection.objectID; var worldPos = intersection.intersection; var props = null;