diff --git a/indra/newview/fsposestate.cpp b/indra/newview/fsposestate.cpp index 753e33bfa2..8f062895da 100644 --- a/indra/newview/fsposestate.cpp +++ b/indra/newview/fsposestate.cpp @@ -18,10 +18,11 @@ void FSPoseState::captureMotionStates(LLVOAvatar* avatar) continue; fsMotionState newState; - newState.avatarId = avatar->getID(); - newState.motionId = anim_it->first; + newState.avatarId = avatar->getID(); + newState.motionId = anim_it->first; newState.lastUpdateTime = motion->getLastUpdateTime(); newState.captureOrder = 0; + newState.avatarOwnsPose = canSaveMotionId(avatar, anim_it->first); sMotionStates[avatar->getID()].push_back(newState); } @@ -78,6 +79,7 @@ void FSPoseState::updateMotionStates(LLVOAvatar* avatar, FSPosingMotion* posingM newState.lastUpdateTime = motion->getLastUpdateTime(); newState.jointNamesAnimated = jointNamesRecaptured; newState.captureOrder = sCaptureOrder[avatar->getID()]; + newState.avatarOwnsPose = canSaveMotionId(avatar, anim_it->first); sMotionStates[avatar->getID()].push_back(newState); } @@ -108,6 +110,8 @@ void FSPoseState::writeMotionStates(LLVOAvatar* avatar, LLSD* saveRecord) { if (it->avatarId != avatar->getID()) continue; + if (!it->avatarOwnsPose) + continue; std::string uniqueAnimId = "poseState" + std::to_string(animNumber++); (*saveRecord)[uniqueAnimId]["animationId"] = it->motionId.asString(); @@ -181,12 +185,6 @@ bool FSPoseState::applyMotionStatesToPosingMotion(LLVOAvatar* avatar, FSPosingMo if (it->motionApplied) continue; - if (!avatarCanUsePose(avatar, it->motionId)) - { - it->motionApplied = true; - continue; - } - LLKeyframeMotion* kfm = dynamic_cast(avatar->findMotion(it->motionId)); if (kfm) @@ -194,7 +192,6 @@ bool FSPoseState::applyMotionStatesToPosingMotion(LLVOAvatar* avatar, FSPosingMo if (needPriorityReset) { lastCaptureOrder = it->captureOrder; - LL_WARNS("Posing") << "Resetting priority at cap order: " << lastCaptureOrder << LL_ENDL; resetPriorityForCaptureOrder(avatar, posingMotion, lastCaptureOrder); } @@ -225,25 +222,37 @@ void FSPoseState::resetPriorityForCaptureOrder(LLVOAvatar* avatar, FSPosingMotio if (it->captureOrder != captureOrder) continue; - LL_WARNS("Posing") << "Resetting priority for: " << it->jointNamesAnimated << LL_ENDL; posingMotion->resetBonePriority(it->jointNamesAnimated); } } -bool FSPoseState::avatarCanUsePose(LLVOAvatar* avatar, LLUUID motionId) +bool FSPoseState::canSaveMotionId(LLVOAvatar* avatar, LLAssetID motionId) { - if (!avatar) - return true; - - if (!motionId.notNull()) - return true; - - if (avatar != gAgentAvatarp) - return true; + if (!gAgentAvatarp || gAgentAvatarp.isNull()) + return false; + // does the animation exist in inventory LLInventoryItem* item = gInventory.getItem(motionId); - if (!item) + if (item && item->getPermissions().getOwner() == avatar->getID()) return true; - return item->getPermissions().getOwner() == avatar->getID(); + for (const auto& [anim_object_id, anim_anim_id] : gAgentAvatarp->mAnimationSources) + { + if (anim_anim_id != motionId) + continue; + + // is the item that started the anim in inventory + item = gInventory.getItem(anim_object_id); + if (item && item->getPermissions().getOwner() == avatar->getID()) + return true; + + // is the item that start the animation in-world + LLViewerObject* object = gObjectList.findObject(anim_object_id); + if (object && object->permYouOwner()) + return true; + + return false; + } + + return false; } diff --git a/indra/newview/fsposestate.h b/indra/newview/fsposestate.h index b992fb11cc..233258565c 100644 --- a/indra/newview/fsposestate.h +++ b/indra/newview/fsposestate.h @@ -91,8 +91,6 @@ public: /// bool applyMotionStatesToPosingMotion(LLVOAvatar* avatar, FSPosingMotion* posingMotion); - void resetPriorityForCaptureOrder(LLVOAvatar* avatar, FSPosingMotion* posingMotion, int captureOrder); - private: /// /// A class documenting the state of an animation for an avatar. @@ -120,9 +118,14 @@ private: /// bool motionApplied = false; + /// + /// Whether the avatar owns the pose, or the pose was loaded. + /// + bool avatarOwnsPose = false; + /// /// When reloading, larger numbers are loaded last, nesting order and priority. - /// Represents recaptures. + /// This is used to represent recaptures, where joints could be animated with different poses. /// int captureOrder = 0; @@ -133,12 +136,20 @@ private: }; /// - /// Gets whether the supplied avatar has ownership of the supplied motion id. + /// Resets the priority for the named joints for the supplied posing motion at the supplied capture order. /// - /// The avatar to query for ownership. - /// The motion to query for ownership. - /// True if the avatar has ownership of the motion, otherwise false. - bool avatarCanUsePose(LLVOAvatar* avatar, LLUUID motionId); + /// The avatar being posed by the motion. + /// The posing motion. + /// The order of the capture. + void resetPriorityForCaptureOrder(LLVOAvatar* avatar, FSPosingMotion* posingMotion, int captureOrder); + + /// + /// Gets whether the supplied avatar owns, and thus can save information about the supplied asset ID. + /// + /// The avatar to query ownership for. + /// The asset ID of the object. + /// True if the avatar owns the asset, otherwise false. + bool canSaveMotionId(LLVOAvatar* avatar, LLAssetID motionId); struct compareByCaptureOrder { @@ -152,7 +163,7 @@ private: }; static std::map > sMotionStates; - static std::map sCaptureOrder; + static std::map sCaptureOrder; }; #endif // LL_FSPoseState_H