From 429905de51d1f11ff9074f4797922b8c47f4b033 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 16 Oct 2017 15:52:17 -0700 Subject: [PATCH] update scripts to use ignoreItems, fix caching bug --- interface/src/raypick/LaserPointer.cpp | 10 +++-- interface/src/raypick/RayPickManager.cpp | 37 ++++++++++--------- interface/src/raypick/RayPickManager.h | 25 +++++++++++-- .../src/raypick/RayPickScriptingInterface.h | 2 +- .../pointers/src/pointers/PointerManager.h | 2 +- .../pointers/src/pointers/rays/RayPick.h | 8 ---- .../controllers/controllerDispatcher.js | 12 +++--- .../controllerModules/inEditMode.js | 9 ++++- .../controllerModules/overlayLaserInput.js | 7 +++- .../controllers/controllerModules/teleport.js | 8 ++-- scripts/system/controllers/grab.js | 2 +- 11 files changed, 76 insertions(+), 46 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 7fa5eaed5f..a2f7c7a521 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -58,8 +58,8 @@ void LaserPointer::enable() { void LaserPointer::disable() { qApp->getRayPickManager().disableRayPick(_rayPickUID); - _renderingEnabled = false; withWriteLock([&] { + _renderingEnabled = false; if (!_currentRenderState.empty()) { if (_renderStates.find(_currentRenderState) != _renderStates.end()) { disableRenderState(_renderStates[_currentRenderState]); @@ -219,11 +219,15 @@ void LaserPointer::setPrecisionPicking(const bool precisionPicking) { } void LaserPointer::setLaserLength(const float laserLength) { - _laserLength = laserLength; + withWriteLock([&] { + _laserLength = laserLength; + }); } void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) { - _objectLockEnd = std::pair(objectID, isOverlay); + withWriteLock([&] { + _objectLockEnd = std::pair(objectID, isOverlay); + }); } void LaserPointer::setIgnoreItems(const QVector& ignoreItems) const { diff --git a/interface/src/raypick/RayPickManager.cpp b/interface/src/raypick/RayPickManager.cpp index f3425a2b28..beb0075428 100644 --- a/interface/src/raypick/RayPickManager.cpp +++ b/interface/src/raypick/RayPickManager.cpp @@ -22,24 +22,24 @@ #include "JointRayPick.h" #include "MouseRayPick.h" -bool RayPickManager::checkAndCompareCachedResults(QPair& ray, RayPickCache& cache, RayPickResult& res, const RayPickFilter::Flags& mask) { - if (cache.contains(ray) && cache[ray].find(mask) != cache[ray].end()) { - if (cache[ray][mask].distance < res.distance) { - res = cache[ray][mask]; +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 RayPickFilter::Flags& mask, RayPickResult& res, QPair& ray, RayPickCache& cache) { +void RayPickManager::cacheResult(const bool intersects, const RayPickResult& resTemp, const RayCacheKey& key, RayPickResult& res, QPair& ray, RayPickCache& cache) { if (intersects) { - cache[ray][mask] = resTemp; + cache[ray][key] = resTemp; if (resTemp.distance < res.distance) { res = resTemp; } } else { - cache[ray][mask] = RayPickResult(res.searchRay); + cache[ray][key] = RayPickResult(res.searchRay); } } @@ -74,8 +74,8 @@ void RayPickManager::update() { bool fromCache = true; bool invisible = rayPick->getFilter().doesPickInvisible(); bool nonCollidable = rayPick->getFilter().doesPickNonCollidable(); - RayPickFilter::Flags entityMask = rayPick->getFilter().getEntityFlags(); - if (!checkAndCompareCachedResults(rayKey, results, res, entityMask)) { + 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; @@ -83,7 +83,7 @@ void RayPickManager::update() { if (!fromCache) { cacheResult(entityRes.intersects, RayPickResult(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, ray, entityRes.surfaceNormal), - entityMask, res, rayKey, results); + entityKey, res, rayKey, results); } } @@ -92,8 +92,8 @@ void RayPickManager::update() { bool fromCache = true; bool invisible = rayPick->getFilter().doesPickInvisible(); bool nonCollidable = rayPick->getFilter().doesPickNonCollidable(); - RayPickFilter::Flags overlayMask = rayPick->getFilter().getOverlayFlags(); - if (!checkAndCompareCachedResults(rayKey, results, res, overlayMask)) { + 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; @@ -101,25 +101,26 @@ void RayPickManager::update() { if (!fromCache) { cacheResult(overlayRes.intersects, RayPickResult(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, ray, overlayRes.surfaceNormal), - overlayMask, res, rayKey, results); + overlayKey, res, rayKey, results); } } if (rayPick->getFilter().doesPickAvatars()) { - RayPickFilter::Flags avatarMask = rayPick->getFilter().getAvatarFlags(); - if (!checkAndCompareCachedResults(rayKey, results, res, avatarMask)) { + 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), avatarMask, res, rayKey, results); + 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()) { RayPickFilter::Flags hudMask = rayPick->getFilter().getHUDFlags(); - if (!checkAndCompareCachedResults(rayKey, results, res, hudMask)) { + RayCacheKey hudKey = { rayPick->getFilter().getHUDFlags() }; + 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), hudMask, res, rayKey, results); + cacheResult(true, RayPickResult(IntersectionType::HUD, 0, glm::distance(ray.origin, hudRes), hudRes, ray), hudKey, res, rayKey, results); } } diff --git a/interface/src/raypick/RayPickManager.h b/interface/src/raypick/RayPickManager.h index 8c6c28ceab..fd2c6f4a6b 100644 --- a/interface/src/raypick/RayPickManager.h +++ b/interface/src/raypick/RayPickManager.h @@ -24,6 +24,25 @@ 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: @@ -45,11 +64,11 @@ private: RayPick::Pointer findRayPick(const QUuid& uid) const; QHash _rayPicks; - typedef QHash, std::unordered_map> RayPickCache; + 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 RayPickFilter::Flags& mask); - void cacheResult(const bool intersects, const RayPickResult& resTemp, const RayPickFilter::Flags& mask, RayPickResult& res, QPair& ray, RayPickCache& cache); + 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.h b/interface/src/raypick/RayPickScriptingInterface.h index 59c5804d72..099103e4c5 100644 --- a/interface/src/raypick/RayPickScriptingInterface.h +++ b/interface/src/raypick/RayPickScriptingInterface.h @@ -24,7 +24,7 @@ class RayPickScriptingInterface : public QObject, public Dependency { 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_COURSE READ PICK_COURSE 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) diff --git a/libraries/pointers/src/pointers/PointerManager.h b/libraries/pointers/src/pointers/PointerManager.h index 0a045997c2..df21ab7cf2 100644 --- a/libraries/pointers/src/pointers/PointerManager.h +++ b/libraries/pointers/src/pointers/PointerManager.h @@ -26,4 +26,4 @@ signals: void hoverLeave(const QUuid& id, const PointerEvent& pointerEvent); }; -#endif // hifi_RayPick_h +#endif // hifi_pointers_PointerManager_h diff --git a/libraries/pointers/src/pointers/rays/RayPick.h b/libraries/pointers/src/pointers/rays/RayPick.h index 3691ac9985..5a53891dc6 100644 --- a/libraries/pointers/src/pointers/rays/RayPick.h +++ b/libraries/pointers/src/pointers/rays/RayPick.h @@ -142,14 +142,6 @@ public: void setIgnoreItems(const QVector& items); void setIncludeItems(const QVector& items); -#if 0 - void setIgnoreEntities(const QScriptValue& ignoreEntities); - void setIncludeEntities(const QScriptValue& includeEntities); - void setIgnoreOverlays(const QScriptValue& ignoreOverlays); - void setIncludeOverlays(const QScriptValue& includeOverlays); - void setIgnoreAvatars(const QScriptValue& ignoreAvatars); - void setIncludeAvatars(const QScriptValue& includeAvatars); -#endif private: RayPickFilter _filter; diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 9295f50518..2deef5f9fa 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -141,8 +141,11 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); }; this.setIgnoreTablet = function() { - RayPick.setIgnoreOverlays(_this.leftControllerRayPick, [HMD.tabletID]); - RayPick.setIgnoreOverlays(_this.rightControllerRayPick, [HMD.tabletID]); + if (HMD.tabletID !== this.tabletID) { + this.tabletID = HMD.tabletID; + RayPick.setIgnoreItems(_this.leftControllerRayPick, _this.blacklist.concat([HMD.tabletID])); + RayPick.setIgnoreItems(_this.rightControllerRayPick, _this.blacklist.concat([HMD.tabletID])); + } }; this.update = function () { @@ -367,9 +370,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); }; this.setBlacklist = function() { - RayPick.setIgnoreEntities(_this.leftControllerRayPick, this.blacklist); - RayPick.setIgnoreEntities(_this.rightControllerRayPick, this.blacklist); - + RayPick.setIgnoreItems(_this.leftControllerRayPick, this.blacklist.concat(HMD.tabletID)); + RayPick.setIgnoreItems(_this.rightControllerRayPick, this.blacklist.concat(HMD.tabletID)); }; var MAPPING_NAME = "com.highfidelity.controllerDispatcher"; diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index cbe64b1870..5049185827 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -134,6 +134,13 @@ Script.include("/~/system/libraries/utils.js"); LaserPointers.enableLaserPointer(this.laserPointer); LaserPointers.setRenderState(this.laserPointer, this.mode); + + if (HMD.tabletID !== this.tabletID || HMD.tabletButtonID !== this.tabletButtonID || HMD.tabletScreenID !== this.tabletScreenID) { + this.tabletID = HMD.tabletID; + this.tabletButtonID = HMD.tabletButtonID; + this.tabletScreenID = HMD.tabletScreenID; + LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]); + } }; this.pointingAtTablet = function(objectID) { @@ -244,7 +251,7 @@ Script.include("/~/system/libraries/utils.js"); defaultRenderStates: defaultRenderStates }); - LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]); + LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]); } var leftHandInEditMode = new InEditMode(LEFT_HAND); diff --git a/scripts/system/controllers/controllerModules/overlayLaserInput.js b/scripts/system/controllers/controllerModules/overlayLaserInput.js index 7dace85ec4..7c86a01c5d 100644 --- a/scripts/system/controllers/controllerModules/overlayLaserInput.js +++ b/scripts/system/controllers/controllerModules/overlayLaserInput.js @@ -184,6 +184,11 @@ Script.include("/~/system/libraries/controllers.js"); LaserPointers.enableLaserPointer(this.laserPointer); LaserPointers.setRenderState(this.laserPointer, this.mode); + + if (HMD.tabletID !== this.tabletID) { + this.tabletID = HMD.tabletID; + LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID]); + } }; this.processControllerTriggers = function(controllerData) { @@ -378,7 +383,7 @@ Script.include("/~/system/libraries/controllers.js"); defaultRenderStates: defaultRenderStates }); - LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID]); + LaserPointers.setIgnoreItems(this.laserPointer, [HMD.tabletID]); } var leftOverlayLaserInput = new OverlayLaserInput(LEFT_HAND); diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index d2717a1348..86ad9c56ca 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -347,10 +347,10 @@ Script.include("/~/system/libraries/controllers.js"); }; this.setIgnoreEntities = function(entitiesToIgnore) { - LaserPointers.setIgnoreEntities(this.teleportRayHandVisible, entitiesToIgnore); - LaserPointers.setIgnoreEntities(this.teleportRayHandInvisible, entitiesToIgnore); - LaserPointers.setIgnoreEntities(this.teleportRayHeadVisible, entitiesToIgnore); - LaserPointers.setIgnoreEntities(this.teleportRayHeadInvisible, entitiesToIgnore); + LaserPointers.setIgnoreItems(this.teleportRayHandVisible, entitiesToIgnore); + LaserPointers.setIgnoreItems(this.teleportRayHandInvisible, entitiesToIgnore); + LaserPointers.setIgnoreItems(this.teleportRayHeadVisible, entitiesToIgnore); + LaserPointers.setIgnoreItems(this.teleportRayHeadInvisible, entitiesToIgnore); }; } diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index 2f046cbce3..a1846e7ad7 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -263,7 +263,7 @@ function Grabber() { filter: RayPick.PICK_OVERLAYS, enabled: true }); - RayPick.setIncludeOverlays(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); + RayPick.setIncludeItems(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); var renderStates = [{name: "grabbed", end: beacon}]; this.mouseRayEntities = LaserPointers.createLaserPointer({ joint: "Mouse",