Пример #1
0
AudioMixerClientData::IgnoreZone& AudioMixerClientData::IgnoreZoneMemo::get(unsigned int frame) {
    // check for a memoized zone
    if (frame != _frame.load(std::memory_order_acquire)) {
        AvatarAudioStream* stream = _data.getAvatarAudioStream();

        // get the initial dimensions from the stream
        glm::vec3 corner = stream ? stream->getAvatarBoundingBoxCorner() : glm::vec3(0);
        glm::vec3 scale = stream ? stream->getAvatarBoundingBoxScale() : glm::vec3(0);

        // enforce a minimum scale
        static const glm::vec3 MIN_IGNORE_BOX_SCALE = glm::vec3(0.3f, 1.3f, 0.3f);
        if (glm::any(glm::lessThan(scale, MIN_IGNORE_BOX_SCALE))) {
            scale = MIN_IGNORE_BOX_SCALE;
        }

        // quadruple the scale (this is arbitrary number chosen for comfort)
        const float IGNORE_BOX_SCALE_FACTOR = 4.0f;
        scale *= IGNORE_BOX_SCALE_FACTOR;

        // create the box (we use a box for the zone for convenience)
        AABox box(corner, scale);

        // update the memoized zone
        // This may be called by multiple threads concurrently,
        // so take a lock and only update the memo if this call is first.
        // This prevents concurrent updates from invalidating the returned reference
        // (contingent on the preconditions listed in the header).
        std::lock_guard<std::mutex> lock(_mutex);
        if (frame != _frame.load(std::memory_order_acquire)) {
            _zone = box;
            unsigned int oldFrame = _frame.exchange(frame, std::memory_order_release);
            Q_UNUSED(oldFrame);
        }
    }

    return _zone;
}