summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llvoicewebrtc.cpp300
-rw-r--r--indra/newview/llvoicewebrtc.h47
2 files changed, 199 insertions, 148 deletions
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 9a1b3525d7..0ff8a09de8 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -85,6 +85,8 @@ extern LLMenuBarGL* gMenuBarView;
extern void handle_voice_morphing_subscribe();
namespace {
+
+ const F32 MAX_AUDIO_DIST = 50.0f;
const F32 VOLUME_SCALE_WEBRTC = 0.01f;
const F32 LEVEL_SCALE_WEBRTC = 0.008f;
@@ -391,56 +393,35 @@ void LLWebRTCVoiceClient::updateSettings()
/////////////////////////////
// session control messages
-void LLWebRTCVoiceClient::predOnConnectionEstablished(const LLWebRTCVoiceClient::sessionStatePtr_t& session, std::string channelID)
-{
- session->OnConnectionEstablished(channelID);
-}
-
-void LLWebRTCVoiceClient::predOnConnectionFailure(const LLWebRTCVoiceClient::sessionStatePtr_t& session, std::string channelID)
-{
- session->OnConnectionFailure(channelID);
-}
-
-void LLWebRTCVoiceClient::OnConnectionFailure(const std::string& channelID)
-{
- if (mNextAudioSession && mNextAudioSession->mChannelID == channelID)
- {
- LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
- }
- else if (mAudioSession && mAudioSession->mChannelID == channelID)
- {
- LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
- }
- sessionState::for_each(boost::bind(predOnConnectionFailure, _1, channelID));
-}
-
-void LLWebRTCVoiceClient::OnConnectionEstablished(const std::string& channelID)
+void LLWebRTCVoiceClient::OnConnectionFailure(const std::string& channelID, const LLUUID& regionID)
{
- if (mNextAudioSession && mNextAudioSession->mChannelID == channelID)
- {
- mAudioSession = mNextAudioSession;
- mNextAudioSession.reset();
- LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN);
- }
- else if (mAudioSession && mAudioSession->mChannelID == channelID)
- {
- LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN);
- }
- sessionState::for_each(boost::bind(predOnConnectionEstablished, _1, channelID));
-}
-
-void LLWebRTCVoiceClient::sessionState::OnConnectionEstablished(const std::string& channelID)
-{
- if (channelID == mPrimaryConnectionID)
+ if (gAgent.getRegion()->getRegionID() == regionID)
{
+ if (mNextAudioSession && mNextAudioSession->mChannelID == channelID)
+ {
+ LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
+ }
+ else if (mAudioSession && mAudioSession->mChannelID == channelID)
+ {
+ LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
+ }
}
}
-void LLWebRTCVoiceClient::sessionState::OnConnectionFailure(const std::string &channelID)
+void LLWebRTCVoiceClient::OnConnectionEstablished(const std::string& channelID, const LLUUID& regionID)
{
- if (channelID == mPrimaryConnectionID)
+ if (gAgent.getRegion()->getRegionID() == regionID)
{
- LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
+ if (mNextAudioSession && mNextAudioSession->mChannelID == channelID)
+ {
+ mAudioSession = mNextAudioSession;
+ mNextAudioSession.reset();
+ LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN);
+ }
+ else if (mAudioSession && mAudioSession->mChannelID == channelID)
+ {
+ LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN);
+ }
}
}
@@ -457,6 +438,7 @@ void LLWebRTCVoiceClient::idle(void* user_data)
void LLWebRTCVoiceClient::sessionState::processSessionStates()
{
+
auto iter = mSessions.begin();
while (iter != mSessions.end())
{
@@ -473,10 +455,20 @@ void LLWebRTCVoiceClient::sessionState::processSessionStates()
bool LLWebRTCVoiceClient::sessionState::processConnectionStates()
{
- std::list<connectionPtr_t>::iterator iter = mWebRTCConnections.begin();
+ // Estate voice requires connection to neighboring regions.
+ std::set<LLUUID> neighbor_ids = LLWebRTCVoiceClient::getInstance()->getNeighboringRegions();
+
+ std::list<connectionPtr_t>::iterator iter = mWebRTCConnections.begin();
while (iter != mWebRTCConnections.end())
{
+ if (neighbor_ids.find(iter->get()->getRegionID()) == neighbor_ids.end())
+ {
+ // shut down connections to neighbors that are too far away.
+ iter->get()->shutDown();
+ }
+ neighbor_ids.erase(iter->get()->getRegionID());
+
if (!iter->get()->connectionStateMachine())
{
iter = mWebRTCConnections.erase(iter);
@@ -486,6 +478,15 @@ bool LLWebRTCVoiceClient::sessionState::processConnectionStates()
++iter;
}
}
+
+ // add new connections for new neighbors
+ if (mSessionType == SESSION_TYPE_ESTATE)
+ {
+ for (auto &neighbor : neighbor_ids)
+ {
+ mWebRTCConnections.emplace_back(new LLVoiceWebRTCConnection(neighbor, INVALID_PARCEL_ID, mChannelID));
+ }
+ }
return !mWebRTCConnections.empty();
}
@@ -505,26 +506,33 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
{
continue;
}
-
- if (mVoiceEnabled && (!mAudioSession || mAudioSession->isSpatial()) && !mNextAudioSession)
+ bool voiceEnabled = mVoiceEnabled && regionp->isVoiceEnabled();
+ if ((!mAudioSession || mAudioSession->isSpatial()) && !mNextAudioSession)
{
// check to see if parcel changed.
- std::string channelID = regionp->getRegionID().asString();
+ std::string channelID = "Estate";
+ S32 parcel_local_id = INVALID_PARCEL_ID;
- LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- S32 parcel_local_id = INVALID_PARCEL_ID;
- if (parcel && parcel->getLocalID() != INVALID_PARCEL_ID)
+ if (voiceEnabled)
{
- if (!parcel->getParcelFlagAllowVoice())
- {
- channelID.clear();
- }
- else if (!parcel->getParcelFlagUseEstateVoiceChannel())
+ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel && parcel->getLocalID() != INVALID_PARCEL_ID)
{
- parcel_local_id = parcel->getLocalID();
- channelID += "-" + std::to_string(parcel->getLocalID());
+ if (!parcel->getParcelFlagAllowVoice())
+ {
+ channelID.clear();
+ }
+ else if (!parcel->getParcelFlagUseEstateVoiceChannel())
+ {
+ parcel_local_id = parcel->getLocalID();
+ channelID = regionp->getRegionID().asString() + "-" + std::to_string(parcel->getLocalID());
+ }
}
}
+ else
+ {
+ channelID.clear();
+ }
if ((mNextAudioSession && channelID != mNextAudioSession->mChannelID) ||
(!mAudioSession && !channelID.empty()) ||
@@ -533,8 +541,12 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
setSpatialChannel(channelID, "", parcel_local_id);
}
}
+ else
+ {
+
+ }
sessionState::processSessionStates();
- if (mVoiceEnabled)
+ if (voiceEnabled)
{
updatePosition();
sendPositionAndVolumeUpdate(true);
@@ -766,26 +778,6 @@ void LLWebRTCVoiceClient::sendPositionAndVolumeUpdate(bool force)
if (mSpatialCoordsDirty || force)
{
Json::Value spatial = Json::objectValue;
- LLVector3d earPosition;
- LLQuaternion earRot;
- switch (mEarLocation)
- {
- case earLocCamera:
- default:
- earPosition = mCameraPosition;
- earRot = mCameraRot;
- break;
-
- case earLocAvatar:
- earPosition = mAvatarPosition;
- earRot = mAvatarRot;
- break;
-
- case earLocMixed:
- earPosition = mAvatarPosition;
- earRot = mCameraRot;
- break;
- }
spatial["sp"] = Json::objectValue;
spatial["sp"]["x"] = (int) (mAvatarPosition[0] * 100);
@@ -798,14 +790,14 @@ void LLWebRTCVoiceClient::sendPositionAndVolumeUpdate(bool force)
spatial["sh"]["w"] = (int) (mAvatarRot[3] * 100);
spatial["lp"] = Json::objectValue;
- spatial["lp"]["x"] = (int) (earPosition[0] * 100);
- spatial["lp"]["y"] = (int) (earPosition[1] * 100);
- spatial["lp"]["z"] = (int) (earPosition[2] * 100);
+ spatial["lp"]["x"] = (int) (mListenerPosition[0] * 100);
+ spatial["lp"]["y"] = (int) (mListenerPosition[1] * 100);
+ spatial["lp"]["z"] = (int) (mListenerPosition[2] * 100);
spatial["lh"] = Json::objectValue;
- spatial["lh"]["x"] = (int) (earRot[0] * 100);
- spatial["lh"]["y"] = (int) (earRot[1] * 100);
- spatial["lh"]["z"] = (int) (earRot[2] * 100);
- spatial["lh"]["w"] = (int) (earRot[3] * 100);
+ spatial["lh"]["x"] = (int) (mListenerRot[0] * 100);
+ spatial["lh"]["y"] = (int) (mListenerRot[1] * 100);
+ spatial["lh"]["z"] = (int) (mListenerRot[2] * 100);
+ spatial["lh"]["w"] = (int) (mListenerRot[3] * 100);
mSpatialCoordsDirty = false;
if (force || (uint_audio_level != mAudioLevel))
@@ -1479,79 +1471,120 @@ std::string LLWebRTCVoiceClient::getAudioSessionURI()
/////////////////////////////
// Sending updates of current state
-void LLWebRTCVoiceClient::enforceTether(void)
+void LLWebRTCVoiceClient::enforceTether()
{
- LLVector3d tethered = mCameraRequestedPosition;
+ LLVector3d tethered = mListenerRequestedPosition;
// constrain 'tethered' to within 50m of mAvatarPosition.
{
- F32 max_dist = 50.0f;
- LLVector3d camera_offset = mCameraRequestedPosition - mAvatarPosition;
+ LLVector3d camera_offset = mListenerRequestedPosition - mAvatarPosition;
F32 camera_distance = (F32)camera_offset.magVec();
- if(camera_distance > max_dist)
+ if(camera_distance > MAX_AUDIO_DIST)
{
tethered = mAvatarPosition +
- (max_dist / camera_distance) * camera_offset;
+ (MAX_AUDIO_DIST / camera_distance) * camera_offset;
}
}
- if(dist_vec_squared(mCameraPosition, tethered) > 0.01)
+ if(dist_vec_squared(mListenerPosition, tethered) > 0.01)
{
- mCameraPosition = tethered;
+ mListenerPosition = tethered;
mSpatialCoordsDirty = true;
}
}
-void LLWebRTCVoiceClient::updatePosition(void)
+void LLWebRTCVoiceClient::updateNeighboringRegions()
{
+ static const std::vector<LLVector3d> neighbors {LLVector3d(0.0f, 1.0f, 0.0f), LLVector3d(0.707f, 0.707f, 0.0f),
+ LLVector3d(1.0f, 0.0f, 0.0f), LLVector3d(0.707f, -0.707f, 0.0f),
+ LLVector3d(0.0f, -1.0f, 0.0f), LLVector3d(-0.707f, -0.707f, 0.0f),
+ LLVector3d(-1.0f, 0.0f, 0.0f), LLVector3d(-0.707f, 0.707f, 0.0f)};
+ // Estate voice requires connection to neighboring regions.
+ mNeighboringRegions.clear();
+
+ mNeighboringRegions.insert(gAgent.getRegion()->getRegionID());
+
+ // base off of speaker position as it'll move more slowly than camera position.
+ // Once we have hysteresis, we may be able to track off of speaker and camera position at 50m
+ // TODO: Add hysteresis so we don't flip-flop connections to neighbors
+ LLVector3d speaker_pos = LLWebRTCVoiceClient::getInstance()->getSpeakerPosition();
+ for (auto &neighbor_pos : neighbors)
+ {
+ // include every region within 100m (2*MAX_AUDIO_DIST) to deal witht he fact that the camera
+ // can stray 50m away from the avatar.
+ LLViewerRegion *neighbor = LLWorld::instance().getRegionFromPosGlobal(speaker_pos + 2 * MAX_AUDIO_DIST * neighbor_pos);
+ if (neighbor && !neighbor->getRegionID().isNull())
+ {
+ mNeighboringRegions.insert(neighbor->getRegionID());
+ }
+ }
+}
+
+void LLWebRTCVoiceClient::updatePosition(void)
+{
LLViewerRegion *region = gAgent.getRegion();
if(region && isAgentAvatarValid())
{
- LLVector3d pos;
- LLQuaternion qrot;
+ LLVector3d avatar_pos = gAgentAvatarp->getPositionGlobal();
+ LLQuaternion avatar_qrot = gAgentAvatarp->getRootJoint()->getWorldRotation();
+
+ avatar_pos += LLVector3d(0.f, 0.f, 1.f); // bump it up to head height
// TODO: If camera and avatar velocity are actually used by the voice system, we could compute them here...
// They're currently always set to zero.
-
- // Send the current camera position to the voice code
- pos = gAgent.getRegion()->getPosGlobalFromRegion(LLViewerCamera::getInstance()->getOrigin());
-
- LLWebRTCVoiceClient::getInstance()->setCameraPosition(
- pos, // position
- LLVector3::zero, // velocity
- LLViewerCamera::getInstance()->getQuaternion()); // rotation matrix
-
- // Send the current avatar position to the voice code
- qrot = gAgentAvatarp->getRootJoint()->getWorldRotation();
- pos = gAgentAvatarp->getPositionGlobal();
+ LLVector3d earPosition;
+ LLQuaternion earRot;
+ switch (mEarLocation)
+ {
+ case earLocCamera:
+ default:
+ earPosition = region->getPosGlobalFromRegion(LLViewerCamera::getInstance()->getOrigin());
+ earRot = LLViewerCamera::getInstance()->getQuaternion();
+ break;
- // TODO: Can we get the head offset from outside the LLVOAvatar?
- // pos += LLVector3d(mHeadOffset);
- pos += LLVector3d(0.f, 0.f, 1.f);
+ case earLocAvatar:
+ earPosition = mAvatarPosition;
+ earRot = mAvatarRot;
+ break;
+
+ case earLocMixed:
+ earPosition = mAvatarPosition;
+ earRot = LLViewerCamera::getInstance()->getQuaternion();
+ break;
+ }
+ setListenerPosition(earPosition, // position
+ LLVector3::zero, // velocity
+ earRot); // rotation matrix
- LLWebRTCVoiceClient::getInstance()->setAvatarPosition(
- pos, // position
- LLVector3::zero, // velocity
- qrot); // rotation matrix
+ setAvatarPosition(
+ avatar_pos, // position
+ LLVector3::zero, // velocity
+ avatar_qrot); // rotation matrix
enforceTether();
+
+ if (mSpatialCoordsDirty)
+ {
+ updateNeighboringRegions();
+ }
}
}
-void LLWebRTCVoiceClient::setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLQuaternion &rot)
+void LLWebRTCVoiceClient::setListenerPosition(const LLVector3d &position, const LLVector3 &velocity, const LLQuaternion &rot)
{
- mCameraRequestedPosition = position;
+
+ mListenerPosition = position;
- if(mCameraVelocity != velocity)
+ if(mListenerVelocity != velocity)
{
- mCameraVelocity = velocity;
+ mListenerVelocity = velocity;
mSpatialCoordsDirty = true;
}
- if(mCameraRot != rot)
+ if(mListenerRot != rot)
{
- mCameraRot = rot;
+ mListenerRot = rot;
mSpatialCoordsDirty = true;
}
}
@@ -1925,7 +1958,8 @@ LLWebRTCVoiceClient::sessionState::sessionState() :
mErrorStatusCode(0),
mVolumeDirty(false),
mMuteDirty(false),
- mParticipantsChanged(false)
+ mParticipantsChanged(false),
+ mShuttingDown(false)
{
}
@@ -2047,7 +2081,8 @@ LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::findP2PSession(const
void LLWebRTCVoiceClient::sessionState::shutdownAllConnections()
-{
+{
+ mShuttingDown = true;
for (auto &&connection : mWebRTCConnections)
{
connection->shutDown();
@@ -2686,7 +2721,7 @@ void LLVoiceWebRTCConnection::OnVoiceConnectionRequestFailure(std::string url, i
boost::bind(&LLVoiceWebRTCConnection::OnVoiceConnectionRequestFailure, this, url, retries - 1, body, _1));
return;
}
- LL_WARNS("Voice") << "Unable to connect voice." << result << LL_ENDL;
+ LL_WARNS("Voice") << "Unable to connect voice." << body << " RESULT: " << result << LL_ENDL;
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
mOutstandingRequests--;
}
@@ -2753,7 +2788,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
mWebRTCAudioInterface->setMute(mMuted);
mWebRTCAudioInterface->setReceiveVolume(mSpeakerVolume);
mWebRTCAudioInterface->setSendVolume(mMicGain);
- LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID);
+ LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID, mRegionID);
setVoiceConnectionState(VOICE_STATE_SESSION_UP);
}
break;
@@ -2767,7 +2802,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
}
case VOICE_STATE_SESSION_RETRY:
- LLWebRTCVoiceClient::getInstance()->OnConnectionFailure(mChannelID);
+ LLWebRTCVoiceClient::getInstance()->OnConnectionFailure(mChannelID, mRegionID);
setVoiceConnectionState(VOICE_STATE_DISCONNECT);
break;
break;
@@ -2903,10 +2938,19 @@ void LLVoiceWebRTCConnection::OnVoiceDisconnectionRequestFailure(std::string url
void LLVoiceWebRTCConnection::setMuteMic(bool muted)
{
- mMuted = true;
+ mMuted = muted;
if (mWebRTCAudioInterface)
{
- mWebRTCAudioInterface->setMute(muted);
+ LLViewerRegion *regionp = gAgent.getRegion();
+ if (regionp && mRegionID == regionp->getRegionID())
+ {
+ mWebRTCAudioInterface->setMute(muted);
+ }
+ else
+ {
+ // always mute to regions the agent isn't on, to prevent echo.
+ mWebRTCAudioInterface->setMute(true);
+ }
}
}
diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h
index 1e8ecdf5c2..9b8372cba7 100644
--- a/indra/newview/llvoicewebrtc.h
+++ b/indra/newview/llvoicewebrtc.h
@@ -242,8 +242,8 @@ public:
void userAuthorized(const std::string &user_id, const LLUUID &agentID) override {};
- void OnConnectionEstablished(const std::string& channelID);
- void OnConnectionFailure(const std::string &channelID);
+ void OnConnectionEstablished(const std::string& channelID, const LLUUID& regionID);
+ void OnConnectionFailure(const std::string &channelID, const LLUUID& regionID);
void sendPositionAndVolumeUpdate(bool force);
void updateOwnVolume();
@@ -312,6 +312,12 @@ public:
typedef boost::weak_ptr<sessionState> wptr_t;
typedef boost::function<void(const ptr_t &)> sessionFunc_t;
+ typedef enum e_session_type
+ {
+ SESSION_TYPE_ESTATE = 1,
+ SESSION_TYPE_PARCEL,
+ SESSION_TYPE_P2P
+ } ESessionType;
static ptr_t createSession(const std::string& channelID, S32 parcel_local_id);
~sessionState();
@@ -334,9 +340,6 @@ public:
bool processConnectionStates();
- void OnConnectionEstablished(const std::string &channelID);
- void OnConnectionFailure(const std::string &channelID);
-
void sendData(const std::string &data);
void setMuteMic(bool muted);
@@ -351,12 +354,7 @@ public:
bool isSpatial() { return mSessionType == SESSION_TYPE_ESTATE || mSessionType == SESSION_TYPE_PARCEL; }
- typedef enum e_session_type
- {
- SESSION_TYPE_ESTATE = 1,
- SESSION_TYPE_PARCEL,
- SESSION_TYPE_P2P
- } ESessionType;
+ ESessionType getSessionType() { return mSessionType; }
std::string mHandle;
std::string mGroupHandle;
@@ -378,6 +376,7 @@ public:
bool mIncoming;
bool mVoiceActive;
bool mReconnect; // Whether we should try to reconnect to this session if it's dropped
+ bool mShuttingDown;
// Set to true when the volume/mute state of someone in the participant list changes.
// The code will have to walk the list to find the changed participant(s).
@@ -417,8 +416,6 @@ public:
// Private Member Functions
//////////////////////////////////////////////////////
- static void predOnConnectionEstablished(const LLWebRTCVoiceClient::sessionStatePtr_t &session, std::string channelID);
- static void predOnConnectionFailure(const LLWebRTCVoiceClient::sessionStatePtr_t &session, std::string channelID);
static void predSendData(const LLWebRTCVoiceClient::sessionStatePtr_t &session, const std::string& spatial_data, const std::string& volume_data);
static void predUpdateOwnVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 audio_level);
static void predSetMuteMic(const LLWebRTCVoiceClient::sessionStatePtr_t &session, bool mute);
@@ -459,10 +456,13 @@ public:
/////////////////////////////
// Sending updates of current state
void updatePosition(void);
- void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLQuaternion &rot);
+ void setListenerPosition(const LLVector3d &position, const LLVector3 &velocity, const LLQuaternion &rot);
void setAvatarPosition(const LLVector3d &position, const LLVector3 &velocity, const LLQuaternion &rot);
bool channelFromRegion(LLViewerRegion *region, std::string &name);
+ LLVector3d getListenerPosition() { return mListenerPosition; }
+ LLVector3d getSpeakerPosition() { return mAvatarPosition; }
+
void setEarLocation(S32 loc);
@@ -613,23 +613,28 @@ private:
std::string displayNameFromAvatar(LLVOAvatar *avatar);
- bool inSpatialChannel(void);
+ bool inSpatialChannel();
std::string getAudioSessionURI();
void setHidden(bool hidden) override; //virtual
- void enforceTether(void);
+ void enforceTether();
+
+ void updateNeighboringRegions();
+ std::set<LLUUID> getNeighboringRegions() { return mNeighboringRegions; }
bool mSpatialCoordsDirty;
- LLVector3d mCameraPosition;
- LLVector3d mCameraRequestedPosition;
- LLVector3 mCameraVelocity;
- LLQuaternion mCameraRot;
+ LLVector3d mListenerPosition;
+ LLVector3d mListenerRequestedPosition;
+ LLVector3 mListenerVelocity;
+ LLQuaternion mListenerRot;
LLVector3d mAvatarPosition;
LLVector3 mAvatarVelocity;
LLQuaternion mAvatarRot;
+
+ std::set<LLUUID> mNeighboringRegions; // includes current region
bool mMuteMic;
bool mMuteMicDirty;
@@ -763,6 +768,8 @@ class LLVoiceWebRTCConnection :
void setMicGain(F32 volume);
void setSpeakerVolume(F32 volume);
+ LLUUID getRegionID() { return mRegionID; }
+
void shutDown()
{
LLMutexLock lock(&mVoiceStateMutex);