Syncing latest appearance work from avatar pipeline into viewer2.0.

Result of: (NO CONFLICTS)
svn merge -r 134301:134742 svn+ssh://svn.lindenlab.com/svn/linden/branches/avatar-pipeline/currently-worn-folder-9 .
meow-7.2.2
Eric Tulla 2009-09-29 23:09:41 +00:00
parent 7dbf4d526a
commit 6d887be589
3 changed files with 119 additions and 28 deletions

View File

@ -1684,6 +1684,107 @@ void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed)
}
}
// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
// get attachments into desired state with minimal number of adds/removes.
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
{
// Possible cases:
// already wearing but not in request set -> take off.
// already wearing and in request set -> leave alone.
// not wearing and in request set -> put on.
LLVOAvatar* avatarp = gAgent.getAvatarObject();
if (!avatarp)
{
llwarns << "No avatar found." << llendl;
return;
}
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());
// Build up list of objects to be removed and items currently attached.
llvo_vec_t objects_to_remove;
for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
iter != avatarp->mAttachmentPoints.end();)
{
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
LLViewerJointAttachment* attachment = curiter->second;
LLViewerObject* objectp = attachment->getObject();
if (objectp)
{
LLUUID object_item_id = attachment->getItemID();
if (requested_item_ids.find(object_item_id) != requested_item_ids.end())
{
// Object currently worn, was requested.
// Flag as currently worn so we won't have to add it again.
current_item_ids.insert(object_item_id);
}
else
{
// object currently worn, not requested.
objects_to_remove.push_back(objectp);
}
}
}
LLInventoryModel::item_array_t items_to_add;
for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin();
it != obj_item_array.end();
++it)
{
LLUUID linked_id = (*it).get()->getLinkedUUID();
if (current_item_ids.find(linked_id) != current_item_ids.end())
{
// Requested attachment is already worn.
}
else
{
// Requested attachment is not worn yet.
items_to_add.push_back(*it);
}
}
// S32 remove_count = objects_to_remove.size();
// S32 add_count = items_to_add.size();
// llinfos << "remove " << remove_count << " add " << add_count << llendl;
// Remove everything in objects_to_remove
userRemoveMultipleAttachments(objects_to_remove);
// Add everything in items_to_add
userAttachMultipleAttachments(items_to_add);
}
void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)
{
LLVOAvatar* avatarp = gAgent.getAvatarObject();
if (!avatarp)
{
llwarns << "No avatar found." << llendl;
return;
}
if (objects_to_remove.empty())
return;
gMessageSystem->newMessage("ObjectDetach");
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
for (llvo_vec_t::iterator it = objects_to_remove.begin();
it != objects_to_remove.end();
++it)
{
LLViewerObject *objectp = *it;
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
}
gMessageSystem->sendReliable(gAgent.getRegionHost());
}
void LLAgentWearables::userRemoveAllAttachments()
{
LLVOAvatar* avatarp = gAgent.getAvatarObject();
@ -1693,11 +1794,8 @@ void LLAgentWearables::userRemoveAllAttachments()
return;
}
gMessageSystem->newMessage("ObjectDetach");
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
llvo_vec_t objects_to_remove;
for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
iter != avatarp->mAttachmentPoints.end();)
{
@ -1705,12 +1803,9 @@ void LLAgentWearables::userRemoveAllAttachments()
LLViewerJointAttachment* attachment = curiter->second;
LLViewerObject* objectp = attachment->getObject();
if (objectp)
{
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
}
objects_to_remove.push_back(objectp);
}
gMessageSystem->sendReliable(gAgent.getRegionHost());
userRemoveMultipleAttachments(objects_to_remove);
}
void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array)

View File

@ -44,6 +44,7 @@ class LLInventoryItem;
class LLVOAvatarSelf;
class LLWearable;
class LLInitialWearablesFetch;
class LLViewerObject;
class LLAgentWearables
{
@ -181,6 +182,11 @@ public:
// MULTI-WEARABLE: assuming one wearable per type. Need upstream changes.
static void userRemoveWearable(void* userdata); // userdata is EWearableType
static void userRemoveAllClothes(void* userdata); // userdata is NULL
typedef std::vector<LLViewerObject*> llvo_vec_t;
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userRemoveAllAttachments();
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);

View File

@ -416,11 +416,11 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory
if (!append && total_links > 0)
{
// Remove all current outfit folder links since we're now replacing the contents.
for (S32 i = 0; i < cof_items.count(); ++i)
{
gInventory.purgeObject(cof_items.get(i)->getUUID());
}
gInventory.notifyObservers();
}
LLPointer<LLUpdateAppearanceOnDestroy> link_waiter = new LLUpdateAppearanceOnDestroy;
@ -532,19 +532,19 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory
const LLUUID &current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
// Processes that take time should show the busy cursor
//inc_busy_count();
LLInventoryModel::cat_array_t cof_cats;
LLInventoryModel::item_array_t cof_items;
gInventory.collectDescendents(current_outfit_id, cof_cats, cof_items,
LLInventoryModel::EXCLUDE_TRASH);
if (items.count() > 0)
{
// Remove all current outfit folder links since we're now replacing the contents.
for (S32 i = 0; i < cof_items.count(); ++i)
{
gInventory.purgeObject(cof_items.get(i)->getUUID());
}
gInventory.notifyObservers();
}
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
@ -696,21 +696,11 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
}
}
//If the folder doesn't contain only gestures, take off all attachments.
if (!(wear_items.count() == 0 && obj_items.count() == 0 && gest_items.count() > 0) )
// Update attachments to match those requested.
LLVOAvatar* avatar = gAgent.getAvatarObject();
if( avatar )
{
LLAgentWearables::userRemoveAllAttachments();
}
if( obj_items.count() > 0 )
{
// We've found some attachments. Add these.
LLVOAvatar* avatar = gAgent.getAvatarObject();
if( avatar )
{
LLAgentWearables::userAttachMultipleAttachments(obj_items);
}
LLAgentWearables::userUpdateAttachments(obj_items);
}
}