From 81f28b3b2cdf6ba81b6ccc5f66fc6afc5278e9a9 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 28 Mar 2019 09:38:28 +0200 Subject: [PATCH 1/2] Fixed ray intersections with Local entities. Previously, rays *always* intersected with Local entities, regardless of whether the pick filter requested to hit on collidable or noncollidable entities. But Local entities are always collisionless, so a pick filter for collidable entities shouldn't intersect with Local entities. --- libraries/entities/src/EntityTreeElement.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index aab98adb52..51e3da0dca 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -148,13 +148,20 @@ bool EntityTreeElement::checkFilterSettings(const EntityItemPointer& entity, Pic (!searchFilter.doesPickLocalEntities() && hostType == entity::HostType::LOCAL)) { return false; } - // We only check the collidable filters for non-local entities, because local entities are always collisionless - bool collidable = !entity->getCollisionless() && (entity->getShapeType() != SHAPE_TYPE_NONE); - if (hostType != entity::HostType::LOCAL) { - if ((collidable && !searchFilter.doesPickCollidable()) || (!collidable && !searchFilter.doesPickNonCollidable())) { - return false; - } + + bool collidable; + if (hostType == entity::HostType::LOCAL) { + // Local entities are always collisionless + collidable = false; } + else { + collidable = !entity->getCollisionless() && (entity->getShapeType() != SHAPE_TYPE_NONE); + } + + if ((collidable && !searchFilter.doesPickCollidable()) || (!collidable && !searchFilter.doesPickNonCollidable())) { + return false; + } + return true; } From 32406b839926d5b12ad1e3a3b942ee88161947ae Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 28 Mar 2019 19:46:51 +0200 Subject: [PATCH 2/2] Fixed Safe Landing interaction with Local entities. Local entities are collisionless, so they shouldn't affect Safe Landing since it specifies that it only wants to find COLLIDABLE entities. However, due to the requirement to support legacy behavior, picks for COLLIDABLE entities *do* intersect Local entities. In order to prevent this, we have to explicitly request only intersections with Domain or Avatar entities. For more information about this, see this Pull Request: https://github.com/highfidelity/hifi/pull/15282 --- interface/src/avatar/MyAvatar.cpp | 3 ++- libraries/entities/src/EntityTreeElement.cpp | 23 +++++++++----------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f2d8730ebb..42f9923652 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3742,7 +3742,8 @@ bool MyAvatar::requiresSafeLanding(const glm::vec3& positionIn, glm::vec3& bette // See https://highfidelity.fogbugz.com/f/cases/5003/findRayIntersection-has-option-to-use-collidableOnly-but-doesn-t-actually-use-colliders QVariantMap extraInfo; EntityItemID entityID = entityTree->evalRayIntersection(startPointIn, directionIn, include, ignore, - PickFilter(PickFilter::getBitMask(PickFilter::FlagBit::COLLIDABLE) | PickFilter::getBitMask(PickFilter::FlagBit::PRECISE)), + PickFilter(PickFilter::getBitMask(PickFilter::FlagBit::COLLIDABLE) | PickFilter::getBitMask(PickFilter::FlagBit::PRECISE) + | PickFilter::getBitMask(PickFilter::FlagBit::DOMAIN_ENTITIES) | PickFilter::getBitMask(PickFilter::FlagBit::AVATAR_ENTITIES)), // exclude Local entities element, distance, face, normalOut, extraInfo, lockType, accurateResult); if (entityID.isNull()) { return false; diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 51e3da0dca..60eaafc0dd 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -148,20 +148,17 @@ bool EntityTreeElement::checkFilterSettings(const EntityItemPointer& entity, Pic (!searchFilter.doesPickLocalEntities() && hostType == entity::HostType::LOCAL)) { return false; } - - bool collidable; - if (hostType == entity::HostType::LOCAL) { - // Local entities are always collisionless - collidable = false; + // We only check the collidable filters for non-local entities, because local entities are always collisionless, + // but picks always include COLLIDABLE (see PickScriptingInterface::getPickFilter()), so if we were to respect + // the getCollisionless() property of Local entities then we would *never* intersect them in a pick. + // An unfortunate side effect of the following code is that Local entities are intersected even if the + // pick explicitly requested only COLLIDABLE entities (but, again, Local entities are always collisionless). + if (hostType != entity::HostType::LOCAL) { + bool collidable = !entity->getCollisionless() && (entity->getShapeType() != SHAPE_TYPE_NONE); + if ((collidable && !searchFilter.doesPickCollidable()) || (!collidable && !searchFilter.doesPickNonCollidable())) { + return false; + } } - else { - collidable = !entity->getCollisionless() && (entity->getShapeType() != SHAPE_TYPE_NONE); - } - - if ((collidable && !searchFilter.doesPickCollidable()) || (!collidable && !searchFilter.doesPickNonCollidable())) { - return false; - } - return true; }