From 81de668c1edec983420d4b1f9a6cfb5e677486ef Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 23 Feb 2018 11:20:45 -0800 Subject: [PATCH 01/12] faster per-entity raypick culling --- libraries/entities/src/EntityTreeElement.cpp | 33 +++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 9e32bc3346..1ebb07c3a2 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -643,25 +643,25 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori int entityNumber = 0; EntityItemID entityID; forEachEntity([&](EntityItemPointer entity) { - if ( (visibleOnly && !entity->isVisible()) || (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE)) - || (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID())) - || (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) { - return; - } - + // use simple line-sphere for broadphase check + // (this is faster and more likely to cull results than the filter check below so we do it first) bool success; AABox entityBox = entity->getAABox(success); if (!success) { return; } + glm::vec3 sphereCenter = entityBox.calcCenter() - origin; + float r2 = 0.25f * glm::length2(entityBox.getScale()); + float d = glm::dot(sphereCenter, direction); + if (glm::length2(sphereCenter) > r2 && (glm::abs(d) > 0.0f && glm::distance2(d * direction, sphereCenter) > r2)) { + return; + } - float localDistance; - BoxFace localFace; - glm::vec3 localSurfaceNormal; - QVariantMap localExtraInfo; - - // if the ray doesn't intersect with our cube, we can stop searching! - if (!entityBox.findRayIntersection(origin, direction, localDistance, localFace, localSurfaceNormal)) { + // check RayPick filter settings + if ((visibleOnly && !entity->isVisible()) + || (collidableOnly && (entity->getCollisionless() || entity->getShapeType() == SHAPE_TYPE_NONE)) + || (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID())) + || (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) { return; } @@ -682,14 +682,17 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori // we can use the AABox's ray intersection by mapping our origin and direction into the entity frame // and testing intersection there. + float localDistance; + BoxFace localFace; + glm::vec3 localSurfaceNormal; if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, localDistance, localFace, localSurfaceNormal)) { if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) { // now ask the entity if we actually intersect if (entity->supportsDetailedRayIntersection()) { + QVariantMap localExtraInfo; if (entity->findDetailedRayIntersection(origin, direction, keepSearching, element, localDistance, - localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) { - + localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) { if (localDistance < distance) { distance = localDistance; face = localFace; From 79b9fec900f5587b1de2c2686cad4e0649e054f9 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 23 Feb 2018 16:08:31 -0800 Subject: [PATCH 02/12] add rayHitsSphere() util method --- libraries/shared/src/GeometryUtil.cpp | 8 ++++++++ libraries/shared/src/GeometryUtil.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 0742a5625b..65adc28e07 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -40,6 +40,14 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec } } +bool rayHitsSphere(const glm::vec3& rayStart, const glm::vec3& rayDirection, + const glm::vec3& sphereCenter, float sphereRadiusSquared) { + glm::vec3 center = sphereCenter - rayStart; + float distance = glm::dot(center, rayDirection); + return (glm::length2(center) < sphereRadiusSquared + || (glm::abs(distance) > 0.0f && glm::distance2(distance * rayDirection, center) < sphereRadiusSquared)); +} + // Computes the penetration between a point and a sphere (centered at the origin) // if point is inside sphere: returns true and stores the result in 'penetration' // (the vector that would move the point outside the sphere) diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index 4832616fbd..bc09b71fc6 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -19,6 +19,9 @@ class Plane; glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end); +bool rayHitsSphere(const glm::vec3& rayStart, const glm::vec3& rayDirection, + const glm::vec3& sphereCenter, float sphereRadiusSquared); + /// Computes the penetration between a point and a sphere (centered at the origin) /// \param point the point location relative to sphere center (origin) /// \param defaultDirection the direction of the pentration when the point is near the origin From 6ab85d5800266635a51f23f01f829045e10ed600 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 23 Feb 2018 16:09:03 -0800 Subject: [PATCH 03/12] cleanup and a few small optimizations --- libraries/entities/src/EntityTreeElement.cpp | 40 +++++++++----------- libraries/entities/src/EntityTreeElement.h | 2 +- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 1ebb07c3a2..e6bcdc9487 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -598,13 +598,13 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con EntityItemID result; float distanceToElementCube = std::numeric_limits::max(); - float distanceToElementDetails = distance; BoxFace localFace; glm::vec3 localSurfaceNormal; - QVariantMap localExtraInfo; - // if the ray doesn't intersect with our cube, we can stop searching! - if (!_cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal)) { + // if the ray doesn't intersect with our cube OR the distance to element is less than current best distance + // we can stop searching! + if (!_cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal) + || (!_cube.contains(origin) && distanceToElementCube > distance)) { keepSearching = false; // no point in continuing to search return result; // we did not intersect } @@ -616,20 +616,17 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con // if the distance to the element cube is not less than the current best distance, then it's not possible // for any details inside the cube to be closer so we don't need to consider them. - if (_cube.contains(origin) || distanceToElementCube < distance) { - - EntityItemID entityID = findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails, - face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, - localExtraInfo, precisionPicking, distanceToElementCube); - if (!entityID.isNull()) { - if (distanceToElementDetails < distance) { - distance = distanceToElementDetails; - face = localFace; - surfaceNormal = localSurfaceNormal; - extraInfo = localExtraInfo; - result = entityID; - } - } + QVariantMap localExtraInfo; + float distanceToElementDetails = distance; + EntityItemID entityID = findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails, + face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, + localExtraInfo, precisionPicking); + if (!entityID.isNull() && distanceToElementDetails < distance) { + distance = distanceToElementDetails; + face = localFace; + surfaceNormal = localSurfaceNormal; + extraInfo = localExtraInfo; + result = entityID; } return result; } @@ -637,7 +634,7 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, const QVector& entityIDsToDiscard, - bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking, float distanceToElementCube) { + bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking) { // only called if we do intersect our bounding cube, but find if we actually intersect with entities... int entityNumber = 0; @@ -650,10 +647,7 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori if (!success) { return; } - glm::vec3 sphereCenter = entityBox.calcCenter() - origin; - float r2 = 0.25f * glm::length2(entityBox.getScale()); - float d = glm::dot(sphereCenter, direction); - if (glm::length2(sphereCenter) > r2 && (glm::abs(d) > 0.0f && glm::distance2(d * direction, sphereCenter) > r2)) { + if (!rayHitsSphere(origin, direction, entityBox.calcCenter(), 0.25f * glm::length2(entityBox.getScale()))) { return; } diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index 2313bde0c4..80707fcb14 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -155,7 +155,7 @@ public: bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, - QVariantMap& extraInfo, bool precisionPicking, float distanceToElementCube); + QVariantMap& extraInfo, bool precisionPicking); virtual bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject) const override; From 2750f3ee71d350e7a9451dce9dfc9a1075dbfb5b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 23 Feb 2018 16:38:42 -0800 Subject: [PATCH 04/12] remove unused cruft and avoid useless work --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 2 +- .../entities-renderer/src/RenderableModelEntityItem.h | 2 +- .../entities-renderer/src/RenderablePolyVoxEntityItem.cpp | 2 +- .../entities-renderer/src/RenderablePolyVoxEntityItem.h | 2 +- libraries/entities/src/EntityItem.h | 2 +- libraries/entities/src/EntityTreeElement.cpp | 8 +++----- libraries/entities/src/EntityTreeElement.h | 2 +- libraries/entities/src/LightEntityItem.cpp | 2 +- libraries/entities/src/LightEntityItem.h | 2 +- libraries/entities/src/LineEntityItem.h | 2 +- libraries/entities/src/PolyLineEntityItem.h | 2 +- libraries/entities/src/PolyVoxEntityItem.h | 2 +- libraries/entities/src/ShapeEntityItem.cpp | 2 +- libraries/entities/src/ShapeEntityItem.h | 2 +- libraries/entities/src/TextEntityItem.cpp | 2 +- libraries/entities/src/TextEntityItem.h | 2 +- libraries/entities/src/WebEntityItem.cpp | 2 +- libraries/entities/src/WebEntityItem.h | 2 +- libraries/entities/src/ZoneEntityItem.cpp | 2 +- libraries/entities/src/ZoneEntityItem.h | 2 +- 20 files changed, 22 insertions(+), 24 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index eb42e9af22..c4fa71a488 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -286,7 +286,7 @@ bool RenderableModelEntityItem::supportsDetailedRayIntersection() const { } bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { auto model = getModel(); if (!model) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 5d7d84b7bc..68bc70c8a9 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -68,7 +68,7 @@ public: virtual bool supportsDetailedRayIntersection() const override; virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override; diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 2b1de8d11b..0211daff1e 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -565,7 +565,7 @@ public: #endif bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 0a00d1cb73..70c87dca6f 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -53,7 +53,7 @@ public: virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index d08c5514e9..0303964e18 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -159,7 +159,7 @@ public: virtual bool supportsDetailedRayIntersection() const { return false; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { return true; } diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index e6bcdc9487..2c51ff13f1 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -594,8 +594,6 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con const QVector& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking) { - keepSearching = true; // assume that we will continue searching after this. - EntityItemID result; float distanceToElementCube = std::numeric_limits::max(); BoxFace localFace; @@ -618,7 +616,7 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con // for any details inside the cube to be closer so we don't need to consider them. QVariantMap localExtraInfo; float distanceToElementDetails = distance; - EntityItemID entityID = findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails, + EntityItemID entityID = findDetailedRayIntersection(origin, direction, element, distanceToElementDetails, face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, localExtraInfo, precisionPicking); if (!entityID.isNull() && distanceToElementDetails < distance) { @@ -631,7 +629,7 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con return result; } -EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, +EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, const QVector& entityIDsToDiscard, bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking) { @@ -685,7 +683,7 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori // now ask the entity if we actually intersect if (entity->supportsDetailedRayIntersection()) { QVariantMap localExtraInfo; - if (entity->findDetailedRayIntersection(origin, direction, keepSearching, element, localDistance, + if (entity->findDetailedRayIntersection(origin, direction, element, localDistance, localFace, localSurfaceNormal, localExtraInfo, precisionPicking)) { if (localDistance < distance) { distance = localDistance; diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index 80707fcb14..b219d64d9d 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -152,7 +152,7 @@ public: const QVector& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking = false); virtual EntityItemID findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking); diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index 85edefa413..3f7fc5f799 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -298,7 +298,7 @@ void LightEntityItem::resetLightPropertiesChanged() { } bool LightEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { diff --git a/libraries/entities/src/LightEntityItem.h b/libraries/entities/src/LightEntityItem.h index 3be1d48aa5..4d0bde3718 100644 --- a/libraries/entities/src/LightEntityItem.h +++ b/libraries/entities/src/LightEntityItem.h @@ -86,7 +86,7 @@ public: virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override; diff --git a/libraries/entities/src/LineEntityItem.h b/libraries/entities/src/LineEntityItem.h index 9f16807084..375453e0e9 100644 --- a/libraries/entities/src/LineEntityItem.h +++ b/libraries/entities/src/LineEntityItem.h @@ -61,7 +61,7 @@ class LineEntityItem : public EntityItem { // never have a ray intersection pick a LineEntityItem. virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override { return false; } diff --git a/libraries/entities/src/PolyLineEntityItem.h b/libraries/entities/src/PolyLineEntityItem.h index 8af2b26216..2dc8befe97 100644 --- a/libraries/entities/src/PolyLineEntityItem.h +++ b/libraries/entities/src/PolyLineEntityItem.h @@ -94,7 +94,7 @@ class PolyLineEntityItem : public EntityItem { // never have a ray intersection pick a PolyLineEntityItem. virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override { return false; } diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index 47d2a4b4e1..90982fe448 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -45,7 +45,7 @@ class PolyVoxEntityItem : public EntityItem { // never have a ray intersection pick a PolyVoxEntityItem. virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override { return false; } diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 2425208a87..db3d6798be 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -228,7 +228,7 @@ bool ShapeEntityItem::supportsDetailedRayIntersection() const { } bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { // determine the ray in the frame of the entity transformed from a unit sphere diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index 7ad1b3c1c2..46d696f979 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -92,7 +92,7 @@ public: bool supportsDetailedRayIntersection() const override; bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override; diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp index 7b1089e6ed..7030a95562 100644 --- a/libraries/entities/src/TextEntityItem.cpp +++ b/libraries/entities/src/TextEntityItem.cpp @@ -129,7 +129,7 @@ void TextEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits } bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { glm::vec3 dimensions = getScaledDimensions(); diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h index 3ab743ecfd..06b377ee14 100644 --- a/libraries/entities/src/TextEntityItem.h +++ b/libraries/entities/src/TextEntityItem.h @@ -48,7 +48,7 @@ public: virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override; diff --git a/libraries/entities/src/WebEntityItem.cpp b/libraries/entities/src/WebEntityItem.cpp index 91e7bca063..548bca3225 100644 --- a/libraries/entities/src/WebEntityItem.cpp +++ b/libraries/entities/src/WebEntityItem.cpp @@ -106,7 +106,7 @@ void WebEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitst } bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { glm::vec3 dimensions = getScaledDimensions(); diff --git a/libraries/entities/src/WebEntityItem.h b/libraries/entities/src/WebEntityItem.h index 7d8f37cd83..dab7cd5e22 100644 --- a/libraries/entities/src/WebEntityItem.h +++ b/libraries/entities/src/WebEntityItem.h @@ -47,7 +47,7 @@ public: virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override; diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 6083e5b8de..4ae020f966 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -296,7 +296,7 @@ void ZoneEntityItem::setCompoundShapeURL(const QString& url) { } bool ZoneEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const { diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index 95b6248fde..2c6b01fc69 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -105,7 +105,7 @@ public: virtual bool supportsDetailedRayIntersection() const override { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override; From 7a19f48b9c36579fa68eb2fb833470e2503016a6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 1 Mar 2018 16:15:26 -0800 Subject: [PATCH 05/12] move rayHitsSphere logic to AABox method --- libraries/entities/src/EntityTreeElement.cpp | 2 +- libraries/shared/src/AABox.cpp | 9 +++++++++ libraries/shared/src/AABox.h | 1 + libraries/shared/src/GeometryUtil.cpp | 8 -------- libraries/shared/src/GeometryUtil.h | 3 --- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 2c51ff13f1..654d4b4ecc 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -645,7 +645,7 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori if (!success) { return; } - if (!rayHitsSphere(origin, direction, entityBox.calcCenter(), 0.25f * glm::length2(entityBox.getScale()))) { + if (!entityBox.rayHitsBoundingSphere(origin, direction)) { return; } diff --git a/libraries/shared/src/AABox.cpp b/libraries/shared/src/AABox.cpp index cea0a83d52..cbf3c1b785 100644 --- a/libraries/shared/src/AABox.cpp +++ b/libraries/shared/src/AABox.cpp @@ -287,6 +287,15 @@ bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct return false; } +bool AABox::rayHitsBoundingSphere(const glm::vec3& origin, const glm::vec3& direction) const { + glm::vec3 localCenter = calcCenter() - origin; + float distance = glm::dot(localCenter, direction); + const float ONE_OVER_TWO_SQUARED = 0.25f; + float radiusSquared = ONE_OVER_TWO_SQUARED * glm::length2(_scale); + return (glm::length2(localCenter) < radiusSquared + || (glm::abs(distance) > 0.0f && glm::distance2(distance * direction, localCenter) < radiusSquared)); +} + bool AABox::touchesSphere(const glm::vec3& center, float radius) const { // Avro's algorithm from this paper: http://www.mrtc.mdh.se/projects/3Dgraphics/paperF.pdf glm::vec3 e = glm::max(_corner - center, Vectors::ZERO) + glm::max(center - _corner - _scale, Vectors::ZERO); diff --git a/libraries/shared/src/AABox.h b/libraries/shared/src/AABox.h index 24485eaad6..2d5ca242d6 100644 --- a/libraries/shared/src/AABox.h +++ b/libraries/shared/src/AABox.h @@ -71,6 +71,7 @@ public: bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const; bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) const; + bool rayHitsBoundingSphere(const glm::vec3& origin, const glm::vec3& direction) const; bool touchesSphere(const glm::vec3& center, float radius) const; // fast but may generate false positives bool touchesAAEllipsoid(const glm::vec3& center, const glm::vec3& radials) const; bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const; diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 65adc28e07..0742a5625b 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -40,14 +40,6 @@ glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec } } -bool rayHitsSphere(const glm::vec3& rayStart, const glm::vec3& rayDirection, - const glm::vec3& sphereCenter, float sphereRadiusSquared) { - glm::vec3 center = sphereCenter - rayStart; - float distance = glm::dot(center, rayDirection); - return (glm::length2(center) < sphereRadiusSquared - || (glm::abs(distance) > 0.0f && glm::distance2(distance * rayDirection, center) < sphereRadiusSquared)); -} - // Computes the penetration between a point and a sphere (centered at the origin) // if point is inside sphere: returns true and stores the result in 'penetration' // (the vector that would move the point outside the sphere) diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index bc09b71fc6..4832616fbd 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -19,9 +19,6 @@ class Plane; glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end); -bool rayHitsSphere(const glm::vec3& rayStart, const glm::vec3& rayDirection, - const glm::vec3& sphereCenter, float sphereRadiusSquared); - /// Computes the penetration between a point and a sphere (centered at the origin) /// \param point the point location relative to sphere center (origin) /// \param defaultDirection the direction of the pentration when the point is near the origin From 9fbe7ec194da243c0cc48eb46e61905bb946a56d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 1 Mar 2018 22:48:55 -0800 Subject: [PATCH 06/12] time-box Picks and solve in round-robin sequence --- .../src/raypick/PickScriptingInterface.cpp | 10 +- .../src/raypick/PickScriptingInterface.h | 10 +- libraries/entities/src/EntityItem.cpp | 2 +- libraries/pointers/src/PickCacheOptimizer.h | 125 ++++++++++-------- libraries/pointers/src/PickManager.cpp | 9 +- libraries/pointers/src/PickManager.h | 11 +- 6 files changed, 107 insertions(+), 60 deletions(-) diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp index 43e0c059f0..1bf6dd2f8e 100644 --- a/interface/src/raypick/PickScriptingInterface.cpp +++ b/interface/src/raypick/PickScriptingInterface.cpp @@ -174,4 +174,12 @@ void PickScriptingInterface::registerMetaTypes(QScriptEngine* engine) { engine->globalObject().setProperty("PickType", pickTypes); qScriptRegisterMetaType(engine, pickTypesToScriptValue, pickTypesFromScriptValue); -} \ No newline at end of file +} + +unsigned int PickScriptingInterface::getPerFrameTimeBudget() const { + return DependencyManager::get()->getPerFrameTimeBudget(); +} + +void PickScriptingInterface::setPerFrameTimeBudget(unsigned int numUsecs) { + DependencyManager::get()->setPerFrameTimeBudget(numUsecs); +} diff --git a/interface/src/raypick/PickScriptingInterface.h b/interface/src/raypick/PickScriptingInterface.h index 98427e34ca..288d3008bb 100644 --- a/interface/src/raypick/PickScriptingInterface.h +++ b/interface/src/raypick/PickScriptingInterface.h @@ -185,6 +185,14 @@ public: */ Q_INVOKABLE bool isMouse(unsigned int uid); + Q_PROPERTY(unsigned int perFrameTimeBudget READ getPerFrameTimeBudget WRITE setPerFrameTimeBudget) + /**jsdoc + * The max number of usec to spend per frame updating Pick results. + * @typedef {number} Picks.perFrameTimeBudget + */ + unsigned int getPerFrameTimeBudget() const; + void setPerFrameTimeBudget(unsigned int numUsecs); + public slots: static constexpr unsigned int PICK_NOTHING() { return 0; } static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); } @@ -202,4 +210,4 @@ public slots: static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; } }; -#endif // hifi_PickScriptingInterface_h \ No newline at end of file +#endif // hifi_PickScriptingInterface_h diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f77d8a59c3..c01ebe8ca4 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -2984,4 +2984,4 @@ std::unordered_map EntityItem::getMaterial toReturn = _materials; } return toReturn; -} \ No newline at end of file +} diff --git a/libraries/pointers/src/PickCacheOptimizer.h b/libraries/pointers/src/PickCacheOptimizer.h index 10c9d6cf84..e930f8c663 100644 --- a/libraries/pointers/src/PickCacheOptimizer.h +++ b/libraries/pointers/src/PickCacheOptimizer.h @@ -37,7 +37,7 @@ template class PickCacheOptimizer { public: - void update(std::unordered_map>& picks, bool shouldPickHUD); + void update(std::unordered_map>& picks, uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD); protected: typedef std::unordered_map> PickCache; @@ -67,66 +67,85 @@ void PickCacheOptimizer::cacheResult(const bool intersects, const PickResultP } template -void PickCacheOptimizer::update(std::unordered_map>& picks, bool shouldPickHUD) { +void PickCacheOptimizer::update(std::unordered_map>& picks, + uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD) { PickCache results; - for (const auto& pickPair : picks) { - std::shared_ptr> pick = std::static_pointer_cast>(pickPair.second); - + const uint32_t INVALID_PICK_ID = 0; + std::unordered_map>::iterator itr = picks.begin(); + if (nextToUpdate != INVALID_PICK_ID) { + itr = picks.find(nextToUpdate); + if (itr == picks.end()) { + itr = picks.begin(); + } + } + uint32_t numUpdates = 0; + while(numUpdates < picks.size()) { + std::shared_ptr> pick = std::static_pointer_cast>(itr->second); T mathematicalPick = pick->getMathematicalPick(); PickResultPointer res = pick->getDefaultResult(mathematicalPick.toVariantMap()); if (!pick->isEnabled() || pick->getFilter().doesPickNothing() || pick->getMaxDistance() < 0.0f || !mathematicalPick) { pick->setPickResult(res); - continue; - } - - if (pick->getFilter().doesPickEntities()) { - PickCacheKey entityKey = { pick->getFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; - if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) { - PickResultPointer entityRes = pick->getEntityIntersection(mathematicalPick); - if (entityRes) { - 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); - if (overlayRes) { - 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); - if (avatarRes) { - 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); - if (hudRes) { - 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())); + if (pick->getFilter().doesPickEntities()) { + PickCacheKey entityKey = { pick->getFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; + if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) { + PickResultPointer entityRes = pick->getEntityIntersection(mathematicalPick); + if (entityRes) { + 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); + if (overlayRes) { + 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); + if (avatarRes) { + 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); + if (hudRes) { + 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())); + } + } + + ++itr; + if (itr == picks.end()) { + itr = picks.begin(); + } + nextToUpdate = itr->first; + ++numUpdates; + uint64_t now = usecTimestampNow(); + if (usecTimestampNow() > expiry) { + break; } } } -#endif // hifi_PickCacheOptimizer_h \ No newline at end of file +#endif // hifi_PickCacheOptimizer_h diff --git a/libraries/pointers/src/PickManager.cpp b/libraries/pointers/src/PickManager.cpp index 92fec014da..b73b54cdb6 100644 --- a/libraries/pointers/src/PickManager.cpp +++ b/libraries/pointers/src/PickManager.cpp @@ -89,14 +89,17 @@ void PickManager::setIncludeItems(unsigned int uid, const QVector& includ } void PickManager::update() { + uint64_t expiry = usecTimestampNow() + _perFrameTimeBudget; std::unordered_map>> cachedPicks; withReadLock([&] { cachedPicks = _picks; }); bool shouldPickHUD = _shouldPickHUDOperator(); - _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], shouldPickHUD); - _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], false); + // we pass the same expiry to both updates + // even when the rayPicks consume all the budget at least one stylus will be updated + _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD); + _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false); } bool PickManager::isLeftHand(unsigned int uid) { @@ -121,4 +124,4 @@ bool PickManager::isMouse(unsigned int uid) { return pick->isMouse(); } return false; -} \ No newline at end of file +} diff --git a/libraries/pointers/src/PickManager.h b/libraries/pointers/src/PickManager.h index 5b069879a8..3b466be2bc 100644 --- a/libraries/pointers/src/PickManager.h +++ b/libraries/pointers/src/PickManager.h @@ -14,6 +14,8 @@ #include "Pick.h" #include "PickCacheOptimizer.h" +#include + class PickManager : public Dependency, protected ReadWriteLockable { SINGLETON_DEPENDENCY @@ -48,17 +50,24 @@ public: static const unsigned int INVALID_PICK_ID { 0 }; + unsigned int getPerFrameTimeBudget() const { return _perFrameTimeBudget; } + void setPerFrameTimeBudget(unsigned int numUsecs) { _perFrameTimeBudget = numUsecs; } + protected: std::function _shouldPickHUDOperator; std::function _calculatePos2DFromHUDOperator; std::shared_ptr findPick(unsigned int uid) const; std::unordered_map>> _picks; + unsigned int _nextPickToUpdate[PickQuery::NUM_PICK_TYPES] { 0, 0 }; std::unordered_map _typeMap; unsigned int _nextPickID { INVALID_PICK_ID + 1 }; PickCacheOptimizer _rayPickCacheOptimizer; PickCacheOptimizer _stylusPickCacheOptimizer; + + static const unsigned int DEFAULT_PER_FRAME_TIME_BUDGET = 2 * USECS_PER_MSEC; + unsigned int _perFrameTimeBudget { DEFAULT_PER_FRAME_TIME_BUDGET }; }; -#endif // hifi_PickManager_h \ No newline at end of file +#endif // hifi_PickManager_h From 7a39bd5c816edc4ce77c378e8d112df35056dd64 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 2 Mar 2018 09:29:42 -0800 Subject: [PATCH 07/12] remove tab whitespace --- libraries/shared/src/AABox.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/AABox.h b/libraries/shared/src/AABox.h index 2d5ca242d6..cf79cf9d04 100644 --- a/libraries/shared/src/AABox.h +++ b/libraries/shared/src/AABox.h @@ -71,7 +71,7 @@ public: bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const; bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) const; - bool rayHitsBoundingSphere(const glm::vec3& origin, const glm::vec3& direction) const; + bool rayHitsBoundingSphere(const glm::vec3& origin, const glm::vec3& direction) const; bool touchesSphere(const glm::vec3& center, float radius) const; // fast but may generate false positives bool touchesAAEllipsoid(const glm::vec3& center, const glm::vec3& radials) const; bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const; From 24635b045110975c9d21f495a65097c920637bc7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 2 Mar 2018 14:51:18 -0800 Subject: [PATCH 08/12] remove unused debug cruft variable --- libraries/pointers/src/PickCacheOptimizer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/pointers/src/PickCacheOptimizer.h b/libraries/pointers/src/PickCacheOptimizer.h index e930f8c663..dd1fa6cecb 100644 --- a/libraries/pointers/src/PickCacheOptimizer.h +++ b/libraries/pointers/src/PickCacheOptimizer.h @@ -141,7 +141,6 @@ void PickCacheOptimizer::update(std::unordered_mapfirst; ++numUpdates; - uint64_t now = usecTimestampNow(); if (usecTimestampNow() > expiry) { break; } From f83c6000df8f90d35dad902e0a77b0f9f56a886c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 6 Mar 2018 11:06:49 -0800 Subject: [PATCH 09/12] use 'auto' for very long type --- libraries/pointers/src/PickCacheOptimizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/pointers/src/PickCacheOptimizer.h b/libraries/pointers/src/PickCacheOptimizer.h index dd1fa6cecb..95ffa104ee 100644 --- a/libraries/pointers/src/PickCacheOptimizer.h +++ b/libraries/pointers/src/PickCacheOptimizer.h @@ -71,7 +71,7 @@ void PickCacheOptimizer::update(std::unordered_map>::iterator itr = picks.begin(); + auto iter = picks.begin(); if (nextToUpdate != INVALID_PICK_ID) { itr = picks.find(nextToUpdate); if (itr == picks.end()) { From 9eecd3cb80b0c3361ad3649f4415981465f47c0f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 6 Mar 2018 11:07:10 -0800 Subject: [PATCH 10/12] update styluses first: they are cheap --- libraries/pointers/src/PickManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/pointers/src/PickManager.cpp b/libraries/pointers/src/PickManager.cpp index b73b54cdb6..ba8fa814f0 100644 --- a/libraries/pointers/src/PickManager.cpp +++ b/libraries/pointers/src/PickManager.cpp @@ -96,10 +96,10 @@ void PickManager::update() { }); bool shouldPickHUD = _shouldPickHUDOperator(); - // we pass the same expiry to both updates - // even when the rayPicks consume all the budget at least one stylus will be updated - _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD); + // we pass the same expiry to both updates, but the stylus updates are relatively cheap + // and the rayPicks updae will ALWAYS update at least one ray even when there is no budget _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false); + _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD); } bool PickManager::isLeftHand(unsigned int uid) { From 3f1944eb8af38ff5493ededd69c2521cc1a259d1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 7 Mar 2018 10:06:32 -0800 Subject: [PATCH 11/12] fix variable name typo --- libraries/pointers/src/PickCacheOptimizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/pointers/src/PickCacheOptimizer.h b/libraries/pointers/src/PickCacheOptimizer.h index 95ffa104ee..49a039935c 100644 --- a/libraries/pointers/src/PickCacheOptimizer.h +++ b/libraries/pointers/src/PickCacheOptimizer.h @@ -71,7 +71,7 @@ void PickCacheOptimizer::update(std::unordered_map Date: Thu, 8 Mar 2018 10:11:26 -0800 Subject: [PATCH 12/12] more readable code --- libraries/entities/src/EntityTreeElement.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 654d4b4ecc..1ae55bc333 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -601,8 +601,8 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con // if the ray doesn't intersect with our cube OR the distance to element is less than current best distance // we can stop searching! - if (!_cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal) - || (!_cube.contains(origin) && distanceToElementCube > distance)) { + bool hit = _cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal); + if (!hit || (!_cube.contains(origin) && distanceToElementCube > distance)) { keepSearching = false; // no point in continuing to search return result; // we did not intersect }