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
master
Neal Orman 2009-07-14 15:14:46 +00:00
parent 064e917e3d
commit 56e0455479
14 changed files with 443 additions and 368 deletions

View File

@ -48,6 +48,7 @@
#include "llthread.h" // LLThreadSafeRefCount
#include "llstring.h"
#include "llstringtable.h"
#include "llfile.h"
class LLVector3;

View File

@ -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

View File

@ -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())

View File

@ -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,40 +550,13 @@ 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;
}
//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 0;
}
const wearableentry_vec_t& wearable_vec = wearable_iter->second;
return wearable_vec.size();
}
LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearableType type, U32 index)
{
wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
@ -609,22 +574,73 @@ LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearabl
}
}
const LLAgentWearables::LLWearableInv* LLAgentWearables::getWearableInv(const EWearableType type, U32 index) const
void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable)
{
wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
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 LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) 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 NULL;
}
const wearableentry_vec_t& wearable_vec = wearable_iter->second;
if (index>=wearable_vec.size())
return &s_null_wearable;
{
return NULL;
}
else
{
return wearable_vec[index];
}
}
const LLUUID& LLAgentWearables::getWearableItem(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
{
return getWearableInv(type,index)->mItemID;
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
{
return 0;
}
const wearableentry_vec_t& wearable_vec = wearable_iter->second;
return wearable_vec.size();
}
BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
{
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();

View File

@ -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;

View File

@ -37,6 +37,7 @@
#include "llgl.h"
#include "llcoord.h"
#include "llviewertexture.h"
#include "llcamera.h"
class LLViewerDynamicTexture : public LLViewerTexture
{

View File

@ -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.

View File

@ -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

View File

@ -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; }

View File

@ -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;
}

View File

@ -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.)

View File

@ -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

View File

@ -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;

View File

@ -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