From e32a3ba20d0dde5b28c9efda9c2495dd477b386e Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 30 Jan 2019 13:19:45 -0800 Subject: [PATCH 1/3] organize new avatar intersection --- interface/src/avatar/AvatarManager.cpp | 100 +++++++++++++------------ 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 1eb87c16f0..376c4e7931 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -652,28 +652,25 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic PROFILE_RANGE(simulation_physics, __FUNCTION__); - float distance = (float)INT_MAX; // with FLT_MAX bullet rayTest does not return results + float bulletDistance = (float)INT_MAX; // with FLT_MAX bullet rayTest does not return results glm::vec3 rayDirection = glm::normalize(ray.direction); - std::vector physicsResults = _myAvatar->getCharacterController()->rayTest(glmToBullet(ray.origin), glmToBullet(rayDirection), distance, QVector()); + std::vector physicsResults = _myAvatar->getCharacterController()->rayTest(glmToBullet(ray.origin), glmToBullet(rayDirection), bulletDistance, QVector()); if (physicsResults.size() > 0) { glm::vec3 rayDirectionInv = { rayDirection.x != 0.0f ? 1.0f / rayDirection.x : INFINITY, rayDirection.y != 0.0f ? 1.0f / rayDirection.y : INFINITY, rayDirection.z != 0.0f ? 1.0f / rayDirection.z : INFINITY }; - MyCharacterController::RayAvatarResult rayAvatarResult; - AvatarPointer avatar = nullptr; - - BoxFace face = BoxFace::UNKNOWN_FACE; - glm::vec3 surfaceNormal; - QVariantMap extraInfo; - for (auto &hit : physicsResults) { auto avatarID = hit._intersectWithAvatar; if ((avatarsToInclude.size() > 0 && !avatarsToInclude.contains(avatarID)) || (avatarsToDiscard.size() > 0 && avatarsToDiscard.contains(avatarID))) { continue; } - + + MyCharacterController::RayAvatarResult rayAvatarResult; + BoxFace face = BoxFace::UNKNOWN_FACE; + QVariantMap extraInfo; + AvatarPointer avatar = nullptr; if (_myAvatar->getSessionUUID() != avatarID) { auto avatarMap = getHashCopy(); AvatarHash::iterator itr = avatarMap.find(avatarID); @@ -683,44 +680,43 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic } else { avatar = _myAvatar; } + if (!hit._isBound) { rayAvatarResult = hit; } else if (avatar) { auto &multiSpheres = avatar->getMultiSphereShapes(); if (multiSpheres.size() > 0) { - std::vector boxHits; + MyCharacterController::RayAvatarResult boxHit; + boxHit._distance = FLT_MAX; + for (size_t i = 0; i < hit._boundJoints.size(); i++) { assert(hit._boundJoints[i] < multiSpheres.size()); auto &mSphere = multiSpheres[hit._boundJoints[i]]; if (mSphere.isValid()) { float boundDistance = FLT_MAX; - BoxFace face; - glm::vec3 surfaceNormal; + BoxFace boundFace = BoxFace::UNKNOWN_FACE; + glm::vec3 boundSurfaceNormal; auto &bbox = mSphere.getBoundingBox(); - if (bbox.findRayIntersection(ray.origin, rayDirection, rayDirectionInv, boundDistance, face, surfaceNormal)) { - MyCharacterController::RayAvatarResult boxHit; - boxHit._distance = boundDistance; - boxHit._intersect = true; - boxHit._intersectionNormal = surfaceNormal; - boxHit._intersectionPoint = ray.origin + boundDistance * rayDirection; - boxHit._intersectWithAvatar = avatarID; - boxHit._intersectWithJoint = mSphere.getJointIndex(); - boxHits.push_back(boxHit); + if (bbox.findRayIntersection(ray.origin, rayDirection, rayDirectionInv, boundDistance, boundFace, boundSurfaceNormal)) { + if (boundDistance < boxHit._distance) { + boxHit._intersect = true; + boxHit._intersectWithAvatar = avatarID; + boxHit._intersectWithJoint = mSphere.getJointIndex(); + boxHit._distance = boundDistance; + boxHit._intersectionPoint = ray.origin + boundDistance * rayDirection; + boxHit._intersectionNormal = boundSurfaceNormal; + face = boundFace; + } } } } - if (boxHits.size() > 0) { - if (boxHits.size() > 1) { - std::sort(boxHits.begin(), boxHits.end(), [](const MyCharacterController::RayAvatarResult& hitA, - const MyCharacterController::RayAvatarResult& hitB) { - return hitA._distance < hitB._distance; - }); - } - rayAvatarResult = boxHits[0]; + if (boxHit._distance < FLT_MAX) { + rayAvatarResult = boxHit; } } } - if (pickAgainstMesh) { + + if (rayAvatarResult._intersect && pickAgainstMesh) { glm::vec3 localRayOrigin = avatar->worldToJointPoint(ray.origin, rayAvatarResult._intersectWithJoint); glm::vec3 localRayPoint = avatar->worldToJointPoint(ray.origin + rayDirection, rayAvatarResult._intersectWithJoint); @@ -734,29 +730,35 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic auto defaultFrameRayPoint = jointPosition + jointOrientation * localRayPoint; auto defaultFrameRayDirection = defaultFrameRayPoint - defaultFrameRayOrigin; - if (avatar->getSkeletonModel()->findRayIntersectionAgainstSubMeshes(defaultFrameRayOrigin, defaultFrameRayDirection, distance, face, surfaceNormal, extraInfo, true, false)) { - auto newDistance = glm::length(vec3FromVariant(extraInfo["worldIntersectionPoint"]) - defaultFrameRayOrigin); - rayAvatarResult._distance = newDistance; - rayAvatarResult._intersectionPoint = ray.origin + newDistance * rayDirection; - rayAvatarResult._intersectionNormal = surfaceNormal; - extraInfo["worldIntersectionPoint"] = vec3toVariant(rayAvatarResult._intersectionPoint); - break; + float subMeshDistance = FLT_MAX; + BoxFace subMeshFace = BoxFace::UNKNOWN_FACE; + glm::vec3 subMeshSurfaceNormal; + QVariantMap subMeshExtraInfo; + if (avatar->getSkeletonModel()->findRayIntersectionAgainstSubMeshes(defaultFrameRayOrigin, defaultFrameRayDirection, subMeshDistance, subMeshFace, subMeshSurfaceNormal, subMeshExtraInfo, true, false)) { + rayAvatarResult._distance = subMeshDistance; + rayAvatarResult._intersectionPoint = ray.origin + subMeshDistance * rayDirection; + rayAvatarResult._intersectionNormal = subMeshSurfaceNormal; + face = subMeshFace; + extraInfo = subMeshExtraInfo; + } else { + rayAvatarResult._intersect = false; } - } else if (rayAvatarResult._intersect){ + } + + if (rayAvatarResult._intersect) { + result.intersects = true; + result.avatarID = rayAvatarResult._intersectWithAvatar; + result.distance = rayAvatarResult._distance; + result.face = face; + result.intersection = rayAvatarResult._intersectionPoint; + result.surfaceNormal = rayAvatarResult._intersectionNormal; + result.jointIndex = rayAvatarResult._intersectWithJoint; + result.extraInfo = extraInfo; break; } } - if (rayAvatarResult._intersect) { - result.intersects = true; - result.avatarID = rayAvatarResult._intersectWithAvatar; - result.distance = rayAvatarResult._distance; - result.surfaceNormal = rayAvatarResult._intersectionNormal; - result.jointIndex = rayAvatarResult._intersectWithJoint; - result.intersection = ray.origin + rayAvatarResult._distance * rayDirection; - result.extraInfo = extraInfo; - result.face = face; - } } + return result; } From 0e35458f9eeb3f00f71886657b93f46238030552 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 30 Jan 2019 13:27:47 -0800 Subject: [PATCH 2/3] use precisionPicking in RayPick::getAvatarIntersection --- interface/src/raypick/RayPick.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index 24ba4435e2..d476357bab 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -56,7 +56,8 @@ PickResultPointer RayPick::getOverlayIntersection(const PickRay& pick) { } PickResultPointer RayPick::getAvatarIntersection(const PickRay& pick) { - RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(pick, getIncludeItemsAs(), getIgnoreItemsAs(), true); + bool precisionPicking = !(getFilter().isCoarse() || DependencyManager::get()->getForceCoarsePicking()); + RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(pick, getIncludeItemsAs(), getIgnoreItemsAs(), precisionPicking); if (avatarRes.intersects) { return std::make_shared(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, pick, avatarRes.surfaceNormal, avatarRes.extraInfo); } else { From 6cbc0fad7f4304a8189af1f4e8d37de8f96dac1a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 30 Jan 2019 15:33:14 -0800 Subject: [PATCH 3/3] fixes --- interface/src/avatar/AvatarManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 376c4e7931..0b33220c01 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -718,7 +718,7 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic if (rayAvatarResult._intersect && pickAgainstMesh) { glm::vec3 localRayOrigin = avatar->worldToJointPoint(ray.origin, rayAvatarResult._intersectWithJoint); - glm::vec3 localRayPoint = avatar->worldToJointPoint(ray.origin + rayDirection, rayAvatarResult._intersectWithJoint); + glm::vec3 localRayPoint = avatar->worldToJointPoint(ray.origin + rayAvatarResult._distance * rayDirection, rayAvatarResult._intersectWithJoint); auto avatarOrientation = avatar->getWorldOrientation(); auto avatarPosition = avatar->getWorldPosition(); @@ -728,7 +728,7 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic auto defaultFrameRayOrigin = jointPosition + jointOrientation * localRayOrigin; auto defaultFrameRayPoint = jointPosition + jointOrientation * localRayPoint; - auto defaultFrameRayDirection = defaultFrameRayPoint - defaultFrameRayOrigin; + auto defaultFrameRayDirection = glm::normalize(defaultFrameRayPoint - defaultFrameRayOrigin); float subMeshDistance = FLT_MAX; BoxFace subMeshFace = BoxFace::UNKNOWN_FACE; @@ -750,7 +750,7 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic result.avatarID = rayAvatarResult._intersectWithAvatar; result.distance = rayAvatarResult._distance; result.face = face; - result.intersection = rayAvatarResult._intersectionPoint; + result.intersection = ray.origin + rayAvatarResult._distance * rayDirection; result.surfaceNormal = rayAvatarResult._intersectionNormal; result.jointIndex = rayAvatarResult._intersectWithJoint; result.extraInfo = extraInfo;