summaryrefslogtreecommitdiff
path: root/indra/llappearance
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llappearance')
-rw-r--r--indra/llappearance/llavatarappearance.cpp45
-rw-r--r--indra/llappearance/llavatarappearance.h4
-rw-r--r--indra/llappearance/lltexlayer.cpp2
-rw-r--r--indra/llappearance/llwearable.cpp138
-rw-r--r--indra/llappearance/llwearable.h18
5 files changed, 137 insertions, 70 deletions
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index e2dfa2fb74..7d37f5f509 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -1332,43 +1332,16 @@ LLColor4 LLAvatarAppearance::getGlobalColor( const std::string& color_name ) con
// virtual
BOOL LLAvatarAppearance::isWearingWearableType(LLWearableType::EType type) const
{
- if (mIsDummy) return TRUE;
-
- switch(type)
- {
- case LLWearableType::WT_SHAPE:
- case LLWearableType::WT_SKIN:
- case LLWearableType::WT_HAIR:
- case LLWearableType::WT_EYES:
- return TRUE; // everyone has all bodyparts
- default:
- break; // Do nothing
- }
+ return mWearableData->getWearableCount(type) > 0;
+}
- /* switch(type)
- case LLWearableType::WT_SHIRT:
- indicator_te = TEX_UPPER_SHIRT; */
- for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
- ++tex_iter)
- {
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
- if (texture_dict->mWearableType == type)
- {
- // If you're checking another avatar's clothing, you don't have component textures.
- // Thus, you must check to see if the corresponding baked texture is defined.
- // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
- // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
- // gets baked into a texture that always exists (upper or lower).
- if (texture_dict->mIsUsedByBakedTexture)
- {
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
- }
- return FALSE;
- }
- }
- return FALSE;
+LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_index) const
+{
+ /* switch(index)
+ case TEX_HEAD_BAKED:
+ case TEX_HEAD_BODYPAINT:
+ return mHeadLayerSet; */
+ return mBakedTextureDatas[baked_index].mTexLayerSet;
}
//-----------------------------------------------------------------------------
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index 6eab9b9d1f..b512fd4eda 100644
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -269,8 +269,12 @@ private:
** **
** BAKED TEXTURES
**/
+public:
+ LLTexLayerSet* getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+
protected:
virtual LLTexLayerSet* createTexLayerSet() = 0;
+
protected:
class LLMaskedMorph;
typedef std::deque<LLMaskedMorph *> morph_list_t;
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index 1325267dc2..e90efac36b 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -1620,7 +1620,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
}
if (layer)
{
- wearable->writeToAvatar();
+ wearable->writeToAvatar(mAvatarAppearance);
layer->setLTO(lto);
success &= layer->render(x,y,width,height);
}
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
index ea14c6320f..9e73a6669a 100644
--- a/indra/llappearance/llwearable.cpp
+++ b/indra/llappearance/llwearable.cpp
@@ -123,27 +123,80 @@ BOOL LLWearable::exportFile(LLFILE* file) const
}
// texture entries
- S32 num_textures = mTextureIDMap.size();
+ S32 num_textures = mTEMap.size();
if( fprintf( file, "textures %d\n", num_textures ) < 0 )
{
- return FALSE;
+ return FALSE;
}
-
- for (texture_id_map_t::const_iterator iter = mTextureIDMap.begin(); iter != mTextureIDMap.end(); ++iter)
+
+ for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
{
- S32 te = iter->first;
- const LLUUID& image_id = iter->second;
- if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
+ S32 te = iter->first;
+ const LLUUID& image_id = iter->second->getID();
+ if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void LLWearable::createVisualParams(LLAvatarAppearance *avatarp)
+{
+ for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatarp->getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*) avatarp->getNextVisualParam())
+ {
+ if (param->getWearableType() == mType)
{
- return FALSE;
+ addVisualParam(param->cloneParam(this));
+ }
+ }
+
+ // resync driver parameters to point to the newly cloned driven parameters
+ for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin();
+ param_iter != mVisualParamIndexMap.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))
+ {
+ llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
+ continue;
+ }
}
}
- return TRUE;
}
+void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
+{
+ LLTexLayerSet *layer_set = NULL;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+ if (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
+ {
+ llerrs << "could not find layerset for LTO in wearable!" << llendl;
+ }
+}
// virtual
-LLWearable::EImportResult LLWearable::importFile( LLFILE* file )
+LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearance* avatarp )
{
// *NOTE: changing the type or size of this buffer will require
// changes in the fscanf() code below. You would be better off
@@ -158,6 +211,11 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file )
return LLWearable::BAD_HEADER;
}
+ if(!avatarp)
+ {
+ return LLWearable::FAILURE;
+ }
+
// 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
@@ -265,7 +323,7 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file )
}
if( 0 <= type && type < LLWearableType::WT_COUNT )
{
- setType((LLWearableType::EType)type);
+ setType((LLWearableType::EType)type, avatarp);
}
else
{
@@ -313,37 +371,49 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file )
}
// textures
- mTextureIDMap.clear();
for( i = 0; i < num_textures; i++ )
{
S32 te = 0;
- fields_read = fscanf( /* Flawfinder: ignore */
- file,
- "%d %2047s\n",
- &te, text_buffer);
+ fields_read = fscanf( /* Flawfinder: ignore */
+ file,
+ "%d %2047s\n",
+ &te, text_buffer);
if( fields_read != 2 )
{
- llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
- return LLWearable::FAILURE;
+ llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
+ return LLWearable::FAILURE;
}
-
+
if( !LLUUID::validate( text_buffer ) )
{
- llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
- return LLWearable::FAILURE;
+ llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
+ return LLWearable::FAILURE;
}
LLUUID id = LLUUID(text_buffer);
- mTextureIDMap[te] = id;
+ 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(text_buffer);
+ mTEMap[te] = new LLLocalTextureObject(image, textureid);
+ mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
+ createLayers(te, avatarp);
}
return LLWearable::SUCCESS;
}
-void LLWearable::setType(LLWearableType::EType type)
+void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp)
{
mType = type;
- createVisualParams();
+ createVisualParams(avatarp);
}
@@ -442,6 +512,26 @@ void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload
}
}
+void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
+{
+ if (!avatarp) return;
+
+ // Pull params
+ for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
+ {
+ // cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't 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.
+ if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
+ {
+ S32 param_id = param->getID();
+ F32 weight = getVisualParamWeight(param_id);
+
+ avatarp->setVisualParamWeight( param_id, weight, FALSE );
+ }
+ }
+}
+
+
std::string terse_F32_to_string(F32 f)
{
std::string r = llformat("%.2f", f);
diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h
index e1cd26bdef..b8bbf82a6e 100644
--- a/indra/llappearance/llwearable.h
+++ b/indra/llappearance/llwearable.h
@@ -37,6 +37,7 @@ class LLMD5;
class LLVisualParam;
class LLTexGlobalColorInfo;
class LLTexGlobalColor;
+class LLAvatarAppearance;
// Abstract class.
class LLWearable
@@ -52,7 +53,7 @@ public:
//--------------------------------------------------------------------
public:
LLWearableType::EType getType() const { return mType; }
- void setType(LLWearableType::EType type);
+ void setType(LLWearableType::EType type, LLAvatarAppearance *avatarp);
const std::string& getName() const { return mName; }
void setName(const std::string& name) { mName = name; }
const std::string& getDescription() const { return mDescription; }
@@ -70,7 +71,7 @@ public:
public:
typedef std::vector<LLVisualParam*> visual_param_vec_t;
- virtual void writeToAvatar() = 0;
+ virtual void writeToAvatar(LLAvatarAppearance* avatarp);
enum EImportResult
{
@@ -79,7 +80,7 @@ public:
BAD_HEADER
};
virtual BOOL exportFile(LLFILE* file) const;
- virtual EImportResult importFile(LLFILE* file);
+ virtual EImportResult importFile(LLFILE* file, LLAvatarAppearance* avatarp);
@@ -96,9 +97,6 @@ public:
LLColor4 getClothesColor(S32 te) const;
void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
- typedef std::map<S32, LLUUID> texture_id_map_t;
- const texture_id_map_t& getTextureIDMap() const { return mTextureIDMap; }
-
// Something happened that requires the wearable to be updated (e.g. worn/unworn).
virtual void setUpdated() const = 0;
@@ -106,7 +104,8 @@ public:
virtual void addToBakedTextureHash(LLMD5& hash) const = 0;
protected:
- virtual void createVisualParams() = 0;
+ void createVisualParams(LLAvatarAppearance *avatarp);
+ void createLayers(S32 te, LLAvatarAppearance *avatarp);
static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml.
S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created.
@@ -122,8 +121,9 @@ protected:
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
visual_param_index_map_t mVisualParamIndexMap;
- // *TODO: Lazy mutable. Find a better way?
- mutable texture_id_map_t mTextureIDMap;
+ typedef std::map<S32, LLLocalTextureObject*> te_map_t;
+ te_map_t mTEMap; // maps TE to LocalTextureObject
+ te_map_t mSavedTEMap; // last saved version of TEMap
};
#endif // LL_LLWEARABLE_H