diff options
-rw-r--r-- | indra/llxml/llxmlnode.h | 1 | ||||
-rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/newview/llagent.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llagentwearables.cpp | 416 | ||||
-rw-r--r-- | indra/newview/llagentwearables.h | 36 | ||||
-rw-r--r-- | indra/newview/lldynamictexture.h | 1 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 14 | ||||
-rw-r--r-- | indra/newview/lltexlayer.cpp | 10 | ||||
-rw-r--r-- | indra/newview/lltexlayer.h | 2 | ||||
-rw-r--r-- | indra/newview/llviewermenu.cpp | 22 | ||||
-rw-r--r-- | indra/newview/llvoavatarself.cpp | 187 | ||||
-rw-r--r-- | indra/newview/llvoavatarself.h | 18 | ||||
-rw-r--r-- | indra/newview/llwearable.cpp | 81 | ||||
-rw-r--r-- | indra/newview/llwearable.h | 13 |
14 files changed, 440 insertions, 365 deletions
diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index c983a14410..cc9e5cb351 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -48,6 +48,7 @@ #include "llthread.h" // LLThreadSafeRefCount #include "llstring.h" #include "llstringtable.h" +#include "llfile.h" class LLVector3; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1fddf7043d..8becd814e7 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -246,6 +246,7 @@ set(viewer_SOURCE_FILES lllandmarklist.cpp lllistbrowser.cpp lllistview.cpp + lllocaltextureobject.cpp lllocationhistory.cpp lllocationinputctrl.cpp lllogchat.cpp @@ -670,6 +671,7 @@ set(viewer_HEADER_FILES lllightconstants.h lllistbrowser.h lllistview.h + lllocaltextureobject.h lllocationhistory.h lllocationinputctrl.h lllogchat.h diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index c8240de0a7..15fc59e318 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -6450,7 +6450,7 @@ void LLAgent::sendAgentSetAppearance() const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,0); if (wearable) { - hash ^= wearable->getID(); + hash ^= wearable->getAssetID(); } } if (hash.notNull()) diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index f053bfe118..22875cbca2 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -44,6 +44,9 @@ #include "llwearable.h" #include "llwearablelist.h" +#include <boost/scoped_ptr.hpp> + + LLAgentWearables gAgentWearables; BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE; @@ -59,22 +62,23 @@ void LLAgentWearables::dump() llinfos << "Type: " << i << " count " << count << llendl; for (U32 j=0; j<count; j++) { - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,j); - if (wearable_entry == NULL) - { - llinfos << " " << j << " NULL entry" << llendl; - continue; - } - if (wearable_entry->mWearable == NULL) + LLWearable* wearable = getWearable((EWearableType)i,j); + if (wearable == NULL) { llinfos << " " << j << " NULL wearable" << llendl; - continue; } - llinfos << " " << j << " Name " << wearable_entry->mWearable->getName() - << " description " << wearable_entry->mWearable->getDescription() << llendl; + llinfos << " " << j << " Name " << wearable->getName() + << " description " << wearable->getDescription() << llendl; } } + llinfos << "Total items awaiting wearable update " << mItemsAwaitingWearableUpdate.size() << llendl; + for (std::set<LLUUID>::iterator it = mItemsAwaitingWearableUpdate.begin(); + it != mItemsAwaitingWearableUpdate.end(); + ++it) + { + llinfos << (*it).asString() << llendl; + } } // MULTI-WEARABLE: debugging @@ -105,7 +109,7 @@ LLAgentWearables::LLAgentWearables() : // MULTI-WEARABLE: TODO remove null entries. for (U32 i = 0; i < WT_COUNT; i++) { - mWearableDatas[(EWearableType)i].push_back(new LLWearableInv); + mWearableDatas[(EWearableType)i].push_back(NULL); } } @@ -116,18 +120,6 @@ LLAgentWearables::~LLAgentWearables() void LLAgentWearables::cleanup() { - for (wearableentry_map_t::iterator iter = mWearableDatas.begin(); - iter != mWearableDatas.end(); - iter++) - { - wearableentry_vec_t &wearables = iter->second; - for (U32 i = 0; i < wearables.size(); i++) - { - LLWearableInv *wearable = wearables[i]; - delete wearable; - wearables[i] = NULL; - } - } mAvatarObject = NULL; } @@ -207,11 +199,13 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, if (item_id.isNull()) return; - LLWearableInv* wearable_entry = getWearableInv((EWearableType)type, index); + LLUUID old_item_id = getWearableItemID((EWearableType)type,index); + if (wearable) + { + wearable->setItemID(item_id); + } + setWearable((EWearableType)type,index,wearable); - LLUUID old_item_id = wearable_entry->mItemID; - wearable_entry->mItemID = item_id; - wearable_entry->mWearable = wearable; if (old_item_id.notNull()) gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); @@ -221,7 +215,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, // We're changing the asset id, so we both need to set it // locally via setAssetUUID() and via setTransactionID() which // will be decoded on the server. JC - item->setAssetUUID(wearable->getID()); + item->setAssetUUID(wearable->getAssetID()); item->setTransactionID(wearable->getTransactionID()); gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id); item->updateServer(FALSE); @@ -237,11 +231,10 @@ void LLAgentWearables::sendAgentWearablesUpdate() { for (U32 j=0; j < getWearableCount((EWearableType)i); j++) { - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,j); - LLWearable* wearable = wearable_entry->mWearable; + LLWearable* wearable = getWearable((EWearableType)i,j); if (wearable) { - if (wearable_entry->mItemID.isNull()) + if (wearable->getItemID().isNull()) { LLPointer<LLInventoryCallback> cb = new addWearableToAgentInventoryCallback( @@ -255,7 +248,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() else { gInventory.addChangedMask(LLInventoryObserver::LABEL, - wearable_entry->mItemID); + wearable->getItemID()); } } } @@ -281,12 +274,11 @@ void LLAgentWearables::sendAgentWearablesUpdate() gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8); // MULTI-WEARABLE: TODO: hacked index to 0, needs to loop over all once messages support this. - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i, 0); - LLWearable* wearable = wearable_entry->mWearable; + LLWearable* wearable = getWearable((EWearableType)i, 0); if (wearable) { //llinfos << "Sending wearable " << wearable->getName() << llendl; - gMessageSystem->addUUIDFast(_PREHASH_ItemID, wearable_entry->mItemID); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, wearable->getItemID()); } else { @@ -294,7 +286,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null); } - lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getID() : LLUUID::null) << llendl; + lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl; } gAgent.sendReliableMessage(); } @@ -302,14 +294,15 @@ void LLAgentWearables::sendAgentWearablesUpdate() // MULTI-WEARABLE: add index. void LLAgentWearables::saveWearable(const EWearableType type, const U32 index, BOOL send_update) { - LLWearableInv* wearable_entry = getWearableInv(type, index); - LLWearable* old_wearable = wearable_entry ? wearable_entry->mWearable : NULL; + LLWearable* old_wearable = getWearable(type, index); if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion())) { + LLUUID old_item_id = old_wearable->getItemID(); LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar(old_wearable); - wearable_entry->mWearable = new_wearable; + new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()? + setWearable(type,index,new_wearable); - LLInventoryItem* item = gInventory.getItem(wearable_entry->mItemID); + LLInventoryItem* item = gInventory.getItem(old_item_id); if (item) { // Update existing inventory item @@ -317,7 +310,7 @@ void LLAgentWearables::saveWearable(const EWearableType type, const U32 index, B new LLViewerInventoryItem(item->getUUID(), item->getParentUUID(), item->getPermissions(), - new_wearable->getID(), + new_wearable->getAssetID(), new_wearable->getAssetType(), item->getInventoryType(), item->getName(), @@ -368,15 +361,14 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, llwarns << "LLAgent::saveWearableAs() not copyable." << llendl; return; } - LLWearableInv* wearable_entry = getWearableInv(type, index); - LLWearable* old_wearable = wearable_entry->mWearable; + LLWearable* old_wearable = getWearable(type, index); if (!old_wearable) { llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl; return; } - LLInventoryItem* item = gInventory.getItem(wearable_entry->mItemID); + LLInventoryItem* item = gInventory.getItem(getWearableItemID(type,index)); if (!item) { llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl; @@ -417,8 +409,7 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, void LLAgentWearables::revertWearable(const EWearableType type, const U32 index) { - LLWearableInv* wearable_entry = getWearableInv(type, index); - LLWearable* wearable = wearable_entry->mWearable; + LLWearable* wearable = getWearable(type, index); if (wearable) { wearable->writeToAvatar(TRUE); @@ -448,15 +439,16 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& { for (U32 j=0; j < getWearableCount((EWearableType)i); j++) { - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,j); - if (wearable_entry->mItemID == item_id) + LLUUID curr_item_id = getWearableItemID((EWearableType)i,j); + if (curr_item_id == item_id) { - LLWearable* old_wearable = wearable_entry->mWearable; + LLWearable* old_wearable = getWearable((EWearableType)i,j); llassert(old_wearable); std::string old_name = old_wearable->getName(); old_wearable->setName(new_name); LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); + new_wearable->setItemID(item_id); LLInventoryItem* item = gInventory.getItem(item_id); if (item) { @@ -464,7 +456,7 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& } old_wearable->setName(old_name); - wearable_entry->mWearable = new_wearable; + setWearable((EWearableType)i,j,new_wearable); sendAgentWearablesUpdate(); break; } @@ -475,7 +467,7 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& BOOL LLAgentWearables::isWearableModifiable(EWearableType type, U32 index) const { - LLUUID item_id = getWearableItem(type, index); + LLUUID item_id = getWearableItemID(type, index); if (!item_id.isNull()) { LLInventoryItem* item = gInventory.getItem(item_id); @@ -490,7 +482,7 @@ BOOL LLAgentWearables::isWearableModifiable(EWearableType type, U32 index) const BOOL LLAgentWearables::isWearableCopyable(EWearableType type, U32 index) const { - LLUUID item_id = getWearableItem(type, index); + LLUUID item_id = getWearableItemID(type, index); if (!item_id.isNull()) { LLInventoryItem* item = gInventory.getItem(item_id); @@ -506,7 +498,7 @@ BOOL LLAgentWearables::isWearableCopyable(EWearableType type, U32 index) const /* U32 LLAgentWearables::getWearablePermMask(EWearableType type) { - LLUUID item_id = getWearableItem(type); + LLUUID item_id = getWearableItemID(type); if (!item_id.isNull()) { LLInventoryItem* item = gInventory.getItem(item_id); @@ -521,7 +513,7 @@ BOOL LLAgentWearables::isWearableCopyable(EWearableType type, U32 index) const LLInventoryItem* LLAgentWearables::getWearableInventoryItem(EWearableType type, U32 index) { - LLUUID item_id = getWearableItem(type,index); + LLUUID item_id = getWearableItemID(type,index); LLInventoryItem* item = NULL; if (item_id.notNull()) { @@ -530,16 +522,16 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(EWearableType type, return item; } -LLWearable* LLAgentWearables::getWearableFromWearableItem(const LLUUID& item_id) const +const LLWearable* LLAgentWearables::getWearableFromWearableItem(const LLUUID& item_id) const { for (S32 i=0; i < WT_COUNT; i++) { for (U32 j=0; j < getWearableCount((EWearableType)i); j++) { - const LLWearableInv* wearable_entry = getWearableInv((EWearableType)i, j); - if (wearable_entry->mItemID == item_id) + LLUUID curr_item_id = getWearableItemID((EWearableType)i, j); + if (curr_item_id == item_id) { - return wearable_entry->mWearable; + return getWearable((EWearableType)i, j); } } } @@ -558,47 +550,57 @@ void LLAgentWearables::sendAgentWearablesRequest() // MULTI-WEARABLE: update for multiple items per type. // Used to enable/disable menu items. // static -BOOL LLAgentWearables::selfHasWearable(void* userdata) +BOOL LLAgentWearables::selfHasWearable(EWearableType type) { - EWearableType type = (EWearableType)(intptr_t)userdata; // MULTI-WEARABLE: TODO could be getWearableCount > 0, once null entries have been eliminated. - return gAgentWearables.getWearableInv(type,0)->mWearable != NULL; + return gAgentWearables.getWearable(type,0) != NULL; } -const LLAgentWearables::LLWearableInv LLAgentWearables::s_null_wearable; - LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) { - LLWearableInv* inv = getWearableInv(type,index); - return inv->mWearable; -} - -const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const -{ - const LLWearableInv* inv = getWearableInv(type,index); - return inv->mWearable; + wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); + if (wearable_iter == mWearableDatas.end()) + { + return NULL; + } + wearableentry_vec_t& wearable_vec = wearable_iter->second; + if (index>=wearable_vec.size()) + { + return NULL; + } + else + { + return wearable_vec[index]; + } } -//MULTI-WEARABLE: this will give wrong values until we get rid of the "always one empty object" scheme. -U32 LLAgentWearables::getWearableCount(const EWearableType type) const +void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable) { - wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); + wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); if (wearable_iter == mWearableDatas.end()) { - return 0; + llwarns << "invalid type, type " << type << " index " << index << llendl; + return; + } + wearableentry_vec_t& wearable_vec = wearable_iter->second; + if (index>=wearable_vec.size()) + { + llwarns << "invalid index, type " << type << " index " << index << llendl; + } + else + { + wearable_vec[index] = wearable; } - const wearableentry_vec_t& wearable_vec = wearable_iter->second; - return wearable_vec.size(); } - -LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearableType type, U32 index) + +const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const { - wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); + wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); if (wearable_iter == mWearableDatas.end()) { return NULL; } - wearableentry_vec_t& wearable_vec = wearable_iter->second; + const wearableentry_vec_t& wearable_vec = wearable_iter->second; if (index>=wearable_vec.size()) { return NULL; @@ -609,22 +611,36 @@ LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearabl } } -const LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearableType type, U32 index) const +//MULTI-WEARABLE: this will give wrong values until we get rid of the "always one empty object" scheme. +U32 LLAgentWearables::getWearableCount(const EWearableType type) const { wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) return &s_null_wearable; + if (wearable_iter == mWearableDatas.end()) + { + return 0; + } const wearableentry_vec_t& wearable_vec = wearable_iter->second; - if (index>=wearable_vec.size()) - return &s_null_wearable; - else - return wearable_vec[index]; + return wearable_vec.size(); } -const LLUUID& LLAgentWearables::getWearableItem(EWearableType type, U32 index) const +BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const { - return getWearableInv(type,index)->mItemID; + return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end(); } +U32 LLAgentWearables::itemUpdatePendingCount() const +{ + return mItemsAwaitingWearableUpdate.size(); +} + +const LLUUID LLAgentWearables::getWearableItemID(EWearableType type, U32 index) const +{ + const LLWearable *wearable = getWearable(type,index); + if (wearable) + return wearable->getItemID(); + else + return LLUUID(); +} // Warning: include_linked_items = TRUE makes this operation expensive. BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_items) const @@ -646,6 +662,13 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_ return FALSE; } +struct InitialWearableData +{ + S32 mType; + U32 mIndex; + LLUUID mItemID; +}; + // MULTI-WEARABLE: update for multiple // static void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data) @@ -676,7 +699,9 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs //lldebugs << "processAgentInitialWearablesUpdate()" << llendl; // Add wearables LLUUID asset_id_array[WT_COUNT]; + LLUUID item_id_array[WT_COUNT]; // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element. + gAgentWearables.mItemsAwaitingWearableUpdate.clear(); for (S32 i=0; i < num_wearables; i++) { U8 type_u8 = 0; @@ -703,9 +728,10 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs { continue; } - // MULTI-WEARABLE: TODO FIXME: assumes zeroth element always exists and can be safely written to. - LLWearableInv* wearable_entry = gAgentWearables.getWearableInv(type,0); - wearable_entry->mItemID = item_id; + + // MULTI-WEARABLE: extend arrays to index by type + index. + gAgentWearables.mItemsAwaitingWearableUpdate.insert(item_id); + item_id_array[type] = item_id; asset_id_array[type] = asset_id; } @@ -715,14 +741,18 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs // now that we have the asset ids...request the wearable assets for (S32 i = 0; i < WT_COUNT; i++) { - // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element. - LLWearableInv* wearable_entry = gAgentWearables.getWearableInv((EWearableType)i, 0); - if (!wearable_entry->mItemID.isNull()) + // MULTI-WEARABLE: TODO: update once messages change. + // Currently use results to populate the zeroth element. + if (!item_id_array[i].isNull()) { + InitialWearableData *wear_data = new InitialWearableData; + wear_data->mType = i; + wear_data->mIndex = 0; // MULTI-WEARABLE: update + wear_data->mItemID = item_id_array[i]; LLWearableList::instance().getAsset(asset_id_array[i], LLStringUtil::null, LLWearableDictionary::getAssetType((EWearableType) i), - onInitialWearableAssetArrived, (void*)(intptr_t)i); + onInitialWearableAssetArrived, (void*)wear_data); } } } @@ -732,7 +762,9 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs // static void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* userdata) { - const EWearableType type = (EWearableType)(intptr_t)userdata; + boost::scoped_ptr<InitialWearableData> wear_data((InitialWearableData*)userdata); + const EWearableType type = (EWearableType)wear_data->mType; + const U32 index = wear_data->mIndex; LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if (!avatar) @@ -743,44 +775,31 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* if (wearable) { llassert(type == wearable->getType()); - // MULTI-WEARABLE: is this always zeroth element? Change sometime. - LLWearableInv* wearable_entry = gAgentWearables.getWearableInv(type,0); - wearable_entry->mWearable = wearable; - + wearable->setItemID(wear_data->mItemID); + gAgentWearables.setWearable(type,index,wearable); + gAgentWearables.mItemsAwaitingWearableUpdate.erase(wear_data->mItemID); + // disable composites if initial textures are baked avatar->setupComposites(); - gAgentWearables.queryWearableCache(); wearable->writeToAvatar(FALSE); avatar->setCompositeUpdatesEnabled(TRUE); - gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable_entry->mItemID); + gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable->getItemID()); } else { // Somehow the asset doesn't exist in the database. // MULTI-WEARABLE: assuming zeroth elt - gAgentWearables.recoverMissingWearable(type,0); + gAgentWearables.recoverMissingWearable(type,index); } gInventory.notifyObservers(); // Have all the wearables that the avatar was wearing at log-in arrived? // MULTI-WEARABLE: update when multiple wearables can arrive per type. - if (!gAgentWearables.mWearablesLoaded) - { - gAgentWearables.mWearablesLoaded = TRUE; - for (S32 i = 0; i < WT_COUNT; i++) - { - LLWearableInv* wearable_entry = gAgentWearables.getWearableInv((EWearableType)i,0); - if (!wearable_entry->mItemID.isNull() && !wearable_entry->mWearable) - { - gAgentWearables.mWearablesLoaded = FALSE; - break; - } - } - } - if (gAgentWearables.mWearablesLoaded) + gAgentWearables.updateWearablesLoaded(); + if (gAgentWearables.areWearablesLoaded()) { // Can't query cache until all wearables have arrived, so calling this earlier is a no-op. @@ -809,8 +828,7 @@ void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 inde LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type); S32 type_s32 = (S32) type; - LLWearableInv* wearable_entry = getWearableInv(type, index); - wearable_entry->mWearable = new_wearable; + setWearable(type,index,new_wearable); new_wearable->writeToAvatar(TRUE); // Add a new one in the lost and found folder. @@ -831,19 +849,8 @@ void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 inde void LLAgentWearables::recoverMissingWearableDone() { // Have all the wearables that the avatar was wearing at log-in arrived or been fabricated? - mWearablesLoaded = TRUE; - for (S32 i = 0; i < WT_COUNT; i++) - { - // MULTI-WEARABLE: assuming zeroth elt - fix when messages change. - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,0); - if (!wearable_entry->mItemID.isNull() && !wearable_entry->mWearable) - { - mWearablesLoaded = FALSE; - break; - } - } - - if (mWearablesLoaded) + updateWearablesLoaded(); + if (areWearablesLoaded()) { // Make sure that the server's idea of the avatar's wearables actually match the wearables. gAgent.sendAgentSetAppearance(); @@ -855,6 +862,17 @@ void LLAgentWearables::recoverMissingWearableDone() } } +void LLAgentWearables::addLocalTextureObject(const EWearableType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index) +{ + LLWearable* wearable = getWearable((EWearableType)wearable_type, wearable_index); + if (!wearable) + { + llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl; + } + + wearable->setLocalTextureObject(texture_type, new LLLocalTextureObject()); +} + void LLAgentWearables::createStandardWearables(BOOL female) { llwarns << "Creating Standard " << (female ? "female" : "male") @@ -896,10 +914,9 @@ void LLAgentWearables::createStandardWearables(BOOL female) donecb = new createStandardWearablesAllDoneCallback; } // MULTI_WEARABLE: only elt 0, may be the right thing? - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i,0); - llassert(wearable_entry->mWearable == NULL); + llassert(getWearable((EWearableType)i,0) == NULL); LLWearable* wearable = LLWearableList::instance().createNewWearable((EWearableType)i); - wearable_entry->mWearable = wearable; + setWearable((EWearableType)i,0,wearable); // no need to update here... // MULTI_WEARABLE: hardwired index = 0 here. LLPointer<LLInventoryCallback> cb = @@ -929,6 +946,8 @@ void LLAgentWearables::createStandardWearablesAllDone() // ... because sendAgentWearablesUpdate will notify inventory // observers. mWearablesLoaded = TRUE; + checkWearablesLoaded(); + updateServer(); // Treat this as the first texture entry message, if none received yet @@ -968,8 +987,7 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, const S32 type = wearables_to_include[i]; for (U32 j=0; j<getWearableCount((EWearableType)i); j++) { - LLWearableInv* wearable_entry = getWearableInv((EWearableType)type, j); - LLWearable* old_wearable = wearable_entry->mWearable; + LLWearable* old_wearable = getWearable((EWearableType)type, j); if (old_wearable) { std::string new_name; @@ -984,7 +1002,7 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, new_wearable->setName(new_name); } - LLViewerInventoryItem* item = gInventory.getItem(wearable_entry->mItemID); + LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((EWearableType)type,j)); S32 todo = addWearableToAgentInventoryCallback::CALL_NONE; if (!found_first_item) { @@ -1071,8 +1089,7 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index) { - LLWearableInv* wearable_entry = getWearableInv((EWearableType)type, index); - LLUUID first_item_id = wearable_entry->mItemID; + LLUUID first_item_id = getWearableItemID((EWearableType)type, index); // Open the inventory and select the first item we added. if (first_item_id.notNull()) { @@ -1178,17 +1195,15 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem S32 max_entry = mWearableDatas[type].size()-1; for (S32 i=max_entry; i>=0; i--) { - LLWearableInv *wearable_entry = getWearableInv(type,i); - LLWearable* old_wearable = wearable_entry->mWearable; - gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable_entry->mItemID); - wearable_entry->mWearable = NULL; - wearable_entry->mItemID.setNull(); - //queryWearableCache(); // BAP moved below + LLWearable* old_wearable = getWearable(type,i); + gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,i)); + setWearable(type,i,NULL); + + //queryWearableCache(); // moved below // MULTI_WEARABLE: FIXME - currently we keep a null entry, so can't delete the last one. if (i>0) { mWearableDatas[type].pop_back(); - delete wearable_entry; } if (old_wearable) { @@ -1198,15 +1213,12 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem } else { - LLWearableInv* wearable_entry = getWearableInv(type, index); - LLWearable* old_wearable = wearable_entry->mWearable; + LLWearable* old_wearable = getWearable(type, index); - gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable_entry->mItemID); + gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,index)); + setWearable(type,index,NULL); - wearable_entry->mWearable = NULL; - wearable_entry->mItemID.setNull(); - - //queryWearableCache(); // BAP moved below + //queryWearableCache(); // moved below if (old_wearable) { @@ -1221,7 +1233,6 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem llassert_always(wearable_iter != mWearableDatas.end()); wearableentry_vec_t& wearable_vec = wearable_iter->second; wearable_vec.erase( wearable_vec.begin() + index ); - delete(wearable_entry); } } @@ -1268,12 +1279,11 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it wearables_to_remove[type] = FALSE; // MULTI_WEARABLE: using 0th - LLWearableInv* old_wearable_entry = getWearableInv(type, 0); - LLWearable* old_wearable = old_wearable_entry->mWearable; + LLWearable* old_wearable = getWearable(type, 0); if (old_wearable) { - const LLUUID& old_item_id = old_wearable_entry->mItemID; - if ((old_wearable->getID() == new_wearable->getID()) && + const LLUUID& old_item_id = getWearableItemID(type, 0); + if ((old_wearable->getAssetID() == new_wearable->getAssetID()) && (old_item_id == new_item->getUUID())) { lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl; @@ -1290,8 +1300,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } } - old_wearable_entry->mItemID = new_item->getUUID(); - old_wearable_entry->mWearable = new_wearable; + setWearable(type,0,new_wearable); + if (new_wearable) + new_wearable->setItemID(new_item->getUUID()); } std::vector<LLWearable*> wearables_being_removed; @@ -1301,12 +1312,13 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it if (wearables_to_remove[i]) { // MULTI_WEARABLE: assuming 0th - LLWearableInv* wearable_entry = getWearableInv((EWearableType)i, 0); - wearables_being_removed.push_back(wearable_entry->mWearable); - wearable_entry->mWearable = NULL; - - gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable_entry->mItemID); - wearable_entry->mItemID.setNull(); + LLWearable* wearable = getWearable((EWearableType)i, 0); + gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID((EWearableType)i,0)); + if (wearable) + { + wearables_being_removed.push_back(wearable); + } + setWearable((EWearableType)i,0,NULL); } } @@ -1334,6 +1346,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // Start rendering & update the server mWearablesLoaded = TRUE; + checkWearablesLoaded(); updateServer(); lldebugs << "setWearableOutfit() end" << llendl; @@ -1341,9 +1354,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // User has picked "wear on avatar" from a menu. -void LLAgentWearables::setWearable(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append) +void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append) { - //LLAgentDumper dumper("setWearable"); + //LLAgentDumper dumper("setWearableItem"); if (isWearingItem(new_item->getUUID())) { llwarns << "wearable " << new_item->getUUID() << " is already worn" << llendl; @@ -1356,12 +1369,11 @@ void LLAgentWearables::setWearable(LLInventoryItem* new_item, LLWearable* new_we { // Remove old wearable, if any // MULTI_WEARABLE: hardwired to 0 - LLWearableInv* old_wearable_entry = getWearableInv(type,0); - LLWearable* old_wearable = old_wearable_entry->mWearable; + LLWearable* old_wearable = getWearable(type,0); if (old_wearable) { - const LLUUID& old_item_id = old_wearable_entry->mItemID; - if ((old_wearable->getID() == new_wearable->getID()) && + const LLUUID& old_item_id = old_wearable->getItemID(); + if ((old_wearable->getAssetID() == new_wearable->getAssetID()) && (old_item_id == new_item->getUUID())) { lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl; @@ -1417,29 +1429,32 @@ bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& return false; } -// Called from setWearable() and onSetWearableDialog() to actually set the wearable. +// Called from setWearableItem() and onSetWearableDialog() to actually set the wearable. // MULTI_WEARABLE: unify code after null objects are gone. void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append) { const EWearableType type = new_wearable->getType(); - if (do_append && getWearableInv(type,0)->mItemID.notNull()) + if (do_append && getWearableItemID(type,0).notNull()) { - LLWearableInv *new_wearable_entry = new LLWearableInv; - new_wearable_entry->mItemID = new_item->getUUID(); - new_wearable_entry->mWearable = new_wearable; - mWearableDatas[type].push_back(new_wearable_entry); + new_wearable->setItemID(new_item->getUUID()); + mWearableDatas[type].push_back(new_wearable); llinfos << "Added additional wearable for type " << type << " size is now " << mWearableDatas[type].size() << llendl; } else { - LLWearableInv* wearable_entry = getWearableInv(type,0); // Replace the old wearable with a new one. - llassert(new_item->getAssetUUID() == new_wearable->getID()); - LLUUID old_item_id = wearable_entry->mItemID; - wearable_entry->mItemID = new_item->getUUID(); - wearable_entry->mWearable = new_wearable; + llassert(new_item->getAssetUUID() == new_wearable->getAssetID()); + + LLWearable *old_wearable = getWearable(type,0); + LLUUID old_item_id; + if (old_wearable) + { + old_item_id = old_wearable->getItemID(); + } + new_wearable->setItemID(new_item->getUUID()); + setWearable(type,0,new_wearable); if (old_item_id.notNull()) { @@ -1450,7 +1465,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n << " size is now " << mWearableDatas[type].size() << llendl; } - //llinfos << "LLVOAvatar::setWearable()" << llendl; + //llinfos << "LLVOAvatar::setWearableItem()" << llendl; queryWearableCache(); new_wearable->writeToAvatar(TRUE); @@ -1459,7 +1474,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n void LLAgentWearables::queryWearableCache() { - if (!mWearablesLoaded) + if (!areWearablesLoaded()) { return; } @@ -1489,10 +1504,10 @@ void LLAgentWearables::queryWearableCache() // EWearableType baked_type = gBakedWearableMap[baked_index][baked_num]; const EWearableType baked_type = baked_dict->mWearables[i]; // MULTI_WEARABLE: assuming 0th - const LLWearable* wearable = getWearableInv(baked_type,0)->mWearable; + const LLWearable* wearable = getWearable(baked_type,0); if (wearable) { - hash ^= wearable->getID(); + hash ^= wearable->getAssetID(); } } if (hash.notNull()) @@ -1592,6 +1607,29 @@ void LLAgentWearables::userRemoveAllAttachments(void* userdata) gMessageSystem->sendReliable(gAgent.getRegionHost()); } +void LLAgentWearables::checkWearablesLoaded() const +{ +#ifdef SHOW_ASSERT + U32 item_pend_count = itemUpdatePendingCount(); + if (mWearablesLoaded) + { + llassert(item_pend_count==0); + } +#endif +} + +BOOL LLAgentWearables::areWearablesLoaded() const +{ + checkWearablesLoaded(); + return mWearablesLoaded; +} + +// MULTI-WEARABLE: update for multiple indices. +void LLAgentWearables::updateWearablesLoaded() +{ + mWearablesLoaded = (itemUpdatePendingCount()==0); +} + void LLAgentWearables::updateServer() { sendAgentWearablesUpdate(); diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 31d6e30069..977efd71b4 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -66,32 +66,37 @@ public: BOOL isWearingItem(const LLUUID& item_id, const BOOL include_linked_items = FALSE) const; BOOL isWearableModifiable(EWearableType type, U32 index /*= 0*/) const; BOOL isWearableCopyable(EWearableType type, U32 index /*= 0*/) const; - BOOL areWearablesLoaded() const { return mWearablesLoaded; } + BOOL areWearablesLoaded() const; + void updateWearablesLoaded(); + void checkWearablesLoaded() const; + //-------------------------------------------------------------------- // Accessors //-------------------------------------------------------------------- public: - const LLUUID& getWearableItem(EWearableType type, U32 index /*= 0*/) const; - LLWearable* getWearableFromWearableItem(const LLUUID& item_id) const; + const LLUUID getWearableItemID(EWearableType type, U32 index /*= 0*/) const; + const LLWearable* getWearableFromWearableItem(const LLUUID& item_id) const; LLInventoryItem* getWearableInventoryItem(EWearableType type, U32 index /*= 0*/); // MULTI-WEARABLE: assuming one per type. - static BOOL selfHasWearable(void* userdata); // userdata is EWearableType + static BOOL selfHasWearable(EWearableType type); LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/); const LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/) const; U32 getWearableCount(const EWearableType type) const; + private: - struct LLWearableInv; - LLWearableInv* getWearableInv(const EWearableType type, U32 index /*= 0*/); - const LLWearableInv* getWearableInv(const EWearableType type, U32 /*index = 0*/) const; + // Low-level data structure setter - public access is via setWearableItem, etc. + void setWearable(const EWearableType type, U32 index, LLWearable *wearable); + //-------------------------------------------------------------------- // Setters //-------------------------------------------------------------------- public: - void setWearable(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false); + void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false); void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove); void setWearableName(const LLUUID& item_id, const std::string& new_name); + void addLocalTextureObject(const EWearableType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index); protected: void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false); static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable); @@ -160,16 +165,20 @@ public: static void userRemoveAllClothes(void* userdata); // userdata is NULL static void userRemoveAllAttachments(void* userdata); // userdata is NULL + BOOL itemUpdatePending(const LLUUID& item_id) const; + U32 itemUpdatePendingCount() const; + //-------------------------------------------------------------------- // Member variables //-------------------------------------------------------------------- private: - typedef std::vector<LLWearableInv*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts) + typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts) typedef std::map<EWearableType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type wearableentry_map_t mWearableDatas; static BOOL mInitialWearablesUpdateReceived; BOOL mWearablesLoaded; + std::set<LLUUID> mItemsAwaitingWearableUpdate; LLPointer<LLVOAvatarSelf> mAvatarObject; // NULL until avatar object sent down from simulator //-------------------------------------------------------------------------------- @@ -215,15 +224,6 @@ private: LLPointer<LLRefCount> mCB; }; - struct LLWearableInv // Make this subclass of llwearable? - { - LLWearableInv() : mItemID(LLUUID::null), mWearable(NULL) {} - // BOOL exists() const; - LLUUID mItemID; // ID of the inventory item in the agent's inventory. - LLWearable* mWearable; - }; - const static LLWearableInv s_null_wearable; - }; // LLAgentWearables extern LLAgentWearables gAgentWearables; diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index c5fc83f9bb..2a944eaada 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -37,6 +37,7 @@ #include "llgl.h" #include "llcoord.h" #include "llviewertexture.h" +#include "llcamera.h" class LLViewerDynamicTexture : public LLViewerTexture { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d4c40689ce..54d8208e9e 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4192,7 +4192,7 @@ void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data) iter != holder->mFoundList.end(); ++iter) { LLFoundData* data = *iter; - if(wearable->getID() == data->mAssetID) + if(wearable->getAssetID() == data->mAssetID) { data->mWearable = wearable; break; @@ -4225,7 +4225,7 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B { LLViewerInventoryItem* item; item = (LLViewerInventoryItem*)gInventory.getItem(data->mItemID); - if( item && (item->getAssetUUID() == wearable->getID()) ) + if( item && (item->getAssetUUID() == wearable->getAssetID()) ) { items.put(item); wearables.put(wearable); @@ -4629,9 +4629,9 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda item = (LLViewerInventoryItem*)gInventory.getItem(*item_id); if(item) { - if(item->getAssetUUID() == wearable->getID()) + if(item->getAssetUUID() == wearable->getAssetID()) { - gAgentWearables.setWearable(item, wearable); + gAgentWearables.setWearableItem(item, wearable); gInventory.notifyObservers(); //self->getFolderItem()->refreshFromRoot(); } @@ -4654,10 +4654,10 @@ void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* use item = (LLViewerInventoryItem*)gInventory.getItem(*item_id); if(item) { - if(item->getAssetUUID() == wearable->getID()) + if(item->getAssetUUID() == wearable->getAssetID()) { bool do_append = true; - gAgentWearables.setWearable(item, wearable, do_append); + gAgentWearables.setWearableItem(item, wearable, do_append); gInventory.notifyObservers(); //self->getFolderItem()->refreshFromRoot(); } @@ -4691,7 +4691,7 @@ void LLWearableBridge::onEditOnAvatar(void* user_data) void LLWearableBridge::editOnAvatar() { - LLWearable* wearable = gAgentWearables.getWearableFromWearableItem(mUUID); + const LLWearable* wearable = gAgentWearables.getWearableFromWearableItem(mUUID); if( wearable ) { // Set the tab to the right wearable. diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index a570a89b28..5a5f187415 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -1237,6 +1237,16 @@ LLTexLayer::LLTexLayer(LLTexLayerSet* layer_set) : { } +LLTexLayer::LLTexLayer(const LLTexLayer &layer) : + mTexLayerSet( layer.mTexLayerSet ) +{ + setInfo(layer.getInfo()); + + + mHasMorph = layer.mHasMorph; + +} + LLTexLayer::~LLTexLayer() { // mParamAlphaList and mParamColorList are LLViewerVisualParam's and get diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index c3ad07a218..b0ac13913e 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -53,6 +53,7 @@ class LLTexLayerParamColorInfo; class LLTexLayerParamAlpha; class LLTexLayerParamAlphaInfo; + typedef std::vector<LLTexLayerParamColor *> param_color_list_t; typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t; typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t; @@ -74,6 +75,7 @@ public: }; LLTexLayer(LLTexLayerSet* const layer_set); + LLTexLayer(const LLTexLayer &layer); ~LLTexLayer(); const LLTexLayerInfo* getInfo() const { return mInfo; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0bb1bd7857..63854abfea 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7393,47 +7393,47 @@ class LLEditEnableTakeOff : public view_listener_t bool new_value = false; if (clothing == "shirt") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_SHIRT); + new_value = LLAgentWearables::selfHasWearable(WT_SHIRT); } if (clothing == "pants") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_PANTS); + new_value = LLAgentWearables::selfHasWearable(WT_PANTS); } if (clothing == "shoes") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_SHOES); + new_value = LLAgentWearables::selfHasWearable(WT_SHOES); } if (clothing == "socks") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_SOCKS); + new_value = LLAgentWearables::selfHasWearable(WT_SOCKS); } if (clothing == "jacket") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_JACKET); + new_value = LLAgentWearables::selfHasWearable(WT_JACKET); } if (clothing == "gloves") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_GLOVES); + new_value = LLAgentWearables::selfHasWearable(WT_GLOVES); } if (clothing == "undershirt") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_UNDERSHIRT); + new_value = LLAgentWearables::selfHasWearable(WT_UNDERSHIRT); } if (clothing == "underpants") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_UNDERPANTS); + new_value = LLAgentWearables::selfHasWearable(WT_UNDERPANTS); } if (clothing == "skirt") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_SKIRT); + new_value = LLAgentWearables::selfHasWearable(WT_SKIRT); } if (clothing == "alpha") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_ALPHA); + new_value = LLAgentWearables::selfHasWearable(WT_ALPHA); } if (clothing == "tattoo") { - new_value = LLAgentWearables::selfHasWearable((void *)WT_TATTOO); + new_value = LLAgentWearables::selfHasWearable(WT_TATTOO); } return new_value; } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 4a80882c89..4a6bb6facb 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -156,11 +156,6 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id, gAgentWearables.setAvatarObject(this); lldebugs << "Marking avatar as self " << id << llendl; - - for (U32 i = 0; i < TEX_NUM_INDICES; i++) - { - mLocalTextureDatas[(ETextureIndex)i].push_back(new LocalTextureData); - } } void LLVOAvatarSelf::initInstance() @@ -536,19 +531,6 @@ LLVOAvatarSelf::~LLVOAvatarSelf() gAgentWearables.setAvatarObject(NULL); delete mScreenp; mScreenp = NULL; - - for (localtexture_map_t::iterator iter = mLocalTextureDatas.begin(); - iter != mLocalTextureDatas.end(); - iter++) - { - localtexture_vec_t &local_textures = iter->second; - for (U32 i = 0; i < local_textures.size(); i++) - { - LocalTextureData* loc_tex_data = local_textures[i]; - delete loc_tex_data; - local_textures[i] = NULL; - } - } } /** @@ -1008,6 +990,12 @@ LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_obj return attachment; } +U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const +{ + EWearableType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i); + return gAgentWearables.getWearableCount(type); +} + // virtual void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) { @@ -1015,17 +1003,17 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr const LLUUID& src_id = src_vi->getID(); LLAvatarTexData *data = (LLAvatarTexData *)userdata; + ETextureIndex index = data->mIndex; + if (!isIndexLocalTexture(index)) return; + LLLocalTextureObject *local_tex_obj = getLocalTextureObject(index, 0); if (success) { - ETextureIndex index = data->mIndex; - if (!isIndexLocalTexture(index)) return; - LocalTextureData *local_tex_data = getLocalTextureData(index,0); - if (!local_tex_data->mIsBakedReady && - local_tex_data->mImage.notNull() && - (local_tex_data->mImage->getID() == src_id) && - discard_level < local_tex_data->mDiscard) + if (!local_tex_obj->getBakedReady() && + local_tex_obj->getImage() != NULL && + (local_tex_obj->getID() == src_id) && + discard_level < local_tex_obj->getDiscard()) { - local_tex_data->mDiscard = discard_level; + local_tex_obj->setDiscard(discard_level); if (!gAgent.cameraCustomizeAvatar()) { requestLayerSetUpdate(index); @@ -1039,15 +1027,12 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr } else if (final) { - ETextureIndex index = data->mIndex; - if (!isIndexLocalTexture(index)) return; - LocalTextureData *local_tex_data = getLocalTextureData(index,0); // Failed: asset is missing - if (!local_tex_data->mIsBakedReady && - local_tex_data->mImage.notNull() && - local_tex_data->mImage->getID() == src_id) + if (!local_tex_obj->getBakedReady() && + local_tex_obj->getImage() != NULL && + local_tex_obj->getImage()->getID() == src_id) { - local_tex_data->mDiscard = 0; + local_tex_obj->setDiscard(0); requestLayerSetUpdate(index); updateMeshTextures(); } @@ -1082,12 +1067,12 @@ BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex if (!isIndexLocalTexture(type)) return FALSE; if (getLocalTextureID(type, index) == IMG_DEFAULT_AVATAR) return TRUE; - const LocalTextureData *local_tex_data = getLocalTextureData(type, index); - if (!local_tex_data) + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (!local_tex_obj) { return FALSE; } - *tex_pp = local_tex_data->mImage; + *tex_pp = local_tex_obj->getImage(); return TRUE; } @@ -1095,10 +1080,10 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c { if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR; - const LocalTextureData *local_tex_data = getLocalTextureData(type,index); - if (local_tex_data && local_tex_data->mImage.notNull()) + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (local_tex_obj && local_tex_obj->getImage() != NULL) { - return local_tex_data->mImage->getID(); + return local_tex_obj->getImage()->getID(); } return IMG_DEFAULT_AVATAR; } @@ -1288,14 +1273,14 @@ S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 index) const { if (!isIndexLocalTexture(type)) return FALSE; - const LocalTextureData *local_tex_data = getLocalTextureData(type,index); - if (local_tex_data) + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, index); + if (local_tex_obj) { if (type >= 0 && getLocalTextureID(type,index) != IMG_DEFAULT_AVATAR - && !local_tex_data->mImage->isMissingAsset()) + && !local_tex_obj->getImage()->isMissingAsset()) { - return local_tex_data->mImage->getDiscardLevel(); + return local_tex_obj->getImage()->getDiscardLevel(); } else { @@ -1314,13 +1299,13 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const for (S32 type = 0; type < TEX_NUM_INDICES; type++) { if (!isIndexLocalTexture((ETextureIndex)type)) continue; - const localtexture_vec_t & local_tex_vec = getLocalTextureData((ETextureIndex)type); - for (U32 num = 0; num < local_tex_vec.size(); num++) + U32 max_tex = getNumWearables((ETextureIndex) type); + for (U32 num = 0; num < max_tex; num++) { - const LocalTextureData *local_tex_data = local_tex_vec[num]; - if (local_tex_data) + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num); + if (local_tex_obj) { - const LLViewerFetchedTexture* image_gl = local_tex_data->mImage; + const LLViewerFetchedTexture* image_gl = local_tex_obj->getImage(); if (image_gl) { S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); @@ -1347,21 +1332,42 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te } S32 desired_discard = isSelf() ? 0 : 2; - LocalTextureData *local_tex_data = getLocalTextureData(type,index); + LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index); + if (!local_tex_obj) + { + if (type >= TEX_NUM_INDICES) + { + llerrs << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << llendl; + return; + } + EWearableType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(type); + if (!gAgentWearables.getWearable(wearable_type,0)) + { + // no wearable is loaded, cannot set the texture. + return; + } + gAgentWearables.addLocalTextureObject(wearable_type,type,index); + local_tex_obj = getLocalTextureObject(type,index); + if (!local_tex_obj) + { + llerrs << "Unable to create LocalTextureObject for wearable type & index: (" << (U32) wearable_type << ", " << index << ")" << llendl; + return; + } + } if (!baked_version_ready) { - if (tex != local_tex_data->mImage || local_tex_data->mIsBakedReady) + if (tex != local_tex_obj->getImage() || local_tex_obj->getBakedReady()) { - local_tex_data->mDiscard = MAX_DISCARD_LEVEL+1; + local_tex_obj->setDiscard(MAX_DISCARD_LEVEL+1); } if (tex->getID() != IMG_DEFAULT_AVATAR) { - if (local_tex_data->mDiscard > desired_discard) + if (local_tex_obj->getDiscard() > desired_discard) { S32 tex_discard = tex->getDiscardLevel(); if (tex_discard >= 0 && tex_discard <= desired_discard) { - local_tex_data->mDiscard = tex_discard; + local_tex_obj->setDiscard(tex_discard); if (isSelf() && !gAgent.cameraCustomizeAvatar()) { requestLayerSetUpdate(type); @@ -1379,8 +1385,8 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te tex->setMinDiscardLevel(desired_discard); } } - local_tex_data->mIsBakedReady = baked_version_ready; - local_tex_data->mImage = tex; + local_tex_obj->setBakedReady( baked_version_ready ); + local_tex_obj->setImage(tex); } // virtual @@ -1403,7 +1409,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex; const std::string &name = texture_dict->mName; - const LocalTextureData *local_tex_data = getLocalTextureData(iter->first,0); + const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0); if (isTextureDefined(baked_equiv)) { #if LL_RELEASE_FOR_DOWNLOAD @@ -1414,15 +1420,15 @@ void LLVOAvatarSelf::dumpLocalTextures() const llinfos << "LocTex " << name << ": Baked " << getTEImage(baked_equiv)->getID() << llendl; #endif } - else if (local_tex_data->mImage.notNull()) + else if (local_tex_obj->getImage() != NULL) { - if (local_tex_data->mImage->getID() == IMG_DEFAULT_AVATAR) + if (local_tex_obj->getImage()->getID() == IMG_DEFAULT_AVATAR) { llinfos << "LocTex " << name << ": None" << llendl; } else { - const LLViewerFetchedTexture* image = local_tex_data->mImage; + const LLViewerFetchedTexture* image = local_tex_obj->getImage(); llinfos << "LocTex " << name << ": " << "Discard " << image->getDiscardLevel() << ", " @@ -1464,57 +1470,6 @@ void LLVOAvatarSelf::onLocalTextureLoaded(BOOL success, LLViewerFetchedTexture * } } - -const LLVOAvatarSelf::localtexture_vec_t &LLVOAvatarSelf::getLocalTextureData(LLVOAvatarDefines::ETextureIndex type) const -{ - localtexture_map_t::const_iterator found_localtexture = mLocalTextureDatas.find(type); - if (found_localtexture != mLocalTextureDatas.end()) - { - const localtexture_vec_t &local_tex_data = found_localtexture->second; - return local_tex_data; - } - llassert(0); - static localtexture_vec_t ret; - return ret; -} - -const LocalTextureData* LLVOAvatarSelf::getLocalTextureData(LLVOAvatarDefines::ETextureIndex type, U32 index ) const -{ - const localtexture_vec_t &local_tex_array = getLocalTextureData(type); - - if (index >= local_tex_array.size()) - { - return NULL; - } - - return local_tex_array[index]; -} - -LLVOAvatarSelf::localtexture_vec_t &LLVOAvatarSelf::getLocalTextureData(LLVOAvatarDefines::ETextureIndex type) -{ - localtexture_map_t::iterator found_localtexture = mLocalTextureDatas.find(type); - if (found_localtexture != mLocalTextureDatas.end()) - { - localtexture_vec_t &local_tex_data = found_localtexture->second; - return local_tex_data; - } - llassert(0); - static localtexture_vec_t ret; - return ret; -} - -LocalTextureData* LLVOAvatarSelf::getLocalTextureData(LLVOAvatarDefines::ETextureIndex type, U32 index ) -{ - localtexture_vec_t &local_tex_array = getLocalTextureData(type); - - if (index >= local_tex_array.size()) - { - return NULL; - } - - return local_tex_array[index]; -} - // static void LLVOAvatarSelf::dumpTotalLocalTextureByteCount() { @@ -1679,6 +1634,18 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe } } +LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 wearable_index) const +{ + EWearableType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i); + LLWearable* wearable = gAgentWearables.getWearable(type, wearable_index); + if (wearable) + { + return wearable->getLocalTextureObject(i); + } + + return NULL; +} + //----------------------------------------------------------------------------- // getBakedTE() // Used by the LayerSet. (Layer sets don't in general know what textures depend on them.) diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 7e8a36427d..e34f09aca2 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -180,6 +180,8 @@ protected: void localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); void getLocalTextureByteCount(S32* gl_byte_count) const; /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0); + LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index = 0) const; + private: static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); @@ -227,20 +229,6 @@ private: static LLMap< LLGLenum, LLGLuint*> sScratchTexNames; static LLMap< LLGLenum, F32*> sScratchTexLastBindTime; - //-------------------------------------------------------------------- - // Texture Data - //-------------------------------------------------------------------- -private: - typedef std::vector<LocalTextureData*> localtexture_vec_t; // all textures of a certain TE - typedef std::map<LLVOAvatarDefines::ETextureIndex, localtexture_vec_t> localtexture_map_t; // texture TE vectors arranged by texture type - localtexture_map_t mLocalTextureDatas; - - const localtexture_vec_t& getLocalTextureData(LLVOAvatarDefines::ETextureIndex index) const; // const accessor into mLocalTextureDatas - const LocalTextureData* getLocalTextureData(LLVOAvatarDefines::ETextureIndex type, U32 index) const; // const accessor to individual LocalTextureData - - localtexture_vec_t& getLocalTextureData(LLVOAvatarDefines::ETextureIndex index); // accessor into mLocalTextureDatas - LocalTextureData* getLocalTextureData(LLVOAvatarDefines::ETextureIndex type, U32 index); // accessor to individual LocalTextureData - /** Textures ** ** *******************************************************************************/ @@ -278,6 +266,8 @@ public: // HUDs //-------------------------------------------------------------------- private: + U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const; + LLViewerJoint* mScreenp; // special purpose joint for HUD attachments /** Attachments diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index e8c4046660..0d3dd10a01 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -156,7 +156,7 @@ BOOL LLWearable::exportFile(LLFILE* file) const for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter) { S32 te = iter->first; - const LLUUID& image_id = iter->second; + const LLUUID& image_id = iter->second.getID(); if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 ) { return FALSE; @@ -350,7 +350,8 @@ BOOL LLWearable::importFile( LLFILE* file ) return FALSE; } - mTEMap[te] = LLUUID(text_buffer ); + //TODO: check old values + mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, LLUUID(text_buffer)); } return TRUE; @@ -465,10 +466,15 @@ BOOL LLWearable::isDirty() const llassert( 0 ); continue; } - const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); - if( avatar_image->getID() != image_id ) + + te_map_t::const_iterator iter = mTEMap.find(te); + if(iter != mTEMap.end()) { - return TRUE; + const LLUUID& image_id = iter->second.getID(); + if (avatar_image->getID() != image_id) + { + return TRUE; + } } } } @@ -511,7 +517,7 @@ void LLWearable::setTexturesToDefaults() { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - mTEMap[te] = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); } } } @@ -558,7 +564,16 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); + te_map_t::const_iterator iter = mTEMap.find(te); + LLUUID image_id; + if(iter != mTEMap.end()) + { + image_id = iter->second.getID(); + } + else + { + image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + } LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE ); avatar->setLocalTextureTE(te, image, set_by_user); } @@ -570,7 +585,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) { LLViewerInventoryItem* item; // MULTI_WEARABLE: - item = (LLViewerInventoryItem*)gInventory.getItem(gAgentWearables.getWearableItem(mType,0)); + item = (LLViewerInventoryItem*)gInventory.getItem(gAgentWearables.getWearableItemID(mType,0)); U32 perm_mask = PERM_NONE; BOOL is_complete = FALSE; if(item) @@ -685,7 +700,7 @@ void LLWearable::readFromAvatar() LLViewerTexture* image = avatar->getTEImage( te ); if( image ) { - mTEMap[te] = image->getID(); + mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, image->getID()); } } } @@ -733,12 +748,54 @@ void LLWearable::copyDataFrom(const LLWearable* src) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { - const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te)); - mTEMap[te] = image_id; + te_map_t::const_iterator iter = mTEMap.find(te); + LLUUID image_id; + if(iter != mTEMap.end()) + { + image_id = iter->second.getID(); + } + else + { + image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); + } + mTEMap[te] = LLLocalTextureObject(NULL, NULL, NULL, image_id); } } } +void LLWearable::setItemID(const LLUUID& item_id) +{ + mItemID = item_id; +} + +const LLUUID& LLWearable::getItemID() const +{ + return mItemID; +} + +LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const +{ + te_map_t::const_iterator iter = mTEMap.find(index); + if( iter != mTEMap.end() ) + { + return (LLLocalTextureObject*) &iter->second; + } + return NULL; +} + +void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject *lto) +{ + if( lto ) + { + LLLocalTextureObject obj(*lto); + mTEMap[index] = obj; + } + else + { + mTEMap.erase(index); + } +} + struct LLWearableSaveData { EWearableType mType; @@ -849,7 +906,7 @@ std::ostream& operator<<(std::ostream &s, const LLWearable &w) iter != w.mTEMap.end(); ++iter) { S32 te = iter->first; - const LLUUID& image_id = iter->second; + const LLUUID& image_id = iter->second.getID(); s << " " << te << " " << image_id << "\n"; } return s; diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index 7ebdd788ce..5f0b235c7f 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -39,6 +39,8 @@ #include "llsaleinfo.h" #include "llassetstorage.h" #include "llwearabledictionary.h" +#include "llfile.h" +#include "lllocaltextureobject.h" class LLViewerInventoryItem; @@ -60,7 +62,7 @@ public: // Accessors //-------------------------------------------------------------------- public: - const LLAssetID& getID() const { return mAssetID; } + const LLAssetID& getAssetID() const { return mAssetID; } const LLTransactionID& getTransactionID() const { return mTransactionID; } EWearableType getType() const { return mType; } void setType(EWearableType type) { mType = type; } @@ -99,6 +101,10 @@ public: static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; } friend std::ostream& operator<<(std::ostream &s, const LLWearable &w); + void setItemID(const LLUUID& item_id); + const LLUUID& getItemID() const; + LLLocalTextureObject* getLocalTextureObject(S32 index) const; + void setLocalTextureObject(S32 index, LLLocalTextureObject *lto); private: static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml. @@ -113,8 +119,9 @@ private: typedef std::map<S32, F32> param_map_t; param_map_t mVisualParamMap; // maps visual param id to weight - typedef std::map<S32, LLUUID> te_map_t; - te_map_t mTEMap; // maps TE to Image ID + typedef std::map<S32, LLLocalTextureObject> te_map_t; + te_map_t mTEMap; // maps TE to LocalTextureObject + LLUUID mItemID; // ID of the inventory item in the agent's inventory }; #endif // LL_LLWEARABLE_H |