diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 65d37f8e0..12960ac01 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -543,3 +543,17 @@ LLAnimPauseRequest LLCharacter::requestPause() return mPauseRequest; } +void LLCharacter::requestPause(std::vector& avatar_pause_handles) +{ + mMotionController.pauseAllMotions(); + avatar_pause_handles.push_back(mPauseRequest); +} + +void LLCharacter::pauseAllSyncedCharacters(std::vector& avatar_pause_handles) +{ + // Pause this avatar. + requestPause(avatar_pause_handles); + // Also pause all avatars with synchronized motions. + mMotionController.pauseAllSyncedCharacters(avatar_pause_handles); +} + diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 74cc35187..f618b446f 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -159,6 +159,8 @@ public: void updateMotions(e_update_t update_type); LLAnimPauseRequest requestPause(); + void requestPause(std::vector& avatar_pause_handles); + void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); BOOL areAnimationsPaused() const { return mMotionController.isPaused(); } void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); } void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); } diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 7c7192be0..f5380957f 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -1257,6 +1257,44 @@ void LLMotionController::refresh_hidden(void) } } } + +void LLMotionController::pauseAllSyncedCharacters(std::vector& avatar_pause_handles) +{ + // Run over all motions. + for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter) + { + LLMotion* motionp = *iter; + AISyncServer* server = motionp->server(); + if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active. + { + // Run over all clients of the found servers. + AISyncServer::client_list_t const& clients = server->getClients(); + for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client) + { + LLMotion* motion = dynamic_cast(client->mClientPtr); + if (!motion) + { + continue; + } + LLMotionController* controller = motion->getController(); + if (controller == this) + { + continue; + } + controller->requestPause(avatar_pause_handles); + } + } + } +} + +void LLMotionController::requestPause(std::vector& avatar_pause_handles) +{ + if (mCharacter) + { + mCharacter->requestPause(avatar_pause_handles); + } +} + // //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index ac3d6d1f2..054f1c2f9 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -52,6 +52,8 @@ //----------------------------------------------------------------------------- class LLCharacter; class LLMotionController; +class LLPauseRequestHandle; +typedef LLPointer LLAnimPauseRequest; //----------------------------------------------------------------------------- // LLMotionRegistry @@ -160,6 +162,10 @@ public: void pauseAllMotions(); void unpauseAllMotions(); BOOL isPaused() const { return mPaused; } + // + void requestPause(std::vector& avatar_pause_handles); + void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); + // void setTimeStep(F32 step); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 4881139df..976397931 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6506,7 +6506,7 @@ void LLSelectMgr::updateSelectionCenter() mSelectionCenterGlobal.clearVec(); mShowSelection = FALSE; mSelectionBBox = LLBBox(); - mPauseRequest = NULL; + mPauseRequests.clear(); resetAgentHUDZoom(); } @@ -6516,27 +6516,18 @@ void LLSelectMgr::updateSelectionCenter() if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid()) { - // Singu Note: Chalice Yao's pause agent on attachment selection - if (object->permYouOwner()) + // Freeze avatars with a selected attachment, and all avatars with synchronized motions, if any. + LLVOAvatar* avatar = object->getAvatar(); + // It is possible that 'avatar' is NULL despite this being an attachment because of some race condition. + // In that case just don't freeze the avatar. + if (avatar) { - mPauseRequest = gAgentAvatarp->requestPause(); - } - else if (LLViewerObject* objectp = mSelectedObjects->getPrimaryObject()) - { - while (objectp && !objectp->isAvatar()) - { - objectp = (LLViewerObject*)objectp->getParent(); - } - - if (objectp) - { - mPauseRequest = objectp->asAvatar()->requestPause(); - } + avatar->pauseAllSyncedCharacters(mPauseRequests); } } else { - mPauseRequest = NULL; + mPauseRequests.clear(); } if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 16c960ba8..145c25005 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -793,7 +793,7 @@ private: LLFrameTimer mEffectsTimer; BOOL mForceSelection; - LLAnimPauseRequest mPauseRequest; + std::vector mPauseRequests; // Selected avatar and all synchronized avatars. friend class LLObjectBackup; };