123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895 |
- /**
- * @file llwearable.cpp
- * @brief LLWearable class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "llwearable.h"
- #include "llavatarappearance.h"
- #include "llavatarappearancedefines.h"
- #include "lllocaltextureobject.h"
- #include "lltexlayer.h"
- #include "lltexturemanagerbridge.h"
- #include "llvisualparam.h"
- using namespace LLAvatarAppearanceDefines;
- // Keep track of active wearables: LLWearableList needs this to avoid double-
- // free !!!
- fast_hset<LLWearable*> LLWearable::sWearableList;
- //static
- S32 LLWearable::sCurrentDefinitionVersion = 1;
- // Private local helper function
- static std::string terse_F32_to_string(F32 f)
- {
- std::string r = llformat("%.2f", f);
- S32 len = r.length();
- // "1.20" -> "1.2"
- // "24.00" -> "24."
- while (len > 0 && r[len - 1] == '0')
- {
- r.erase(--len, 1);
- }
- if (r[len - 1] == '.')
- {
- // "24." -> "24"
- r.erase(len - 1, 1);
- }
- else if (r[0] == '-' && r[1] == '0')
- {
- // "-0.59" -> "-.59"
- r.erase(1, 1);
- }
- else if (r[0] == '0')
- {
- // "0.59" -> ".59"
- r.erase(0, 1);
- }
- return r;
- }
- LLWearable::LLWearable()
- : mDefinitionVersion(-1),
- mName(),
- mDescription(),
- mPermissions(),
- mSaleInfo(),
- mType(LLWearableType::WT_NONE),
- mSavedVisualParamMap(),
- mVisualParamIndexMap(),
- mTEMap(),
- mSavedTEMap()
- {
- sWearableList.insert(this);
- }
- //virtual
- LLWearable::~LLWearable()
- {
- sWearableList.erase(this);
- for (visual_param_index_map_t::iterator it = mVisualParamIndexMap.begin();
- it != mVisualParamIndexMap.end(); ++it)
- {
- LLVisualParam* vp = it->second;
- if (vp)
- {
- vp->clearNextParam();
- delete vp;
- it->second = NULL;
- }
- }
- mVisualParamIndexMap.clear();
- destroyTextures();
- }
- const std::string& LLWearable::getTypeLabel() const
- {
- return LLWearableType::getTypeLabel(mType);
- }
- const std::string& LLWearable::getTypeName() const
- {
- return LLWearableType::getTypeName(mType);
- }
- LLAssetType::EType LLWearable::getAssetType() const
- {
- return LLWearableType::getAssetType(mType);
- }
- bool LLWearable::exportFile(const std::string& filename) const
- {
- llofstream ofs(filename.c_str(),
- std::ios_base::out | std::ios_base::trunc |
- std::ios_base::binary);
- return ofs.is_open() && exportStream(ofs);
- }
- //virtual
- bool LLWearable::exportStream(std::ostream& output_stream) const
- {
- if (!output_stream.good()) return false;
- // Header and version
- output_stream << "LLWearable version " << mDefinitionVersion << "\n";
- // Name
- output_stream << mName << "\n";
- // Description
- output_stream << mDescription << "\n";
- // Permissions
- if (!mPermissions.exportLegacyStream(output_stream))
- {
- return false;
- }
- // Sale info
- if (!mSaleInfo.exportLegacyStream(output_stream))
- {
- return false;
- }
- // Wearable type
- output_stream << "type " << (S32) getType() << "\n";
- // Parameters
- output_stream << "parameters " << mVisualParamIndexMap.size() << "\n";
- for (visual_param_index_map_t::const_iterator
- iter = mVisualParamIndexMap.begin(),
- end = mVisualParamIndexMap.end();
- iter != end; ++iter)
- {
- S32 param_id = iter->first;
- const LLVisualParam* param = iter->second;
- F32 param_weight = param->getWeight();
- output_stream << param_id << " " << terse_F32_to_string(param_weight)
- << "\n";
- }
- // Texture entries
- output_stream << "textures " << mTEMap.size() << "\n";
- for (te_map_t::const_iterator iter = mTEMap.begin(), end = mTEMap.end();
- iter != end; ++iter)
- {
- S32 te = iter->first;
- const LLUUID& image_id = iter->second->getID();
- output_stream << te << " " << image_id << "\n";
- }
- return true;
- }
- void LLWearable::createVisualParams(LLAvatarAppearance* avatarp)
- {
- for (LLViewerVisualParam* param =
- (LLViewerVisualParam*)avatarp->getFirstVisualParam();
- param; param = (LLViewerVisualParam*) avatarp->getNextVisualParam())
- {
- if (param->getWearableType() == mType)
- {
- LLVisualParam* clone_param = param->cloneParam(this);
- clone_param->setParamLocation(LOC_UNKNOWN);
- clone_param->setParamLocation(LOC_WEARABLE);
- addVisualParam(clone_param);
- }
- }
- // Resync driver parameters to point to the newly cloned driven
- // parameters
- for (visual_param_index_map_t::iterator
- param_iter = mVisualParamIndexMap.begin(),
- end = mVisualParamIndexMap.end();
- param_iter != end; ++param_iter)
- {
- LLVisualParam* param = param_iter->second;
- LLVisualParam*(LLWearable::*wearable_function)(S32)const =
- &LLWearable::getVisualParam;
- // need this line to disambiguate between versions of
- // LLCharacter::getVisualParam()
- LLVisualParam*(LLAvatarAppearance::*param_function)(S32)const =
- &LLAvatarAppearance::getVisualParam;
- param->resetDrivenParams();
- if (!param->linkDrivenParams(boost::bind(wearable_function,
- (LLWearable*)this, _1),
- false))
- {
- if (!param->linkDrivenParams(boost::bind(param_function, avatarp,
- _1),
- true))
- {
- #if 0 // Temporarily made into a debug message, till LL determines
- // whether non-linked params are a normal occurrence or not...
- llwarns << "Could not link driven params for wearable "
- << getName() << " id: " << param->getID() << llendl;
- #else
- LL_DEBUGS("Avatar") << "Could not link driven params for wearable "
- << getName() << " id: " << param->getID()
- << LL_ENDL;
- #endif
- continue;
- }
- }
- }
- }
- void LLWearable::createLayers(S32 te, LLAvatarAppearance* avatarp)
- {
- LLTexLayerSet* layer_set = NULL;
- const LLAvatarAppearanceDictionary::TextureEntry* texture_dict =
- gAvatarAppDictp->getTexture((ETextureIndex)te);
- if (texture_dict && texture_dict->mIsUsedByBakedTexture)
- {
- const EBakedTextureIndex baked_index =
- texture_dict->mBakedTextureIndex;
- layer_set = avatarp->getAvatarLayerSet(baked_index);
- }
- if (layer_set)
- {
- layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
- }
- else
- {
- llwarns << "Could not find layerset for texture entry " << te
- << " in wearable. mIsUsedByBakedTexture = "
- << texture_dict->mBakedTextureIndex << llendl;
- }
- }
- LLWearable::EImportResult LLWearable::importFile(const std::string& filename,
- LLAvatarAppearance* avatarp)
- {
- llifstream ifs(filename.c_str(), std::ios_base::in | std::ios_base::binary);
- return ifs.is_open() ? importStream(ifs, avatarp) : FAILURE;
- }
- //virtual
- LLWearable::EImportResult LLWearable::importStream(std::istream& input_stream,
- LLAvatarAppearance* avatarp)
- {
- if (!avatarp || !gTextureManagerBridgep)
- {
- return FAILURE;
- }
- // *NOTE: changing the type or size of this buffer will require changes in
- // the fscanf() code below.
- // We are using a local max buffer size here to avoid issues if MAX_STRING
- // size changes.
- constexpr U32 PARSE_BUFFER_SIZE = 2048;
- char buffer[PARSE_BUFFER_SIZE];
- char uuid_buffer[37];
- // This data is being generated on the viewer.
- // Impose some sane limits on parameter and texture counts.
- constexpr S32 MAX_WEARABLE_ASSET_TEXTURES = 100;
- constexpr S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000;
- // Read header and version
- if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
- {
- llwarns << "Failed to read wearable asset input stream." << llendl;
- return FAILURE;
- }
- if (sscanf(buffer, "LLWearable version %d\n", &mDefinitionVersion) != 1)
- {
- return BAD_HEADER;
- }
- // Temporary hack to allow wearables with definition version 24 to still
- // load. This should only affect lindens and NDA'd testers who have saved
- // wearables in 2.0 the extra check for version == 24 can be removed before
- // release, once internal testers have loaded these wearables again.
- // See hack pt 2 at bottom of function to ensure that these wearables get
- // re-saved with version definition 22.
- if (mDefinitionVersion > sCurrentDefinitionVersion &&
- mDefinitionVersion != 24)
- {
- llwarns << "Wearable asset has newer version (" << mDefinitionVersion
- << ") than XML (" << sCurrentDefinitionVersion << ")"
- << llendl;
- return FAILURE;
- }
- // Name may be empty
- if (!input_stream.good())
- {
- llwarns << "Bad wearable asset: early end of input stream while reading name"
- << llendl;
- return FAILURE;
- }
- input_stream.getline(buffer, PARSE_BUFFER_SIZE);
- mName = buffer;
- // Description may be empty
- if (!input_stream.good())
- {
- llwarns << "Bad wearable asset: early end of input stream while reading description"
- << llendl;
- return FAILURE;
- }
- input_stream.getline(buffer, PARSE_BUFFER_SIZE);
- mDescription = buffer;
- // Permissions may have extra empty lines before the correct line
- if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
- {
- llwarns << "Bad wearable asset: early end of input stream while reading permissions"
- << llendl;
- return FAILURE;
- }
- S32 perm_version = -1;
- if (sscanf(buffer, " permissions %d\n", &perm_version) != 1 ||
- perm_version != 0)
- {
- llwarns << "Bad wearable asset: missing valid permissions" << llendl;
- return FAILURE;
- }
- if (!mPermissions.importLegacyStream(input_stream))
- {
- return FAILURE;
- }
- // Sale info
- if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
- {
- llwarns << "Bad wearable asset: early end of input stream while reading sale info"
- << llendl;
- return FAILURE;
- }
- S32 sale_info_version = -1;
- if (sscanf(buffer, " sale_info %d\n", &sale_info_version) != 1 ||
- sale_info_version != 0)
- {
- llwarns << "Bad wearable asset: missing valid sale_info" << llendl;
- return FAILURE;
- }
- // Sale info used to contain next owner perm. It is now in the permissions.
- // Thus, we read that out, and fix legacy objects. It's possible this op
- // would fail, but it should pick up the vast majority of the tasks.
- bool has_perm_mask = false;
- U32 perm_mask = 0;
- if (!mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask))
- {
- return FAILURE;
- }
- if (has_perm_mask)
- {
- // Fair use fix.
- if (!(perm_mask & PERM_COPY))
- {
- perm_mask |= PERM_TRANSFER;
- }
- mPermissions.setMaskNext(perm_mask);
- }
- // Wearable type
- if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
- {
- llwarns << "Bad wearable asset: early end of input stream while reading type"
- << llendl;
- return FAILURE;
- }
- S32 type = -1;
- if (sscanf(buffer, "type %d\n", &type) != 1)
- {
- llwarns << "Bad wearable asset: cannot read type" << llendl;
- return FAILURE;
- }
- if (type >= 0 && type < LLWearableType::WT_COUNT)
- {
- setType((LLWearableType::EType)type, avatarp);
- }
- else
- {
- mType = LLWearableType::WT_COUNT;
- llwarns << "Bad wearable asset: bad type #" << type << llendl;
- return FAILURE;
- }
- // Parameters header
- if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
- {
- llwarns << "Bad wearable asset: early end of input stream while reading parameters header. Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- return FAILURE;
- }
- S32 num_parameters = -1;
- if (sscanf(buffer, "parameters %d\n", &num_parameters) != 1)
- {
- llwarns << "Bad wearable asset: missing parameters block. Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- return FAILURE;
- }
- if (num_parameters > MAX_WEARABLE_ASSET_PARAMETERS)
- {
- llwarns << "Bad wearable asset: too many parameters: "
- << num_parameters << ". Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- return FAILURE;
- }
- S32 param_count = mVisualParamIndexMap.size();
- if (num_parameters > param_count)
- {
- llwarns << "Wearable parameter mismatch. Reading in "
- << num_parameters << " from file, but created " << param_count
- << " from avatar parameters. Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- }
- else if (num_parameters < param_count)
- {
- llinfos << "Old wearable detected. Reading in "
- << num_parameters << " from file, but created " << param_count
- << " from avatar parameters. Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- }
- // Parameters
- S32 i;
- for (i = 0; i < num_parameters; ++i)
- {
- if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
- {
- llwarns << "Bad wearable asset: early end of input stream "
- << "while reading parameter #" << i << ". Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- return FAILURE;
- }
- S32 param_id = 0;
- F32 param_weight = 0.f;
- if (sscanf(buffer, "%d %f\n", ¶m_id, ¶m_weight) != 2)
- {
- llwarns << "Bad wearable asset: bad parameter, #" << i
- << ". Type: " << LLWearableType::getTypeName(getType())
- << llendl;
- return FAILURE;
- }
- mSavedVisualParamMap[param_id] = param_weight;
- }
- // Textures header
- if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
- {
- llwarns << "Bad wearable asset: early end of input stream while reading textures header #"
- << i << ". Type: " << LLWearableType::getTypeName(getType())
- << llendl;
- return FAILURE;
- }
- S32 num_textures = -1;
- if (sscanf(buffer, "textures %d\n", &num_textures) != 1)
- {
- llwarns << "Bad wearable asset: missing textures block. Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- return FAILURE;
- }
- if (num_textures > MAX_WEARABLE_ASSET_TEXTURES)
- {
- llwarns << "Bad wearable asset: too many textures: " << num_textures
- << ". Type: " << LLWearableType::getTypeName(getType())
- << llendl;
- return FAILURE;
- }
- // Textures
- for (i = 0; i < num_textures; ++i)
- {
- if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
- {
- llwarns << "Bad wearable asset: early end of input stream "
- << "while reading textures #" << i << ". Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- return FAILURE;
- }
- S32 te = 0;
- if (sscanf(buffer, "%d %36s\n", &te, uuid_buffer) != 2)
- {
- llwarns << "Bad wearable asset: bad texture, #" << i << ". Type: "
- << LLWearableType::getTypeName(getType()) << llendl;
- return FAILURE;
- }
- if (te >= TEX_NUM_INDICES)
- {
- llwarns << "Bad wearable asset: texture index too large " << te
- << ". Type: " << LLWearableType::getTypeName(getType())
- << llendl;
- return FAILURE;
- }
- if (!LLUUID::validate(uuid_buffer))
- {
- llwarns << "Bad wearable asset: bad texture uuid: " << uuid_buffer
- << ". Type: " << LLWearableType::getTypeName(getType())
- << llendl;
- return FAILURE;
- }
- LLUUID id = LLUUID(uuid_buffer);
- LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture(id);
- if (mTEMap.find(te) != mTEMap.end())
- {
- delete mTEMap[te];
- }
- if (mSavedTEMap.find(te) != mSavedTEMap.end())
- {
- delete mSavedTEMap[te];
- }
- LLUUID textureid(uuid_buffer);
- mTEMap[te] = new LLLocalTextureObject(image, textureid);
- mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
- createLayers(te, avatarp);
- }
- // Copy all saved param values to working params
- revertValues();
- return SUCCESS;
- }
- bool LLWearable::getNextPopulatedLine(std::istream& input_stream, char* buffer,
- U32 buffer_size)
- {
- if (!input_stream.good())
- {
- return false;
- }
- do
- {
- input_stream.getline(buffer, buffer_size);
- }
- while (input_stream.good() && buffer[0] == '\0');
- return buffer[0] != '\0';
- }
- void LLWearable::setType(LLWearableType::EType type,
- LLAvatarAppearance* avatarp)
- {
- mType = type;
- createVisualParams(avatarp);
- }
- LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
- {
- te_map_t::iterator iter = mTEMap.find(index);
- if (iter != mTEMap.end())
- {
- LLLocalTextureObject* lto = iter->second;
- return lto;
- }
- return NULL;
- }
- const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
- {
- te_map_t::const_iterator iter = mTEMap.find(index);
- if (iter != mTEMap.end())
- {
- const LLLocalTextureObject* lto = iter->second;
- return lto;
- }
- return NULL;
- }
- void LLWearable::getLocalTextureListSeq(std::vector<LLLocalTextureObject*>& lv)
- {
- lv.clear();
- lv.reserve(mTEMap.size());
- for (te_map_t::const_iterator iter = mTEMap.begin(), end = mTEMap.end();
- iter != end; ++iter)
- {
- LLLocalTextureObject* ltop = iter->second;
- if (ltop)
- {
- lv.push_back(ltop);
- }
- }
- }
- LLLocalTextureObject* LLWearable::setLocalTextureObject(S32 index,
- LLLocalTextureObject& lto)
- {
- if (mTEMap.find(index) != mTEMap.end())
- {
- mTEMap.erase(index);
- }
- LLLocalTextureObject* clone_lto = new LLLocalTextureObject(lto);
- mTEMap[index] = clone_lto;
- return clone_lto;
- }
- // *FIXME: this triggers changes to driven params on avatar, potentially
- // clobbering baked appearance.
- void LLWearable::revertValues()
- {
- // Update saved settings so wearable is no longer dirty; non-driver params
- // first.
- for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(),
- end = mSavedVisualParamMap.end();
- iter != end; ++iter)
- {
- S32 id = iter->first;
- F32 value = iter->second;
- LLVisualParam* param = getVisualParam(id);
- if (param && !param->asDriverParam())
- {
- setVisualParamWeight(id, value, true);
- }
- }
- // Then update driver params
- for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(),
- end = mSavedVisualParamMap.end();
- iter != end; ++iter)
- {
- S32 id = iter->first;
- F32 value = iter->second;
- LLVisualParam* param = getVisualParam(id);
- if (param && param->asDriverParam())
- {
- setVisualParamWeight(id, value, true);
- }
- }
- // Make sure that saved values are sane
- for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(),
- end = mSavedVisualParamMap.end();
- iter != end; ++iter)
- {
- S32 id = iter->first;
- LLVisualParam* param = getVisualParam(id);
- if (param)
- {
- mSavedVisualParamMap[id] = param->getWeight();
- }
- }
- syncImages(mSavedTEMap, mTEMap);
- }
- void LLWearable::saveValues()
- {
- // Update saved settings so wearable is no longer dirty
- mSavedVisualParamMap.clear();
- for (visual_param_index_map_t::const_iterator
- iter = mVisualParamIndexMap.begin(),
- end = mVisualParamIndexMap.end();
- iter != end; ++iter)
- {
- S32 id = iter->first;
- LLVisualParam* wearable_param = iter->second;
- F32 value = wearable_param->getWeight();
- mSavedVisualParamMap[id] = value;
- }
- // Deep copy of mTEMap (copies only those tes that are current, filling in
- // defaults where needed)
- syncImages(mTEMap, mSavedTEMap);
- }
- void LLWearable::syncImages(te_map_t& src, te_map_t& dst)
- {
- // Deep copy of mTEMap (copies only those tes that are current, filling in
- // defaults where needed)
- for (S32 te = 0; te < TEX_NUM_INDICES; ++te)
- {
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == mType)
- {
- te_map_t::const_iterator iter = src.find(te);
- LLUUID image_id;
- LLGLTexture* image = NULL;
- LLLocalTextureObject* lto = NULL;
- if (iter != src.end())
- {
- // There is a Local Texture Object in the source image map. Use
- // this to populate the values to store in the destination
- // image map.
- lto = iter->second;
- image = lto->getImage();
- image_id = lto->getID();
- }
- else
- {
- // There is no Local Texture Object in the source image map.
- // Get the defaults values for populating the destination image
- // map.
- image_id = getDefaultTextureImageID((ETextureIndex) te);
- if (gTextureManagerBridgep)
- {
- image = gTextureManagerBridgep->getFetchedTexture(image_id);
- }
- }
- if (dst.find(te) != dst.end())
- {
- // There is already an entry in the destination map for the
- // texture. Just update its values.
- dst[te]->setImage(image);
- dst[te]->setID(image_id);
- }
- else
- {
- // No entry found in the destination map, we need to create a
- // new Local Texture Object
- dst[te] = new LLLocalTextureObject(image, image_id);
- }
- if (lto)
- {
- // If we pulled values from a Local Texture Object in the
- // source map, make sure the proper flags are set in the new
- // (or updated) entry in the destination map.
- dst[te]->setBakedReady(lto->getBakedReady());
- dst[te]->setDiscard(lto->getDiscard());
- }
- }
- }
- }
- void LLWearable::destroyTextures()
- {
- std::for_each(mTEMap.begin(), mTEMap.end(), DeletePairedPointer());
- mTEMap.clear();
- std::for_each(mSavedTEMap.begin(), mSavedTEMap.end(),
- DeletePairedPointer());
- mSavedTEMap.clear();
- }
- void LLWearable::addVisualParam(LLVisualParam* param)
- {
- S32 id = param->getID();
- if (mVisualParamIndexMap[id])
- {
- delete mVisualParamIndexMap[id];
- }
- param->setIsDummy(false);
- param->setParamLocation(LOC_WEARABLE);
- mVisualParamIndexMap[id] = param;
- mSavedVisualParamMap[id] = param->getDefaultWeight();
- }
- void LLWearable::setVisualParamWeight(S32 i, F32 value, bool upload_bake)
- {
- visual_param_index_map_t::iterator it = mVisualParamIndexMap.find(i);
- if (it == mVisualParamIndexMap.end())
- {
- llwarns << "Passed invalid parameter index #" << i << " for wearable: "
- << getName() << llendl;
- }
- it->second->setWeight(value, upload_bake);
- }
- F32 LLWearable::getVisualParamWeight(S32 i) const
- {
- visual_param_index_map_t::const_iterator it = mVisualParamIndexMap.find(i);
- if (it == mVisualParamIndexMap.end())
- {
- llwarns << "Passed invalid parameter index #" << i << " for wearable: "
- << getName() << llendl;
- return -1.f;
- }
- const LLVisualParam* wearable_param = it->second;
- return wearable_param->getWeight();
- }
- LLVisualParam* LLWearable::getVisualParam(S32 i) const
- {
- visual_param_index_map_t::const_iterator it = mVisualParamIndexMap.find(i);
- return it == mVisualParamIndexMap.end() ? NULL : it->second;
- }
- void LLWearable::getVisualParams(visual_param_vec_t& list)
- {
- list.reserve(mVisualParamIndexMap.size());
- // Add all visual params to the passed-in vector
- for (visual_param_index_map_t::iterator
- iter = mVisualParamIndexMap.begin(),
- end = mVisualParamIndexMap.end();
- iter != end; ++iter)
- {
- list.push_back(iter->second);
- }
- }
- void LLWearable::animateParams(F32 delta, bool upload_bake)
- {
- for (visual_param_index_map_t::iterator
- iter = mVisualParamIndexMap.begin(),
- end = mVisualParamIndexMap.end();
- iter != end; ++iter)
- {
- LLVisualParam* param = (LLVisualParam*)iter->second;
- param->animate(delta, upload_bake);
- }
- }
- LLColor4 LLWearable::getClothesColor(S32 te) const
- {
- LLColor4 color;
- U32 param_name[3];
- if (LLAvatarAppearance::teToColorParams((LLAvatarAppearanceDefines::ETextureIndex)te,
- param_name))
- {
- for (U8 index = 0; index < 3; ++index)
- {
- color.mV[index] = getVisualParamWeight(param_name[index]);
- }
- }
- return color;
- }
- void LLWearable::setClothesColor(S32 te, const LLColor4& new_color,
- bool upload_bake)
- {
- U32 param_name[3];
- if (LLAvatarAppearance::teToColorParams((LLAvatarAppearanceDefines::ETextureIndex)te,
- param_name))
- {
- for (U8 index = 0; index < 3; ++index)
- {
- setVisualParamWeight(param_name[index], new_color.mV[index],
- upload_bake);
- }
- }
- }
- void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
- {
- if (!avatarp) return;
- // Pull params
- for (LLVisualParam* param = avatarp->getFirstVisualParam(); param;
- param = avatarp->getNextVisualParam())
- {
- if (param &&
- ((LLViewerVisualParam*)param)->getWearableType() == mType &&
- // Cross-wearable parameters are not authoritative, as they are
- // driven by a different wearable. So do not copy the values to
- // the avatar object if cross wearable. Cross wearable params get
- // their values from the avatar, they shouldn't write the other
- // way.
- !((LLViewerVisualParam*)param)->getCrossWearable())
- {
- S32 param_id = param->getID();
- F32 weight = getVisualParamWeight(param_id);
- avatarp->setVisualParamWeight(param_id, weight, false);
- }
- }
- }
|