diff options
author | Neal Orman <nyx@lindenlab.com> | 2009-07-14 15:14:46 +0000 |
---|---|---|
committer | Neal Orman <nyx@lindenlab.com> | 2009-07-14 15:14:46 +0000 |
commit | 56e045547951cdad356da38ba3da4251d58d3fb8 (patch) | |
tree | 7d7f14cbf9741b7e5b12f36a04062888b31aa8cd /indra | |
parent | 064e917e3d34fa04edf20a6d583819f194171ea7 (diff) |
QAR-1602 Checkpoint for Avatar Pipeline Multiple textures branch
Merging changes for first checkpoint of multiple textures branch as part of the avatar pipeline project (AVP). Functionality should be same as before, but sets up the structure that later changes build upon. Changes passed QA, merge conflicts were minimal and easily resolved. Contact Nyx with any problems with this code.
-Nyx
Diffstat (limited to 'indra')
-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 |