From 607f34699301af95610ce4a0d72750e61b778a0e Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 7 Oct 2019 20:37:07 +0300 Subject: SL-9116 Implemented sound cut-off for llSetSoundRadius --- indra/newview/llaudiosourcevo.cpp | 98 +++++++++++++++++++++++++++++++-------- indra/newview/llaudiosourcevo.h | 4 ++ indra/newview/llviewerobject.cpp | 7 +++ indra/newview/llviewerobject.h | 2 + 4 files changed, 92 insertions(+), 19 deletions(-) diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp index b37aba6c15..4b6c855bde 100644 --- a/indra/newview/llaudiosourcevo.cpp +++ b/indra/newview/llaudiosourcevo.cpp @@ -29,8 +29,10 @@ #include "llaudiosourcevo.h" +#include "llagent.h" #include "llagentcamera.h" #include "llmutelist.h" +#include "llviewercontrol.h" #include "llviewerparcelmgr.h" LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp) @@ -54,6 +56,79 @@ void LLAudioSourceVO::setGain(const F32 gain) mGain = llclamp(gain, 0.f, 1.f); } +void LLAudioSourceVO::checkCutOffRadius() +{ + if (mSourceMuted // already muted by something, will be recalculated on update() + || !mObjectp) + { + return; + } + + F32 cutoff = mObjectp->getSoundCutOffRadius(); + if (cutoff < 0.1f) + { + // consider cutoff below 0.1m as off (to avoid near zero comparison) + return; + } + + LLVector3d pos_global = getPosGlobal(); + if (!isInCutOffRadius(pos_global, cutoff)) + { + mSourceMuted = true; + } +} + +LLVector3d LLAudioSourceVO::getPosGlobal() const +{ + if (mObjectp->isAttachment()) + { + LLViewerObject* parent = mObjectp; + while (parent && !parent->isAvatar()) + { + parent = (LLViewerObject*)parent->getParent(); + } + if (parent) + { + return parent->getPositionGlobal(); + } + } + else + { + return mObjectp->getPositionGlobal(); + } + return LLVector3d(); +} + +bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const +{ + static LLCachedControl ear_mode(gSavedSettings, "VoiceEarLocation", 0); + + LLVector3d pos_ear; + + switch (ear_mode()) + { + case 0: // camera + pos_ear = gAgentCamera.getCameraPositionGlobal(); + break; + + case 1: // avatar + case 2: + // voice support 'mixed' in '2' case with agent's position and camera's rotations + // but it is not defined in settings and uses camera as default + pos_ear = gAgent.getPositionGlobal(); + break; + + default: + pos_ear = gAgentCamera.getCameraPositionGlobal(); + break; + } + LLVector3d to_vec = pos_global - pos_ear; + + F32 dist = (F32)to_vec.magVec(); + + return dist < cutoff; +} + void LLAudioSourceVO::updateMute() { if (!mObjectp || mObjectp->isDead()) @@ -63,26 +138,11 @@ void LLAudioSourceVO::updateMute() } bool mute = false; - LLVector3d pos_global; - - if (mObjectp->isAttachment()) - { - LLViewerObject* parent = mObjectp; - while (parent && !parent->isAvatar()) - { - parent = (LLViewerObject*)parent->getParent(); - } - if (parent) - { - pos_global = parent->getPositionGlobal(); - } - } - else - { - pos_global = mObjectp->getPositionGlobal(); - } + LLVector3d pos_global = getPosGlobal(); - if (!LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) + F32 cutoff = mObjectp->getSoundCutOffRadius(); + if ((cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff)) // consider cutoff below 0.1m as off + || !LLViewerParcelMgr::getInstance()->canHearSound(pos_global)) { mute = true; } diff --git a/indra/newview/llaudiosourcevo.h b/indra/newview/llaudiosourcevo.h index f1d8ef4528..672a07f7d3 100644 --- a/indra/newview/llaudiosourcevo.h +++ b/indra/newview/llaudiosourcevo.h @@ -41,7 +41,11 @@ public: /*virtual*/ void update(); /*virtual*/ void setGain(const F32 gain); + void checkCutOffRadius(); + private: + LLVector3d getPosGlobal() const; + bool isInCutOffRadius(LLVector3d pos_global, const F32 cutoff) const; void updateMute(); private: diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8d7bfa42ed..bc0a151670 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -268,6 +268,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mData(NULL), mAudioSourcep(NULL), mAudioGain(1.f), + mSoundCutOffRadius(0.f), mAppAngle(0.f), mPixelArea(1024.f), mInventory(NULL), @@ -1245,6 +1246,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, LLUUID audio_uuid; LLUUID owner_id; // only valid if audio_uuid or particle system is not null F32 gain; + F32 cutoff; U8 sound_flags; mesgsys->getU32Fast( _PREHASH_ObjectData, _PREHASH_CRC, crc, block_num); @@ -1253,6 +1255,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // HACK: Owner id only valid if non-null sound id or particle system mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, block_num ); mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Gain, gain, block_num ); + mesgsys->getF32Fast( _PREHASH_ObjectData, _PREHASH_Radius, cutoff, block_num ); mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Flags, sound_flags, block_num ); mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_Material, material, block_num ); mesgsys->getU8Fast( _PREHASH_ObjectData, _PREHASH_ClickAction, click_action, block_num); @@ -1261,6 +1264,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_ObjectData, data, length, block_num, MAX_OBJECT_BINARY_DATA_SIZE); mTotalCRC = crc; + mSoundCutOffRadius = cutoff; // Owner ID used for sound muting or particle system muting setAttachedSound(audio_uuid, owner_id, gain, sound_flags); @@ -1957,6 +1961,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } mTotalCRC = crc; + mSoundCutOffRadius = cutoff; setAttachedSound(sound_uuid, owner_id, gain, sound_flags); @@ -5912,6 +5917,8 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow if( gAgent.canAccessMaturityAtGlobal(this->getPositionGlobal()) ) { //LL_INFOS() << "Playing attached sound " << audio_uuid << LL_ENDL; + // recheck cutoff radius in case this update was an object-update with new value + mAudioSourcep->checkCutOffRadius(); mAudioSourcep->play(audio_uuid); } } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index e9ae26939a..03c5403a1e 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -403,6 +403,7 @@ public: // Owner id is this object's owner void setAttachedSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const U8 flags); void adjustAudioGain(const F32 gain); + F32 getSoundCutOffRadius() const { return mSoundCutOffRadius; } void clearAttachedSound() { mAudioSourcep = NULL; } // Create if necessary @@ -790,6 +791,7 @@ protected: LLPointer mPartSourcep; // Particle source associated with this object. LLAudioSourceVO* mAudioSourcep; F32 mAudioGain; + F32 mSoundCutOffRadius; F32 mAppAngle; // Apparent visual arc in degrees F32 mPixelArea; // Apparent area in pixels -- cgit v1.2.3