void LLWearable::createVisualParams() { LLVOAvatar* avatar = gAgent.getAvatarObject(); for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam()) { if (param->getWearableType() == mType) { 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*(LLVOAvatarSelf::*avatar_function)(S32)const = &LLVOAvatarSelf::getVisualParam; param->resetDrivenParams(); if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false)) { if( !param->linkDrivenParams(boost::bind(avatar_function,(LLVOAvatarSelf*)avatar,_1 ), true)) { llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl; continue; } } } }
// Avatar parameter and texture definitions can change over time. // This function returns true if parameters or textures have been added or removed // since this wearable was created. BOOL LLWearable::isOldVersion() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return FALSE; } if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion ) { llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl; llassert(0); } if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion ) { return TRUE; } S32 param_count = 0; for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { if (param->getWearableType() == mType && param->isTweakable()) { param_count++; if( !is_in_map(mVisualParamMap, param->getID() ) ) { return TRUE; } } } if( param_count != mVisualParamMap.size() ) { return TRUE; } S32 te_count = 0; for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType ) { te_count++; if( !is_in_map(mTEMap, te ) ) { return TRUE; } } } if( te_count != mTEMap.size() ) { return TRUE; } return FALSE; }
// Avatar parameter and texture definitions can change over time. // This function returns true if parameters or textures have been added or removed // since this wearable was created. BOOL LLWearable::isOldVersion() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return FALSE; } if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion ) { llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl; llassert(0); } if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion ) { return TRUE; } S32 param_count = 0; for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { param_count++; if( !is_in_map(mVisualParamMap, param->getID() ) ) { return TRUE; } } } if( param_count != mVisualParamMap.size() ) { return TRUE; } S32 te_count = 0; for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) { if( LLVOAvatar::getTEWearableType( te ) == mType ) { te_count++; if( !is_in_map(mTEMap, te ) ) { return TRUE; } } } if( te_count != mTEMap.size() ) { return TRUE; } return FALSE; }
// Avatar parameter and texture definitions can change over time. // * If parameters or textures have been REMOVED since the wearable was created, // they're just ignored, so we consider the wearable clean even though isOldVersion() // will return true. // * If parameters or textures have been ADDED since the wearable was created, // they are taken to have default values, so we consider the wearable clean // only if those values are the same as the defaults. BOOL LLWearable::isDirty() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return FALSE; } for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { if (param->getWearableType() == mType && param->isTweakable()) { F32 weight = get_if_there(mVisualParamMap, param->getID(), param->getDefaultWeight()); weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); U8 a = F32_to_U8( param->getWeight(), param->getMinWeight(), param->getMaxWeight() ); U8 b = F32_to_U8( weight, param->getMinWeight(), param->getMaxWeight() ); if( a != b ) { return TRUE; } } } for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType ) { LLViewerImage* avatar_image = avatar->getTEImage( te ); if( !avatar_image ) { llassert( 0 ); continue; } const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) ); if( avatar_image->getID() != image_id ) { return TRUE; } } } //if( gFloaterCustomize ) //{ // if( mDescription != gFloaterCustomize->getWearableDescription( mType ) ) // { // return TRUE; // } //} return FALSE; }
// Updates asset from the user's avatar void LLWearable::readFromAvatar() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if (((LLViewerVisualParam*)param)->getWearableType() == mType && param->isTweakable()) { //pretty sure is right if(param->getID() == 507) avatar->setActualBoobGrav(param->getWeight()); if(param->getID() == 151) avatar->setActualButtGrav(param->getWeight()); if(param->getID() == 157) avatar->setActualFatGrav(param->getWeight()); //if(param->getID() == 507) //{ // llwarns << "current = " << avatar->getActualBoobGrav() << llendl; // llwarns << "param weight = " << param->getWeight() << llendl; //} mVisualParamMap[param->getID()] = param->getWeight(); } } mTEMap.clear(); for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType ) { LLViewerImage* image = avatar->getTEImage( te ); if( image ) { mTEMap[te] = image->getID(); } } } //if( gFloaterCustomize ) //{ // mDescription = gFloaterCustomize->getWearableDescription( mType ); //} }
// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values. // static void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user ) { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } // You can't just remove body parts. if( (type == WT_SHAPE) || (type == WT_SKIN) || (type == WT_HAIR) || (type == WT_EYES) ) { return; } // Pull params for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if (((LLViewerVisualParam*)param)->getWearableType() == type && param->isTweakable()) { S32 param_id = param->getID(); avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user ); } } // Pull textures LLViewerImage* image = gImageList.getImage( IMG_DEFAULT_AVATAR ); for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == type ) { avatar->setLocTexTE( te, image, set_by_user ); } } if( gFloaterCustomize ) { gFloaterCustomize->setWearable(type, NULL, PERM_ALL, TRUE); } avatar->updateVisualParams(); avatar->updateMeshTextures(); // if( set_by_user ) // { // gAgent.sendAgentSetAppearance(); // } }
void LLWearable::setParamsToDefaults() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE); } } }
void LLWearable::setParamsToDefaults() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if (((LLViewerVisualParam*)param)->getWearableType() == mType && param->isTweakable()) { mVisualParamMap[param->getID()] = param->getDefaultWeight(); } } }
// Does not copy mAssetID. // Definition version is current: removes obsolete enties and creates default values for new ones. void LLWearable::copyDataFrom( LLWearable* src ) { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; mName = src->mName; mDescription = src->mDescription; mPermissions = src->mPermissions; mSaleInfo = src->mSaleInfo; mType = src->mType; // Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed) for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { if( (param->getWearableType() == mType) && (param->isTweakable() ) ) { S32 id = param->getID(); F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() ); if(id == 507) avatar->setActualBoobGrav(weight); mVisualParamMap[id] = weight; } } // 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( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType ) { const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) ); mTEMap[te] = image_id; } } }
void LLWearable::pullCrossWearableValues() { // scan through all of the avatar's visual parameters LLVOAvatar* avatar = gAgent.getAvatarObject(); for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam()) { if( param ) { LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param); if(driver_param) { // parameter is a driver parameter, have it update its driver_param->updateCrossDrivenParams(getType()); } } } }
// Updates asset from the user's avatar void LLWearable::readFromAvatar() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if (((LLViewerVisualParam*)param)->getWearableType() == mType && param->isTweakable()) { mVisualParamMap[param->getID()] = param->getWeight(); } } mTEMap.clear(); for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType ) { LLViewerImage* image = avatar->getTEImage( te ); if( image ) { mTEMap[te] = image->getID(); } } } //if( gFloaterCustomize ) //{ // mDescription = gFloaterCustomize->getWearableDescription( mType ); //} }
// Updates asset from the user's avatar void LLWearable::readFromAvatar() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { mVisualParamMap[param->getID()] = param->getWeight(); } } mTEMap.clear(); for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) { if( LLVOAvatar::getTEWearableType( te ) == mType ) { LLViewerImage* image = avatar->getTEImage( te ); if( image ) { mTEMap[te] = image->getID(); } } } //if( gFloaterCustomize ) //{ // mDescription = gFloaterCustomize->getWearableDescription( mType ); //} }
// Updates the user's avatar's appearance void LLWearable::writeToAvatar( BOOL set_by_user ) { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } ESex old_sex = avatar->getSex(); // Pull params for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if (((LLViewerVisualParam*)param)->getWearableType() == mType && param->isTweakable()) { S32 param_id = param->getID(); F32 weight = get_if_there(mVisualParamMap, param_id, param->getDefaultWeight()); // only animate with user-originated changes if (set_by_user) { param->setAnimationTarget(weight, set_by_user); } else { avatar->setVisualParamWeight( param_id, weight, set_by_user ); } } } // only interpolate with user-originated changes if (set_by_user) { avatar->startAppearanceAnimation(TRUE, TRUE); } // Pull texture entries for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType ) { const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) ); LLViewerImage* image = gImageList.getImage( image_id ); avatar->setLocTexTE( te, image, set_by_user ); } } avatar->updateVisualParams(); if( gFloaterCustomize ) { LLViewerInventoryItem* item; item = (LLViewerInventoryItem*)gInventory.getItem(gAgent.getWearableItem(mType)); U32 perm_mask = PERM_NONE; BOOL is_complete = FALSE; if(item) { perm_mask = item->getPermissions().getMaskOwner(); is_complete = item->isComplete(); if(!is_complete) { item->fetchFromServer(); } } gFloaterCustomize->setWearable(mType, this, perm_mask, is_complete); LLFloaterCustomize::setCurrentWearableType( mType ); } ESex new_sex = avatar->getSex(); if( old_sex != new_sex ) { avatar->updateSexDependentLayerSets( set_by_user ); } avatar->updateMeshTextures(); // if( set_by_user ) // { // gAgent.sendAgentSetAppearance(); // } }
// Does not copy mAssetID. // Definition version is current: removes obsolete enties and creates default values for new ones. void LLWearable::copyDataFrom( LLWearable* src ) { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return; } mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; mName = src->mName; mDescription = src->mDescription; mPermissions = src->mPermissions; mSaleInfo = src->mSaleInfo; mType = src->mType; // Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed) for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { S32 id = param->getID(); F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() ); //llwarns << "------------------------------" << llendl; //llwarns << "copydatafrom" << llendl; //llwarns << "------------------------------" << llendl; //if(id == 507) //{ // llwarns << "weight = " << weight << llendl; // llwarns << "actual = " << avatar->getActualBoobGrav() << llendl; // llwarns << "mVisualParamMap[id] = " << mVisualParamMap[id] << llendl; //} //pretty sure right if(id == 507) avatar->setActualBoobGrav(weight); /*if(id == 795) avatar->setActualButtGrav(weight); if(id == 157) avatar->setActualFatGrav(weight); */ mVisualParamMap[id] = weight; } } // 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( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType ) { const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) ); mTEMap[te] = image_id; } } }
// Avatar parameter and texture definitions can change over time. // * If parameters or textures have been REMOVED since the wearable was created, // they're just ignored, so we consider the wearable clean even though isOldVersion() // will return true. // * If parameters or textures have been ADDED since the wearable was created, // they are taken to have default values, so we consider the wearable clean // only if those values are the same as the defaults. BOOL LLWearable::isDirty() { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return FALSE; } for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { if (param->getWearableType() == mType && param->isTweakable()) { F32 weight = get_if_there(mVisualParamMap, param->getID(), param->getDefaultWeight()); weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); U8 a = F32_to_U8( param->getWeight(), param->getMinWeight(), param->getMaxWeight() ); if(avatar->getAppearanceFlag() == true) { //boob if(param->getID() == 507) { weight = get_if_there(mVisualParamMap, param->getID(), avatar->getActualBoobGrav()); weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); } //butt if(param->getID() == 795) { weight = get_if_there(mVisualParamMap, param->getID(), avatar->getActualButtGrav()); weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); } //fat if(param->getID() == 157) { weight = get_if_there(mVisualParamMap, param->getID(), avatar->getActualFatGrav()); weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); } } else { //boob if(param->getID() == 507) { a = F32_to_U8( avatar->getActualBoobGrav(), param->getMinWeight(), param->getMaxWeight() ); } //butt if(param->getID() == 795) { a = F32_to_U8( avatar->getActualButtGrav(), param->getMinWeight(), param->getMaxWeight() ); } //fat if(param->getID() == 157) { a = F32_to_U8( avatar->getActualFatGrav(), param->getMinWeight(), param->getMaxWeight() ); } } U8 b = F32_to_U8( weight, param->getMinWeight(), param->getMaxWeight() ); if( a != b ) { llwarns << "param ID " << param->getID() << " was changed." << llendl; return TRUE; } } } for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if( LLVOAvatar::getTEWearableType((ETextureIndex) te ) == mType ) { LLViewerImage* avatar_image = avatar->getTEImage( te ); if( !avatar_image ) { llassert( 0 ); continue; } const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID((ETextureIndex) te ) ); if( avatar_image->getID() != image_id ) { return TRUE; } } } //if( gFloaterCustomize ) //{ // if( mDescription != gFloaterCustomize->getWearableDescription( mType ) ) // { // return TRUE; // } //} return FALSE; }
// Creates new parameters for the given wearable and applies them to the avatar. void LLGenePool::spawn( EWearableType type ) { LLVOAvatar* avatar = gAgent.getAvatarObject(); if( !avatar ) { return; } if( !mLoaded ) { if( !load() ) { return; } } if( mArchetypes.count() < 1 ) { return; } // Only consider archetypes that have the same sex as you have already. LLVisualParam* male_param = avatar->getVisualParam( "male" ); if (!male_param) { llwarns << "The hard coded \'male\' parameter passed to avatar->getVisualParam() in LLGenePool::spawn() is no longer valid." << llendl; return; } S32 male_param_id = male_param->getID(); F32 sex_weight = male_param->getWeight(); S32 i = 0; S32 j = 0; S32 k = 0; const S32 MAX_CYCLES = 1000; S32 cycles = 0; F32 cur_sex_weight = 0.f; do { i = rand() % mArchetypes.count(); cur_sex_weight = mArchetypes[i]->getParam(male_param_id, 0.f); cycles++; if (cur_sex_weight != sex_weight) { break; } } while((cycles < MAX_CYCLES)); if( cycles >= MAX_CYCLES ) { return; } LLAppearance* arch1 = mArchetypes[i]; LLAppearance* arch2 = NULL; LLAppearance* arch3 = NULL; if( mArchetypes.count() > 1 ) { cycles = 0; do { j = rand() % mArchetypes.count(); cur_sex_weight = mArchetypes[j]->getParam(male_param_id, 0.f); cycles++; } while( (cycles < MAX_CYCLES) && ( (i == j) || (cur_sex_weight != sex_weight) ) ); if( cycles >= MAX_CYCLES ) { return; } arch2 = mArchetypes[j]; } if( mArchetypes.count() > 2 ) { cycles = 0; do { k = rand() % mArchetypes.count(); cur_sex_weight = mArchetypes[k]->getParam(male_param_id, 0.f); cycles++; } while( (cycles < MAX_CYCLES) && ( (i == k) || (j == k) || (cur_sex_weight != sex_weight) ) ); if( cycles >= MAX_CYCLES ) { return; } arch3 = mArchetypes[k]; } // Lame generation of barycentric coordinates F32 b1 = F32( rand() ) / RAND_MAX; F32 b2 = (F32( rand() ) / RAND_MAX) * (1.f - b1); F32 b3 = 1.f - b1 - b2; // ESex old_sex = avatar->getSex(); // Pull params for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) ) { S32 param_id = param->getID(); // don't try to blend male/female param...as fp innaccuracy will break the [0 | 1] semantics if (param_id != male_param_id) { F32 weight1 = arch1->getParam( param_id, param->getDefaultWeight() ); F32 net_weight = weight1; if( arch2 && arch3 ) { F32 weight2 = arch2->getParam( param_id, param->getDefaultWeight() ); F32 weight3 = arch3->getParam( param_id, param->getDefaultWeight() ); net_weight = b1 * weight1 + b2 * weight2 + b3 * weight3; } param->setAnimationTarget(net_weight, TRUE); } } } // Find the archetype with the greatest influence LLAppearance* dominant_arch = arch1; if( (b2 > b1) && (b2 > b3) ) { dominant_arch = arch2; } else if( (b3 > b1) && (b3 > b2) ) { dominant_arch = arch3; } // Pull Textures from the dominant archetype for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) { if( LLVOAvatar::isTextureIndexBaked( te ) ) { continue; } if( LLVOAvatar::getTEWearableType( te ) == type ) { LLUUID image_id = dominant_arch->getTexture( te ); if( image_id.isNull() ) { image_id = LLVOAvatar::getDefaultTEImageID( te ); } LLViewerImage* image = gImageList.getImage( image_id ); if( image ) { avatar->setLocTexTE( te, image, TRUE ); } } } // avatar->setVisualParamWeight( "male", sex_weight ); avatar->startAppearanceAnimation(TRUE, TRUE); avatar->updateVisualParams(); // ESex new_sex = avatar->getSex(); // if( old_sex != new_sex ) // { // avatar->updateSexDependentLayerSets( TRUE ); // } avatar->updateMeshTextures(); gAgent.sendAgentSetAppearance(); }
// Avatar parameter and texture definitions can change over time. // * If parameters or textures have been REMOVED since the wearable was created, // they're just ignored, so we consider the wearable clean even though isOldVersion() // will return true. // * If parameters or textures have been ADDED since the wearable was created, // they are taken to have default values, so we consider the wearable clean // only if those values are the same as the defaults. BOOL LLWearable::isDirty() const { LLVOAvatar* avatar = gAgent.getAvatarObject(); llassert( avatar ); if( !avatar ) { return FALSE; } for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam(); param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) && !param->getCrossWearable()) { F32 current_weight = getVisualParamWeight(param->getID()); current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() ); F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight()); saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() ); U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() ); U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() ); if( a != b ) { return TRUE; } } } for( S32 te = 0; te < TEX_NUM_INDICES; te++ ) { if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType) { te_map_t::const_iterator current_iter = mTEMap.find(te); if(current_iter != mTEMap.end()) { const LLUUID& current_image_id = current_iter->second->getID(); te_map_t::const_iterator saved_iter = mSavedTEMap.find(te); if(saved_iter != mSavedTEMap.end()) { const LLUUID& saved_image_id = saved_iter->second->getID(); if (saved_image_id != current_image_id) { // saved vs current images are different, wearable is dirty return TRUE; } } else { // image found in current image list but not saved image list return TRUE; } } } } //if( gFloaterCustomize ) //{ // if( mDescription != gFloaterCustomize->getWearableDescription( mType ) ) // { // return TRUE; // } //} return FALSE; }