in Gems/Umbra/Code/Source/UmbraSceneComponent/UmbraSceneComponentController.cpp [609:660]
AZStd::vector<AzFramework::OcclusionState> UmbraSceneComponentController::UmbraOcclusionView::GetSphereToSphereVisibility(const AZ::Sphere& sourceSphere, const AZStd::vector<AZ::Sphere>& targetSpheres) const
{
AZ_Assert(m_controller.IsSceneReady(), "Umbra scene component controller and assets must be valid and ready before query.");
AZ_Assert(m_query, "Umbra query object must be valid before query.");
if (!m_controller.IsSceneReady() || !m_query || targetSpheres.empty())
{
return {};
}
// Convert all of the O3DE data types into Umbra data types for the query
Umbra::Sphere source = {};
sourceSphere.GetCenter().StoreToFloat3(source.center.v);
source.radius = sourceSphere.GetRadius();
const int targetCount = aznumeric_cast<int>(targetSpheres.size());
AZStd::vector<Umbra::Sphere> targets(targetCount, Umbra::Sphere{});
for (int i = 0; i < targetCount; ++i)
{
targetSpheres[i].GetCenter().StoreToFloat3(targets[i].center.v);
targets[i].radius = targetSpheres[i].GetRadius();
}
// Create a container for all of the intersection results, defaulting all objects to being visible.
AZStd::vector<Umbra::QueryExt::IntersectionResult> intersections(targetCount, Umbra::QueryExt::IntersectionResult::IRESULT_NO_INTERSECTION);
const Umbra::Query::ErrorCode errorCode = m_query->querySphereVisibility(source, targets.data(), targetCount, 0, intersections.data());
if (errorCode != Umbra::Query::ErrorCode::ERROR_OK)
{
Internal::PrintQueryErrorMessage(errorCode);
return {};
}
// Convert all of the intersection data into flags, returning true if source and target can see each other.
AZStd::vector<AzFramework::OcclusionState> results(targetCount, AzFramework::OcclusionState::Unknown);
for (int i = 0; i < targetCount; ++i)
{
switch (intersections[i])
{
case Umbra::QueryExt::IntersectionResult::IRESULT_INTERSECTION:
results[i] = AzFramework::OcclusionState::Hidden;
break;
case Umbra::QueryExt::IntersectionResult::IRESULT_NO_INTERSECTION:
results[i] = AzFramework::OcclusionState::Visible;
break;
default:
results[i] = AzFramework::OcclusionState::Unknown;
break;
}
}
return results;
}