mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-15 17:46:47 +02:00
Merge pull request #14816 from SamGondelman/avatar
Case 20924: Cleaning up Avatar findRayIntersection
This commit is contained in:
commit
f9b86725fd
2 changed files with 55 additions and 52 deletions
|
@ -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<MyCharacterController::RayAvatarResult> physicsResults = _myAvatar->getCharacterController()->rayTest(glmToBullet(ray.origin), glmToBullet(rayDirection), distance, QVector<uint>());
|
||||
std::vector<MyCharacterController::RayAvatarResult> physicsResults = _myAvatar->getCharacterController()->rayTest(glmToBullet(ray.origin), glmToBullet(rayDirection), bulletDistance, QVector<uint>());
|
||||
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,46 +680,45 @@ 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<MyCharacterController::RayAvatarResult> 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);
|
||||
glm::vec3 localRayPoint = avatar->worldToJointPoint(ray.origin + rayAvatarResult._distance * rayDirection, rayAvatarResult._intersectWithJoint);
|
||||
|
||||
auto avatarOrientation = avatar->getWorldOrientation();
|
||||
auto avatarPosition = avatar->getWorldPosition();
|
||||
|
@ -732,31 +728,37 @@ 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);
|
||||
|
||||
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 = ray.origin + rayAvatarResult._distance * rayDirection;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,8 @@ PickResultPointer RayPick::getOverlayIntersection(const PickRay& pick) {
|
|||
}
|
||||
|
||||
PickResultPointer RayPick::getAvatarIntersection(const PickRay& pick) {
|
||||
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersectionVector(pick, getIncludeItemsAs<EntityItemID>(), getIgnoreItemsAs<EntityItemID>(), true);
|
||||
bool precisionPicking = !(getFilter().isCoarse() || DependencyManager::get<PickManager>()->getForceCoarsePicking());
|
||||
RayToAvatarIntersectionResult avatarRes = DependencyManager::get<AvatarManager>()->findRayIntersectionVector(pick, getIncludeItemsAs<EntityItemID>(), getIgnoreItemsAs<EntityItemID>(), precisionPicking);
|
||||
if (avatarRes.intersects) {
|
||||
return std::make_shared<RayPickResult>(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, pick, avatarRes.surfaceNormal, avatarRes.extraInfo);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue