AZStd::vector UmbraSceneComponentController::UmbraOcclusionView::GetSphereToSphereVisibility()

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;
    }