diff options
-rwxr-xr-x | indra/newview/llagentwearables.cpp | 27 | ||||
-rwxr-xr-x | indra/newview/llappearancemgr.cpp | 35 | ||||
-rwxr-xr-x | indra/newview/llappearancemgr.h | 9 | ||||
-rwxr-xr-x | indra/newview/llviewerobject.cpp | 7 | ||||
-rwxr-xr-x | indra/newview/llviewerobject.h | 2 | ||||
-rwxr-xr-x | indra/newview/llvoavatar.cpp | 22 | ||||
-rwxr-xr-x | indra/newview/llvoavatar.h | 2 |
7 files changed, 95 insertions, 9 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 1edbbe2a2e..fa810aac76 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1538,7 +1538,11 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj std::set<LLUUID> requested_item_ids; std::set<LLUUID> current_item_ids; for (S32 i=0; i<obj_item_array.count(); i++) - requested_item_ids.insert(obj_item_array[i].get()->getLinkedUUID()); + { + const LLUUID & requested_id = obj_item_array[i].get()->getLinkedUUID(); + //llinfos << "Requested attachment id " << requested_id << llendl; + requested_item_ids.insert(requested_id); + } // Build up list of objects to be removed and items currently attached. llvo_vec_t objects_to_remove; @@ -1555,17 +1559,28 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj if (objectp) { LLUUID object_item_id = objectp->getAttachmentItemID(); + + bool remove_attachment = true; if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) - { - // Object currently worn, was requested. + { // Object currently worn, was requested to keep it // Flag as currently worn so we won't have to add it again. - current_item_ids.insert(object_item_id); + remove_attachment = false; } - else + else if (objectp->isTempAttachment()) + { // Check if we should keep this temp attachment + remove_attachment = LLAppearanceMgr::instance().shouldRemoveTempAttachment(objectp->getID()); + } + + if (remove_attachment) { - // object currently worn, not requested. + // llinfos << "found object to remove, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl; objects_to_remove.push_back(objectp); } + else + { + // llinfos << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl; + current_item_ids.insert(object_item_id); + } } } } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index fd9236c8b3..da1609297e 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3415,21 +3415,50 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) llwarns << "called with empty list, nothing to do" << llendl; } for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) - { + { const LLUUID& id_to_remove = *it; const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove); removeCOFItemLinks(linked_item_id); - } - updateAppearanceFromCOF(); + addDoomedTempAttachment(linked_item_id); } + updateAppearanceFromCOF(); +} void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) { LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); removeCOFItemLinks(linked_item_id); + addDoomedTempAttachment(linked_item_id); updateAppearanceFromCOF(); } + +// Adds the given item ID to mDoomedTempAttachmentIDs iff it's a temp attachment +void LLAppearanceMgr::addDoomedTempAttachment(const LLUUID& id_to_remove) +{ + LLViewerObject * attachmentp = gAgentAvatarp->findAttachmentByID(id_to_remove); + if (attachmentp && + attachmentp->isTempAttachment()) + { // If this is a temp attachment and we want to remove it, record the ID + // so it will be deleted when attachments are synced up with COF + mDoomedTempAttachmentIDs.insert(id_to_remove); + //llinfos << "Will remove temp attachment id " << id_to_remove << llendl; + } +} + +// Find AND REMOVES the given UUID from mDoomedTempAttachmentIDs +bool LLAppearanceMgr::shouldRemoveTempAttachment(const LLUUID& item_id) +{ + doomed_temp_attachments_t::iterator iter = mDoomedTempAttachmentIDs.find(item_id); + if (iter != mDoomedTempAttachmentIDs.end()) + { + mDoomedTempAttachmentIDs.erase(iter); + return true; + } + return false; +} + + bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body) { if (!item || !item->isWearableType()) return false; diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 46252afbde..5ec80f1cf0 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -142,6 +142,9 @@ public: void removeAllClothesFromAvatar(); void removeAllAttachmentsFromAvatar(); + // Special handling of temp attachments, which are not in the COF + bool shouldRemoveTempAttachment(const LLUUID& item_id); + //has the current outfit changed since it was loaded? bool isOutfitDirty() { return mOutfitIsDirty; } @@ -239,6 +242,12 @@ private: std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; + // Set of temp attachment UUIDs that should be removed + typedef std::set<LLUUID> doomed_temp_attachments_t; + doomed_temp_attachments_t mDoomedTempAttachmentIDs; + + void addDoomedTempAttachment(const LLUUID& id_to_remove); + ////////////////////////////////////////////////////////////////////////////////// // Item-specific convenience functions public: diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 7151a0d6ed..1544e66431 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5879,6 +5879,13 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif return ; } +// virtual +BOOL LLViewerObject::isTempAttachment() const +{ + return (mID.notNull() && (mID == mAttachmentItemID)); +} + + const LLUUID &LLViewerObject::getAttachmentItemID() const { return mAttachmentItemID; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index b035473c74..80bdd628a1 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -171,6 +171,8 @@ public: virtual BOOL isAttachment() const { return FALSE; } virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment virtual BOOL isHUDAttachment() const { return FALSE; } + virtual BOOL isTempAttachment() const; + virtual void updateRadius() {}; virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius() diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f92fa0371e..f5918a0a5f 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5975,6 +5975,28 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const +LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) const +{ + for(attachment_map_t::const_iterator attachment_points_iter = mAttachmentPoints.begin(); + attachment_points_iter != gAgentAvatarp->mAttachmentPoints.end(); + ++attachment_points_iter) + { + LLViewerJointAttachment* attachment = attachment_points_iter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *attached_object = (*attachment_iter); + if (attached_object && + attached_object->getID() == target_id) + { + return attached_object; + } + } + } + + return NULL; +} // virtual diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 931e65b3ea..9d45a74ecc 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -731,6 +731,8 @@ public: void cleanupAttachedMesh( LLViewerObject* pVO ); static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const; + LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const; + protected: LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object); void lazyAttach(); |