mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 19:24:32 +02:00
memoize audio ignore box in AudioMixerClientData
This commit is contained in:
parent
ff56eb24c8
commit
569ae113a0
3 changed files with 52 additions and 24 deletions
|
@ -59,6 +59,40 @@ AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
AABox& AudioMixerClientData::getIgnoreBox(unsigned int frame) {
|
||||
// check for a memoized box
|
||||
if (frame != _ignoreBoxMemo.frame.load(std::memory_order_acquire) {
|
||||
// create the box
|
||||
AABox box(getAvatarBoundingBoxCorner(), getAvatarBoundingBoxScale());
|
||||
|
||||
// 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(getAvatarBoundingBoxScale(), MIN_IGNORE_BOX_SCALE))) {
|
||||
box.setScaleStayCentered(MIN_IGNORE_BOX_SCALE);
|
||||
}
|
||||
|
||||
// quadruple the scale
|
||||
const float IGNORE_BOX_SCALE_FACTOR = 4.0f;
|
||||
box.embiggen(IGNORE_BOX_SCALE_FACTOR);
|
||||
|
||||
// update the memoized box
|
||||
// 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 lock(_ignoreBoxMemo.mutex);
|
||||
if (frame != _ignoreBoxMemo.frame.load(std::memory_order_acquire)) {
|
||||
_ignoreBoxMemo.box = box;
|
||||
unsigned int oldFrame = _ignoreBoxMemo.frame.exchange(frame, std::memory_order_release);
|
||||
|
||||
// check the precondition
|
||||
assert(frame == (oldFrame + 1));
|
||||
}
|
||||
}
|
||||
|
||||
return _ignoreBoxMemo.box;
|
||||
}
|
||||
|
||||
void AudioMixerClientData::removeHRTFForStream(const QUuid& nodeID, const QUuid& streamID) {
|
||||
auto it = _nodeSourcesHRTFMap.find(nodeID);
|
||||
if (it != _nodeSourcesHRTFMap.end()) {
|
||||
|
|
|
@ -38,6 +38,12 @@ public:
|
|||
AudioStreamMap getAudioStreams() { QReadLocker readLock { &_streamsLock }; return _audioStreams; }
|
||||
AvatarAudioStream* getAvatarAudioStream();
|
||||
|
||||
// returns an ignore box, memoized by frame (lockless if the box is already memoized)
|
||||
// preconditions:
|
||||
// - frame is monotonically increasing
|
||||
// - calls are only made to getIgnoreBox(frame + 1) when there are no references left from calls to getIgnoreBox(frame)
|
||||
AABox& AudioMixerClientData::getIgnoreBox(unsigned int frame);
|
||||
|
||||
// the following methods should be called from the AudioMixer assignment thread ONLY
|
||||
// they are not thread-safe
|
||||
|
||||
|
@ -86,7 +92,7 @@ public:
|
|||
bool shouldFlushEncoder() { return _shouldFlushEncoder; }
|
||||
|
||||
QString getCodecName() { return _selectedCodecName; }
|
||||
|
||||
|
||||
bool shouldMuteClient() { return _shouldMuteClient; }
|
||||
void setShouldMuteClient(bool shouldMuteClient) { _shouldMuteClient = shouldMuteClient; }
|
||||
glm::vec3 getPosition() { return getAvatarAudioStream() ? getAvatarAudioStream()->getPosition() : glm::vec3(0); }
|
||||
|
@ -106,6 +112,13 @@ private:
|
|||
QReadWriteLock _streamsLock;
|
||||
AudioStreamMap _audioStreams; // microphone stream from avatar is stored under key of null UUID
|
||||
|
||||
struct IgnoreBoxMemo {
|
||||
AABox box;
|
||||
std::atomic<unsigned int> frame { 0 };
|
||||
std::mutex mutex;
|
||||
};
|
||||
IgnoreBoxMemo _ignoreBoxMemo;
|
||||
|
||||
using HRTFMap = std::unordered_map<QUuid, AudioHRTF>;
|
||||
using NodeSourcesHRTFMap = std::unordered_map<QUuid, HRTFMap>;
|
||||
NodeSourcesHRTFMap _nodeSourcesHRTFMap;
|
||||
|
|
|
@ -146,7 +146,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) {
|
|||
mixStream(*listenerData, node->getUUID(), *listenerAudioStream, *nodeStream);
|
||||
}
|
||||
}
|
||||
} else if (!shouldIgnoreNode(listener, node)) {
|
||||
} else if (!shouldIgnoreNode(listener, node, _frame)) {
|
||||
if (!isThrottling) {
|
||||
allStreams(node, &AudioMixerSlave::mixStream);
|
||||
} else {
|
||||
|
@ -452,7 +452,7 @@ void sendEnvironmentPacket(const SharedNodePointer& node, AudioMixerClientData&
|
|||
}
|
||||
}
|
||||
|
||||
bool shouldIgnoreNode(const SharedNodePointer& listener, const SharedNodePointer& node) {
|
||||
bool shouldIgnoreNode(const SharedNodePointer& listener, const SharedNodePointer& node, unsigned int frame) {
|
||||
AudioMixerClientData* listenerData = static_cast<AudioMixerClientData*>(listener->getLinkedData());
|
||||
AudioMixerClientData* nodeData = static_cast<AudioMixerClientData*>(node->getLinkedData());
|
||||
|
||||
|
@ -469,27 +469,8 @@ bool shouldIgnoreNode(const SharedNodePointer& listener, const SharedNodePointer
|
|||
|
||||
// is either node enabling the space bubble / ignore radius?
|
||||
if ((listener->isIgnoreRadiusEnabled() || node->isIgnoreRadiusEnabled())) {
|
||||
// define the minimum bubble size
|
||||
static const glm::vec3 minBubbleSize = glm::vec3(0.3f, 1.3f, 0.3f);
|
||||
|
||||
// set up the bounding box for the listener
|
||||
AABox listenerBox(listenerData->getAvatarBoundingBoxCorner(), listenerData->getAvatarBoundingBoxScale());
|
||||
if (glm::any(glm::lessThan(listenerData->getAvatarBoundingBoxScale(), minBubbleSize))) {
|
||||
listenerBox.setScaleStayCentered(minBubbleSize);
|
||||
}
|
||||
|
||||
// set up the bounding box for the node
|
||||
AABox nodeBox(nodeData->getAvatarBoundingBoxCorner(), nodeData->getAvatarBoundingBoxScale());
|
||||
// Clamp the size of the bounding box to a minimum scale
|
||||
if (glm::any(glm::lessThan(nodeData->getAvatarBoundingBoxScale(), minBubbleSize))) {
|
||||
nodeBox.setScaleStayCentered(minBubbleSize);
|
||||
}
|
||||
|
||||
// quadruple the scale of both bounding boxes
|
||||
listenerBox.embiggen(4.0f);
|
||||
nodeBox.embiggen(4.0f);
|
||||
|
||||
// perform the collision check between the two bounding boxes
|
||||
AABox& listenerBox = listenerData->getIgnoreBox(frame);
|
||||
AABox& nodeBox = nodeData->getIgnoreBox(frame);
|
||||
ignore = listenerBox.touches(nodeBox);
|
||||
} else {
|
||||
ignore = false;
|
||||
|
|
Loading…
Reference in a new issue