bool UmbraSceneComponentController::UmbraOcclusionView::Update()

in Gems/Umbra/Code/Source/UmbraSceneComponent/UmbraSceneComponentController.cpp [433:514]


    bool UmbraSceneComponentController::UmbraOcclusionView::Update(
        const AZ::Vector3& cameraWorldPos, const AZ::Matrix4x4& cameraWorldToClip)
    {
        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.");
        AZ_Assert(m_objectIndexList, "Umbra object index list must be valid before query.");
        AZ_Assert(m_occlusionBuffer, "Umbra occlusion buffer must be instantiated before query.");

        // Reset the object index list and occlusion buffer
        m_objectIndexList->setSize(0);
        m_occlusionBuffer->clear();

        if (m_debugRenderer)
        {
            m_debugRenderer->m_debugLines.clear();
            m_debugRenderer->m_debugStats.clear();
        }

        // Convert the incoming camera transform into an umbra camera transform
        Umbra::Matrix4x4 worldToClip = {};
        cameraWorldToClip.StoreToRowMajorFloat16(reinterpret_cast<float*>(worldToClip.m));

        // Flip z-axis due to reverse Z perspective transform to get depth range [0,1]
        worldToClip.m[2][0] = -worldToClip.m[2][0] + worldToClip.m[3][0];
        worldToClip.m[2][1] = -worldToClip.m[2][1] + worldToClip.m[3][1];
        worldToClip.m[2][2] = -worldToClip.m[2][2] + worldToClip.m[3][2];
        worldToClip.m[2][3] = -worldToClip.m[2][3] + worldToClip.m[3][3];

        Umbra::Vector3 cameraPos = {};
        cameraWorldPos.StoreToFloat3(cameraPos.v);

        Umbra::CameraTransform camera(worldToClip, cameraPos, Umbra::CameraTransform::DEPTHRANGE_ZERO_TO_ONE, Umbra::MF_ROW_MAJOR);

        // Set up the visibility query parameters to fill in the object index list and occlusion buffer
        Umbra::Visibility visibility(m_objectIndexList.get(), m_occlusionBuffer.get());

        const auto& configuration = m_controller.m_configuration;
        const bool renderDebugInfo = m_debugRenderer && configuration.m_renderDebugInfo && !configuration.m_pauseDebugInfo;

        // Configure debug flags for data to be captured during the query
        uint32_t flags = 0;
        flags |= Umbra::Query::VisibilityQueryFlags::QUERYFLAG_IGNORE_CAMERA_POSITION;
        if (renderDebugInfo)
        {
            flags |= configuration.m_renderDebugBuffers ? Umbra::Query::VisibilityQueryFlags::DEBUGFLAG_VISIBILITY_LINES : 0;
            flags |= configuration.m_renderDebugBounds ? Umbra::Query::VisibilityQueryFlags::DEBUGFLAG_OBJECT_BOUNDS : 0;
            flags |= configuration.m_renderDebugVolumes ? Umbra::Query::VisibilityQueryFlags::DEBUGFLAG_VISIBLE_VOLUME : 0;
            flags |= configuration.m_renderDebugFrustums ? Umbra::Query::VisibilityQueryFlags::DEBUGFLAG_VIEW_FRUSTUM : 0;
            flags |= configuration.m_renderDebugStats ? Umbra::Query::VisibilityQueryFlags::DEBUGFLAG_STATISTICS : 0;
        }

        const Umbra::Query::ErrorCode errorCode = m_query->queryPortalVisibility(flags, visibility, camera);
        if (errorCode != Umbra::Query::ErrorCode::ERROR_OK)
        {
            Internal::PrintQueryErrorMessage(errorCode);
        }

        // Store a container of entity IDs corresponding to visible object indices.
        m_visibleEntityIds.clear();
        const int32_t objectIndexListSize = m_objectIndexList->getSize();
        const int32_t* objectIndexListPtr = m_objectIndexList->getPtr();
        m_visibleEntityIds.clear();
        m_visibleEntityIds.reserve(objectIndexListSize);
        for (int32_t i = 0; i < objectIndexListSize; ++i)
        {
            const int32_t objectIndex = objectIndexListPtr[i];
            if (m_controller.m_objectIndexToEntityIdTable.size() > objectIndex)
            {
                m_visibleEntityIds.insert(m_controller.m_objectIndexToEntityIdTable[objectIndex]);
            }
        }

        // Add any recorded data for debug lines and stats to the accumulated sets
        if (renderDebugInfo)
        {
            AZStd::scoped_lock<decltype(m_controller.m_debugMutex)> lock(m_controller.m_debugMutex);
            m_controller.m_debugLines.insert(m_debugRenderer->m_debugLines.begin(), m_debugRenderer->m_debugLines.end());
            m_controller.m_debugStats.insert(m_debugRenderer->m_debugStats.begin(), m_debugRenderer->m_debugStats.end());
        }

        return errorCode == Umbra::Query::ERROR_OK;
    }