Completed code migration from LLViewerWearable to LLWearable.

This commit is contained in:
Shyotl
2013-01-05 00:33:55 -06:00
parent bea4bc6a1a
commit 5cf091b8b2
16 changed files with 1252 additions and 1242 deletions

View File

@@ -40,7 +40,7 @@ set(llappearance_SOURCE_FILES
lltexlayer.cpp
lltexlayerparams.cpp
lltexturemanagerbridge.cpp
#llwearable.cpp
llwearable.cpp
llwearabledata.cpp
llwearabletype.cpp
llviewervisualparam.cpp

View File

@@ -1,7 +1,135 @@
#include "linden_common.h"
#include "llavatarappearance.h"
/**
* @File llavatarappearance.cpp
* @brief Implementation of LLAvatarAppearance class
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#if LL_MSVC
// disable warning about boost::lexical_cast returning uninitialized data
// when it fails to parse the string
#pragma warning (disable:4701)
#endif
#include "linden_common.h"
#include "llavatarappearance.h"
#include "llavatarappearancedefines.h"
#include "llavatarjointmesh.h"
#include "imageids.h"
#include "lldir.h"
#include "lldeleteutils.h"
#include "llpolymorph.h"
#include "llpolymesh.h"
#include "llpolyskeletaldistortion.h"
#include "llstl.h"
#include "lltexglobalcolor.h"
#include "llwearabledata.h"
#if LL_MSVC
// disable boost::lexical_cast warning
#pragma warning (disable:4702)
#endif
#include <boost/lexical_cast.hpp>
using namespace LLAvatarAppearanceDefines;
const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
//static
BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name )
{
switch( te )
{
case TEX_UPPER_SHIRT:
param_name[0] = 803; //"shirt_red";
param_name[1] = 804; //"shirt_green";
param_name[2] = 805; //"shirt_blue";
break;
case TEX_LOWER_PANTS:
param_name[0] = 806; //"pants_red";
param_name[1] = 807; //"pants_green";
param_name[2] = 808; //"pants_blue";
break;
case TEX_LOWER_SHOES:
param_name[0] = 812; //"shoes_red";
param_name[1] = 813; //"shoes_green";
param_name[2] = 817; //"shoes_blue";
break;
case TEX_LOWER_SOCKS:
param_name[0] = 818; //"socks_red";
param_name[1] = 819; //"socks_green";
param_name[2] = 820; //"socks_blue";
break;
case TEX_UPPER_JACKET:
case TEX_LOWER_JACKET:
param_name[0] = 834; //"jacket_red";
param_name[1] = 835; //"jacket_green";
param_name[2] = 836; //"jacket_blue";
break;
case TEX_UPPER_GLOVES:
param_name[0] = 827; //"gloves_red";
param_name[1] = 829; //"gloves_green";
param_name[2] = 830; //"gloves_blue";
break;
case TEX_UPPER_UNDERSHIRT:
param_name[0] = 821; //"undershirt_red";
param_name[1] = 822; //"undershirt_green";
param_name[2] = 823; //"undershirt_blue";
break;
case TEX_LOWER_UNDERPANTS:
param_name[0] = 824; //"underpants_red";
param_name[1] = 825; //"underpants_green";
param_name[2] = 826; //"underpants_blue";
break;
case TEX_SKIRT:
param_name[0] = 921; //"skirt_red";
param_name[1] = 922; //"skirt_green";
param_name[2] = 923; //"skirt_blue";
break;
case TEX_HEAD_TATTOO:
case TEX_LOWER_TATTOO:
case TEX_UPPER_TATTOO:
param_name[0] = 1071; //"tattoo_red";
param_name[1] = 1072; //"tattoo_green";
param_name[2] = 1073; //"tattoo_blue";
break;
default:
llassert(0);
return FALSE;
}
return TRUE;
}
// static
LLColor4 LLAvatarAppearance::getDummyColor()
{

View File

@@ -260,7 +260,7 @@ protected:
public:
virtual void setClothesColor(LLAvatarAppearanceDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake) = 0;
virtual LLColor4 getClothesColor(LLAvatarAppearanceDefines::ETextureIndex te) = 0;
//static BOOL teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name);
static BOOL teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name);
//--------------------------------------------------------------------
// Global colors
@@ -305,7 +305,7 @@ private:
** BAKED TEXTURES
**/
public:
//LLTexLayerSet* getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
virtual LLTexLayerSet* getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const = 0;
protected:
//virtual LLTexLayerSet* createTexLayerSet() = 0;

View File

@@ -0,0 +1,820 @@
/**
* @file llwearable.cpp
* @brief LLWearable class implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llavatarappearance.h"
#include "lllocaltextureobject.h"
#include "lltexlayer.h"
#include "lltexturemanagerbridge.h"
#include "llvisualparam.h"
#include "llavatarappearancedefines.h"
#include "llwearable.h"
using namespace LLAvatarAppearanceDefines;
// static
S32 LLWearable::sCurrentDefinitionVersion = 1;
// Private local functions
static std::string terse_F32_to_string(F32 f);
LLWearable::LLWearable() :
mDefinitionVersion(0),
mType(LLWearableType::WT_INVALID)
{
}
// virtual
LLWearable::~LLWearable()
{
}
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);
}
// reX: new function
BOOL LLWearable::FileExportParams( FILE* file ) const
{
// wearable type
S32 type = (S32)mType;
fprintf( file, "type %d\n", type );
// parameters
S32 num_parameters = mVisualParamIndexMap.size();
fprintf( file, "parameters %d\n", num_parameters );
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end(); ++iter)
{
S32 param_id = iter->first;
F32 param_weight = iter->second->getWeight();
fprintf( file, "%d %s\n", param_id, terse_F32_to_string(param_weight).c_str() );
}
return TRUE;
}
// reX: new function
BOOL LLWearable::FileExportTextures( FILE* file ) const
{
// wearable type
S32 type = (S32)mType;
fprintf( file, "type %d\n", type );
// texture entries
S32 num_textures = mTEMap.size();
fprintf( file, "textures %d\n", num_textures );
for (te_map_t::const_iterator iter = mTEMap.begin();
iter != mTEMap.end(); ++iter)
{
S32 te = iter->first;
fprintf( file, "%d %s\n", te, iter->second->getID().asString().c_str() );
}
return TRUE;
}
BOOL LLWearable::exportFile(LLFILE* fp) const
{
llofstream ofs(fp);
return 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.exportStream( output_stream ) )
{
return FALSE;
}
// sale info
if( !mSaleInfo.exportStream( 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();
iter != mVisualParamIndexMap.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(); iter != mTEMap.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();
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;
}
}
}
}
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;
}
}
LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp )
{
llifstream ifs(fp);
return importStream(ifs, avatarp);
}
// virtual
LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
{
// *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.
const U32 PARSE_BUFFER_SIZE = 2048;
char buffer[2048]; /* Flawfinder: ignore */
char uuid_buffer[37]; /* Flawfinder: ignore */
// This data is being generated on the viewer.
// Impose some sane limits on parameter and texture counts.
const S32 MAX_WEARABLE_ASSET_TEXTURES = 100;
const S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000;
if(!avatarp)
{
return LLWearable::FAILURE;
}
// read header and version
if (!input_stream.good())
{
llwarns << "Failed to read wearable asset input stream." << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
if ( 1 != sscanf( /* Flawfinder: ignore */
buffer,
"LLWearable version %d\n",
&mDefinitionVersion ) )
{
return LLWearable::BAD_HEADER;
}
// 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 > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
{
llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
return LLWearable::FAILURE;
}
// name
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading name" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
mName = buffer;
// description
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading description" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
mDescription = buffer;
// permissions
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading permissions" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 perm_version = -1;
if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) ||
perm_version != 0 )
{
llwarns << "Bad Wearable asset: missing valid permissions" << llendl;
return LLWearable::FAILURE;
}
if( !mPermissions.importStream( input_stream ) )
{
return LLWearable::FAILURE;
}
// sale info
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading sale info" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 sale_info_version = -1;
if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) ||
sale_info_version != 0 )
{
llwarns << "Bad Wearable asset: missing valid sale_info" << llendl;
return LLWearable::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.importStream(input_stream, has_perm_mask, perm_mask) )
{
return LLWearable::FAILURE;
}
if(has_perm_mask)
{
// fair use fix.
if(!(perm_mask & PERM_COPY))
{
perm_mask |= PERM_TRANSFER;
}
mPermissions.setMaskNext(perm_mask);
}
// wearable type
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading type" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 type = -1;
if ( 1 != sscanf( buffer, "type %d\n", &type ) )
{
llwarns << "Bad Wearable asset: bad type" << llendl;
return LLWearable::FAILURE;
}
if( 0 <= type && type < LLWearableType::WT_COUNT )
{
setType((LLWearableType::EType)type, avatarp);
}
else
{
mType = LLWearableType::WT_COUNT;
llwarns << "Bad Wearable asset: bad type #" << type << llendl;
return LLWearable::FAILURE;
}
// parameters header
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading parameters header" << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 num_parameters = -1;
if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) )
{
llwarns << "Bad Wearable asset: missing parameters block" << llendl;
return LLWearable::FAILURE;
}
if ( num_parameters > MAX_WEARABLE_ASSET_PARAMETERS )
{
llwarns << "Bad Wearable asset: too many parameters, "
<< num_parameters << llendl;
return LLWearable::FAILURE;
}
if( num_parameters != mVisualParamIndexMap.size() )
{
llwarns << "Wearable parameter mismatch. Reading in "
<< num_parameters << " from file, but created "
<< mVisualParamIndexMap.size()
<< " from avatar parameters. type: "
<< getType() << llendl;
}
// parameters
S32 i;
for( i = 0; i < num_parameters; i++ )
{
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading parameter #" << i << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 param_id = 0;
F32 param_weight = 0.f;
if ( 2 != sscanf( buffer, "%d %f\n", &param_id, &param_weight ) )
{
llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
return LLWearable::FAILURE;
}
mSavedVisualParamMap[param_id] = param_weight;
}
// textures header
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading textures header" << i << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 num_textures = -1;
if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) )
{
llwarns << "Bad Wearable asset: missing textures block" << llendl;
return LLWearable::FAILURE;
}
if ( num_textures > MAX_WEARABLE_ASSET_TEXTURES )
{
llwarns << "Bad Wearable asset: too many textures, "
<< num_textures << llendl;
return LLWearable::FAILURE;
}
// textures
for( i = 0; i < num_textures; i++ )
{
if (!input_stream.good())
{
llwarns << "Bad Wearable asset: early end of input stream "
<< "while reading textures #" << i << llendl;
return LLWearable::FAILURE;
}
input_stream.getline(buffer, PARSE_BUFFER_SIZE);
S32 te = 0;
if ( 2 != sscanf( /* Flawfinder: ignore */
buffer,
"%d %36s\n",
&te, uuid_buffer) )
{
llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
return LLWearable::FAILURE;
}
if( !LLUUID::validate( uuid_buffer ) )
{
llwarns << "Bad Wearable asset: bad texture uuid: "
<< uuid_buffer << llendl;
return LLWearable::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 LLWearable::SUCCESS;
}
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;
}
std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
{
std::vector<LLLocalTextureObject*> result;
for(te_map_t::const_iterator iter = mTEMap.begin();
iter != mTEMap.end(); iter++)
{
LLLocalTextureObject* lto = iter->second;
result.push_back(lto);
}
return result;
}
void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
{
if( mTEMap.find(index) != mTEMap.end() )
{
mTEMap.erase(index);
}
mTEMap[index] = new LLLocalTextureObject(lto);
}
void LLWearable::revertValues()
{
// FIXME DRANO - this triggers changes to driven params on avatar, potentially clobbering baked appearance.
//update saved settings so wearable is no longer dirty
// non-driver params first
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
{
S32 id = iter->first;
F32 value = iter->second;
LLVisualParam *param = getVisualParam(id);
if(param && !dynamic_cast<LLDriverParam*>(param) )
{
setVisualParamWeight(id, value, TRUE);
}
}
//then driver params
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
{
S32 id = iter->first;
F32 value = iter->second;
LLVisualParam *param = getVisualParam(id);
if(param && dynamic_cast<LLDriverParam*>(param) )
{
setVisualParamWeight(id, value, TRUE);
}
}
// make sure that saved values are sane
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.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(); iter != mVisualParamIndexMap.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 src (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's 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 defaults values for populating the destination image map.
image_id = getDefaultTextureImageID((ETextureIndex) te);
image = gTextureManagerBridgep->getFetchedTexture( image_id );
}
if( dst.find(te) != dst.end() )
{
// there's 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()
{
for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
{
LLLocalTextureObject *lto = iter->second;
delete lto;
}
mTEMap.clear();
for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
{
LLLocalTextureObject *lto = iter->second;
delete lto;
}
mSavedTEMap.clear();
}
void LLWearable::addVisualParam(LLVisualParam *param)
{
if( mVisualParamIndexMap[param->getID()] )
{
delete mVisualParamIndexMap[param->getID()];
}
param->setIsDummy(FALSE);
param->setParamLocation(LOC_WEARABLE);
mVisualParamIndexMap[param->getID()] = param;
mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
}
void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
{
if( is_in_map(mVisualParamIndexMap, param_index ) )
{
LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
wearable_param->setWeight(value, upload_bake);
}
else
{
llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
}
}
F32 LLWearable::getVisualParamWeight(S32 param_index) const
{
if( is_in_map(mVisualParamIndexMap, param_index ) )
{
const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
return wearable_param->getWeight();
}
else
{
llwarns << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
}
return (F32)-1.0;
}
LLVisualParam* LLWearable::getVisualParam(S32 index) const
{
visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
}
void LLWearable::getVisualParams(visual_param_vec_t &list)
{
visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
// add all visual params to the passed-in vector
for( ; 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();
iter != mVisualParamIndexMap.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() )
{
// 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);
S32 len = r.length();
// "1.20" -> "1.2"
// "24.00" -> "24."
while (len > 0 && ('0' == r[len - 1]))
{
r.erase(len-1, 1);
len--;
}
if ('.' == r[len - 1])
{
// "24." -> "24"
r.erase(len-1, 1);
}
else if (('-' == r[0]) && ('0' == r[1]))
{
// "-0.59" -> "-.59"
r.erase(1, 1);
}
else if ('0' == r[0])
{
// "0.59" -> ".59"
r.erase(0, 1);
}
return r;
}

View File

@@ -47,25 +47,99 @@ class LLWearable
// Constructors and destructors
//--------------------------------------------------------------------
public:
virtual ~LLWearable() {};
LLWearable();
virtual ~LLWearable();
//--------------------------------------------------------------------
// Accessors
//--------------------------------------------------------------------
public:
virtual LLWearableType::EType getType() const = 0;
virtual void writeToAvatar(LLAvatarAppearance* avatarp) = 0;
virtual LLLocalTextureObject* getLocalTextureObject(S32 index) = 0;
virtual const LLLocalTextureObject* getLocalTextureObject(S32 index) const = 0;
virtual void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake) = 0;
virtual F32 getVisualParamWeight(S32 index) const = 0;
virtual LLVisualParam* getVisualParam(S32 index) const = 0;
LLWearableType::EType getType() const { return mType; }
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; }
void setDescription(const std::string& desc) { mDescription = desc; }
const LLPermissions& getPermissions() const { return mPermissions; }
void setPermissions(const LLPermissions& p) { mPermissions = p; }
const LLSaleInfo& getSaleInfo() const { return mSaleInfo; }
void setSaleInfo(const LLSaleInfo& info) { mSaleInfo = info; }
const std::string& getTypeLabel() const;
const std::string& getTypeName() const;
LLAssetType::EType getAssetType() const;
S32 getDefinitionVersion() const { return mDefinitionVersion; }
void setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
static S32 getCurrentDefinitionVersion() { return LLWearable::sCurrentDefinitionVersion; }
public:
typedef std::vector<LLVisualParam*> visual_param_vec_t;
virtual void writeToAvatar(LLAvatarAppearance* avatarp);
BOOL FileExportParams(FILE* file) const;
BOOL FileExportTextures(FILE* file) const;
enum EImportResult
{
FAILURE = 0,
SUCCESS,
BAD_HEADER
};
BOOL exportFile(LLFILE* file) const;
EImportResult importFile(LLFILE* file, LLAvatarAppearance* avatarp );
virtual BOOL exportStream( std::ostream& output_stream ) const;
virtual EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
virtual const LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0;
LLLocalTextureObject* getLocalTextureObject(S32 index);
const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
std::vector<LLLocalTextureObject*> getLocalTextureListSeq();
void setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
void addVisualParam(LLVisualParam *param);
void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
F32 getVisualParamWeight(S32 index) const;
LLVisualParam* getVisualParam(S32 index) const;
void getVisualParams(visual_param_vec_t &list);
void animateParams(F32 delta, BOOL upload_bake);
LLColor4 getClothesColor(S32 te) const;
void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
virtual void revertValues();
virtual void saveValues();
// Something happened that requires the wearable to be updated (e.g. worn/unworn).
virtual void setUpdated() const = 0;
// Update the baked texture hash.
virtual void addToBakedTextureHash(LLMD5& hash) const = 0;
protected:
typedef std::map<S32, LLLocalTextureObject*> te_map_t;
void syncImages(te_map_t &src, te_map_t &dst);
void destroyTextures();
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.
std::string mName;
std::string mDescription;
LLPermissions mPermissions;
LLSaleInfo mSaleInfo;
LLWearableType::EType mType;
typedef std::map<S32, F32> param_map_t;
param_map_t mSavedVisualParamMap; // last saved version of visual params
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
visual_param_index_map_t mVisualParamIndexMap;
te_map_t mTEMap; // maps TE to LocalTextureObject
te_map_t mSavedTEMap; // last saved version of TEMap
};
#endif // LL_LLWEARABLE_H

View File

@@ -2,31 +2,25 @@
* @file llinventory.cpp
* @brief Implementation of the inventory system.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* 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
* Copyright (C) 2010, Linden Research, Inc.
*
* 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
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -845,7 +839,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
}
else if(0 == strcmp("permissions", keyword))
{
success = mPermissions.importLegacyStream(input_stream);
success = mPermissions.importStream(input_stream);
}
else if(0 == strcmp("sale_info", keyword))
{
@@ -855,7 +849,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
// should pick up the vast majority of the tasks.
BOOL has_perm_mask = FALSE;
U32 perm_mask = 0;
success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask);
success = mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask);
if(has_perm_mask)
{
if(perm_mask == PERM_NONE)
@@ -971,7 +965,7 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu
output_stream << "\t\titem_id\t" << uuid_str << "\n";
mParentUUID.toString(uuid_str);
output_stream << "\t\tparent_id\t" << uuid_str << "\n";
mPermissions.exportLegacyStream(output_stream);
mPermissions.exportStream(output_stream);
// Check for permissions to see the asset id, and if so write it
// out as an asset id. Otherwise, apply our cheesy encryption.
@@ -1005,7 +999,7 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu
std::string buffer;
buffer = llformat( "\t\tflags\t%08x\n", mFlags);
output_stream << buffer;
mSaleInfo.exportLegacyStream(output_stream);
mSaleInfo.exportStream(output_stream);
output_stream << "\t\tname\t" << mName.c_str() << "|\n";
output_stream << "\t\tdesc\t" << mDescription.c_str() << "|\n";
output_stream << "\t\tcreation_date\t" << mCreationDate << "\n";
@@ -1123,7 +1117,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd)
{
if (sd[w].isString())
{
mType = LLAssetType::lookup(sd[w].asString());
mType = LLAssetType::lookup(sd[w].asString().c_str());
}
else if (sd[w].isInteger())
{

View File

@@ -2,31 +2,25 @@
* @file llinventory.h
* @brief LLInventoryItem and LLInventoryCategory class declaration.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* 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
* Copyright (C) 2010, Linden Research, Inc.
*
* 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
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -3,31 +3,25 @@
* @author Phoenix
* @brief Permissions for objects and inventory.
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* 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
* Copyright (C) 2010, Linden Research, Inc.
*
* 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
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -578,143 +572,17 @@ void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 b
BOOL LLPermissions::importFile(LLFILE* fp)
{
init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
const S32 BUFSIZE = 16384;
// *NOTE: Changing the buffer size will require changing the scanf
// calls below.
char buffer[BUFSIZE]; /* Flawfinder: ignore */
char keyword[256]; /* Flawfinder: ignore */
char valuestr[256]; /* Flawfinder: ignore */
char uuid_str[256]; /* Flawfinder: ignore */
U32 mask;
keyword[0] = '\0';
valuestr[0] = '\0';
while (!feof(fp))
{
if (fgets(buffer, BUFSIZE, fp) == NULL)
{
buffer[0] = '\0';
}
sscanf( /* Flawfinder: ignore */
buffer,
" %255s %255s",
keyword, valuestr);
if (!strcmp("{", keyword))
{
continue;
}
if (!strcmp("}",keyword))
{
break;
}
else if (!strcmp("creator_mask", keyword))
{
// legacy support for "creator" masks
sscanf(valuestr, "%x", &mask);
mMaskBase = mask;
fixFairUse();
}
else if (!strcmp("base_mask", keyword))
{
sscanf(valuestr, "%x", &mask);
mMaskBase = mask;
//fixFairUse();
}
else if (!strcmp("owner_mask", keyword))
{
sscanf(valuestr, "%x", &mask);
mMaskOwner = mask;
}
else if (!strcmp("group_mask", keyword))
{
sscanf(valuestr, "%x", &mask);
mMaskGroup = mask;
}
else if (!strcmp("everyone_mask", keyword))
{
sscanf(valuestr, "%x", &mask);
mMaskEveryone = mask;
}
else if (!strcmp("next_owner_mask", keyword))
{
sscanf(valuestr, "%x", &mask);
mMaskNextOwner = mask;
}
else if (!strcmp("creator_id", keyword))
{
sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
mCreator.set(uuid_str);
}
else if (!strcmp("owner_id", keyword))
{
sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
mOwner.set(uuid_str);
}
else if (!strcmp("last_owner_id", keyword))
{
sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
mLastOwner.set(uuid_str);
}
else if (!strcmp("group_id", keyword))
{
sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
mGroup.set(uuid_str);
}
else if (!strcmp("group_owned", keyword))
{
sscanf(valuestr, "%d", &mask);
if(mask) mIsGroupOwned = true;
else mIsGroupOwned = false;
}
else
{
llinfos << "unknown keyword " << keyword << " in permissions import" << llendl;
}
}
fix();
return TRUE;
llifstream ifs(fp);
return importStream(ifs);
}
BOOL LLPermissions::exportFile(LLFILE* fp) const
{
std::string uuid_str;
fprintf(fp, "\tpermissions 0\n");
fprintf(fp, "\t{\n");
fprintf(fp, "\t\tbase_mask\t%08x\n", mMaskBase);
fprintf(fp, "\t\towner_mask\t%08x\n", mMaskOwner);
fprintf(fp, "\t\tgroup_mask\t%08x\n", mMaskGroup);
fprintf(fp, "\t\teveryone_mask\t%08x\n", mMaskEveryone);
fprintf(fp, "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner);
mCreator.toString(uuid_str);
fprintf(fp, "\t\tcreator_id\t%s\n", uuid_str.c_str());
mOwner.toString(uuid_str);
fprintf(fp, "\t\towner_id\t%s\n", uuid_str.c_str());
mLastOwner.toString(uuid_str);
fprintf(fp, "\t\tlast_owner_id\t%s\n", uuid_str.c_str());
mGroup.toString(uuid_str);
fprintf(fp, "\t\tgroup_id\t%s\n", uuid_str.c_str());
if(mIsGroupOwned)
{
fprintf(fp, "\t\tgroup_owned\t1\n");
}
fprintf(fp,"\t}\n");
return TRUE;
llofstream ofs(fp);
return exportStream(ofs);
}
BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
BOOL LLPermissions::importStream(std::istream& input_stream)
{
init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
const S32 BUFSIZE = 16384;
@@ -733,6 +601,18 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
while (input_stream.good())
{
input_stream.getline(buffer, BUFSIZE);
if (input_stream.eof())
{
llwarns << "Bad permissions: early end of input stream"
<< llendl;
return FALSE;
}
if (input_stream.fail())
{
llwarns << "Bad permissions: failed to read from input stream"
<< llendl;
return FALSE;
}
sscanf( /* Flawfinder: ignore */
buffer,
" %255s %255s",
@@ -806,7 +686,8 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
}
else
{
llinfos << "unknown keyword " << keyword << " in permissions import" << llendl;
llwarns << "unknown keyword " << keyword
<< " in permissions import" << llendl;
}
}
fix();
@@ -814,36 +695,26 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
}
BOOL LLPermissions::exportLegacyStream(std::ostream& output_stream) const
BOOL LLPermissions::exportStream(std::ostream& output_stream) const
{
std::string uuid_str;
if (!output_stream.good()) return FALSE;
output_stream << "\tpermissions 0\n";
output_stream << "\t{\n";
std::string buffer;
buffer = llformat( "\t\tbase_mask\t%08x\n", mMaskBase);
output_stream << buffer;
buffer = llformat( "\t\towner_mask\t%08x\n", mMaskOwner);
output_stream << buffer;
buffer = llformat( "\t\tgroup_mask\t%08x\n", mMaskGroup);
output_stream << buffer;
buffer = llformat( "\t\teveryone_mask\t%08x\n", mMaskEveryone);
output_stream << buffer;
buffer = llformat( "\t\tnext_owner_mask\t%08x\n", mMaskNextOwner);
output_stream << buffer;
char prev_fill = output_stream.fill('0');
output_stream << std::hex;
output_stream << "\t\tbase_mask\t" << std::setw(8) << mMaskBase << "\n";
output_stream << "\t\towner_mask\t" << std::setw(8) << mMaskOwner << "\n";
output_stream << "\t\tgroup_mask\t" << std::setw(8) << mMaskGroup << "\n";
output_stream << "\t\teveryone_mask\t" << std::setw(8) << mMaskEveryone << "\n";
output_stream << "\t\tnext_owner_mask\t" << std::setw(8) << mMaskNextOwner << "\n";
output_stream << std::dec;
output_stream.fill(prev_fill);
mCreator.toString(uuid_str);
output_stream << "\t\tcreator_id\t" << uuid_str << "\n";
mOwner.toString(uuid_str);
output_stream << "\t\towner_id\t" << uuid_str << "\n";
mLastOwner.toString(uuid_str);
output_stream << "\t\tlast_owner_id\t" << uuid_str << "\n";
mGroup.toString(uuid_str);
output_stream << "\t\tgroup_id\t" << uuid_str << "\n";
output_stream << "\t\tcreator_id\t" << mCreator << "\n";
output_stream << "\t\towner_id\t" << mOwner << "\n";
output_stream << "\t\tlast_owner_id\t" << mLastOwner << "\n";
output_stream << "\t\tgroup_id\t" << mGroup << "\n";
if(mIsGroupOwned)
{

View File

@@ -2,31 +2,25 @@
* @file llpermissions.h
* @brief Permissions structures for objects.
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* 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
* Copyright (C) 2010, Linden Research, Inc.
*
* 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
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -322,8 +316,8 @@ public:
BOOL importFile(LLFILE* fp);
BOOL exportFile(LLFILE* fp) const;
BOOL importLegacyStream(std::istream& input_stream);
BOOL exportLegacyStream(std::ostream& output_stream) const;
BOOL importStream(std::istream& input_stream);
BOOL exportStream(std::ostream& output_stream) const;
bool operator==(const LLPermissions &rhs) const;
bool operator!=(const LLPermissions &rhs) const;

View File

@@ -87,15 +87,13 @@ U32 LLSaleInfo::getCRC32() const
BOOL LLSaleInfo::exportFile(LLFILE* fp) const
{
fprintf(fp, "\tsale_info\t0\n\t{\n");
fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType));
fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice);
fprintf(fp,"\t}\n");
return TRUE;
llofstream ofs(fp);
return exportStream(ofs);
}
BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
BOOL LLSaleInfo::exportStream(std::ostream& output_stream) const
{
if (!output_stream.good()) return FALSE;
output_stream << "\tsale_info\t0\n\t{\n";
output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n";
output_stream << "\t\tsale_price\t" << mSalePrice << "\n";
@@ -140,80 +138,39 @@ bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)
BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)
{
has_perm_mask = FALSE;
// *NOTE: Changing the buffer size will require changing the scanf
// calls below.
char buffer[MAX_STRING]; /* Flawfinder: ignore */
char keyword[MAX_STRING]; /* Flawfinder: ignore */
char valuestr[MAX_STRING]; /* Flawfinder: ignore */
BOOL success = TRUE;
keyword[0] = '\0';
valuestr[0] = '\0';
while(success && (!feof(fp)))
{
if (fgets(buffer, MAX_STRING, fp) == NULL)
{
buffer[0] = '\0';
}
sscanf( /* Flawfinder: ignore */
buffer,
" %254s %254s",
keyword, valuestr);
if(!keyword[0])
{
continue;
}
if(0 == strcmp("{",keyword))
{
continue;
}
if(0 == strcmp("}", keyword))
{
break;
}
else if(0 == strcmp("sale_type", keyword))
{
mSaleType = lookup(valuestr);
}
else if(0 == strcmp("sale_price", keyword))
{
sscanf(valuestr, "%d", &mSalePrice);
mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
}
else if (!strcmp("perm_mask", keyword))
{
//llinfos << "found deprecated keyword perm_mask" << llendl;
has_perm_mask = TRUE;
sscanf(valuestr, "%x", &perm_mask);
}
else
{
llwarns << "unknown keyword '" << keyword
<< "' in sale info import" << llendl;
}
}
return success;
llifstream ifs(fp);
return importStream(ifs, has_perm_mask, perm_mask);
}
BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)
BOOL LLSaleInfo::importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)
{
has_perm_mask = FALSE;
const S32 BUFSIZE = 16384;
// *NOTE: Changing the buffer size will require changing the scanf
// calls below.
char buffer[MAX_STRING]; /* Flawfinder: ignore */
char keyword[MAX_STRING]; /* Flawfinder: ignore */
char valuestr[MAX_STRING]; /* Flawfinder: ignore */
BOOL success = TRUE;
char buffer[BUFSIZE]; /* Flawfinder: ignore */
char keyword[255]; /* Flawfinder: ignore */
char valuestr[255]; /* Flawfinder: ignore */
keyword[0] = '\0';
valuestr[0] = '\0';
while(success && input_stream.good())
while(input_stream.good())
{
input_stream.getline(buffer, MAX_STRING);
if (input_stream.eof())
{
llwarns << "Bad sale info: early end of input stream"
<< llendl;
return FALSE;
}
if (input_stream.fail())
{
llwarns << "Bad sale info: failed to read from input stream"
<< llendl;
return FALSE;
}
sscanf( /* Flawfinder: ignore */
buffer,
" %254s %254s",
@@ -251,7 +208,7 @@ BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_m
<< "' in sale info import" << llendl;
}
}
return success;
return TRUE;
}
void LLSaleInfo::setSalePrice(S32 price)

View File

@@ -95,11 +95,11 @@ public:
BOOL exportFile(LLFILE* fp) const;
BOOL importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask);
BOOL exportLegacyStream(std::ostream& output_stream) const;
BOOL exportStream(std::ostream& output_stream) const;
LLSD asLLSD() const;
operator LLSD() const { return asLLSD(); }
bool fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask);
BOOL importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask);
BOOL importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask);
LLSD packMessage() const;
void unpackMessage(LLSD sales);

View File

@@ -29,30 +29,19 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "lldictionary.h"
#include "llfloatercustomize.h"
#include "lllocaltextureobject.h"
#include "llnotificationsutil.h"
#include "llviewertexturelist.h"
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
#include "lltexlayer.h"
#include "lltexglobalcolor.h"
#include "lltrans.h"
#include "llviewerregion.h"
#include "llvisualparam.h"
#include "llvoavatar.h"
#include "lltextureentry.h"
#include "llviewertexlayer.h"
#include "llvoavatarself.h"
#include "llavatarappearancedefines.h"
#include "llviewerwearable.h"
#include "llviewercontrol.h"
#include "llviewertexlayer.h"
#include "llviewerregion.h"
#include "llinventoryobserver.h"
using namespace LLAvatarAppearanceDefines;
// static
S32 LLViewerWearable::sCurrentDefinitionVersion = 1;
// support class - remove for 2.1 (hackity hack hack)
class LLOverrideBakedTextureUpdate
{
@@ -80,22 +69,17 @@ private:
};
// Private local functions
static std::string terse_F32_to_string(F32 f);
static std::string asset_id_to_filename(const LLUUID &asset_id);
LLViewerWearable::LLViewerWearable(const LLTransactionID& transaction_id) :
LLWearable(),
mDefinitionVersion(LLViewerWearable::sCurrentDefinitionVersion),
mType(LLWearableType::WT_INVALID)
LLWearable()
{
mTransactionID = transaction_id;
mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
}
LLViewerWearable::LLViewerWearable(const LLAssetID& asset_id) :
LLWearable(),
mDefinitionVersion( LLViewerWearable::sCurrentDefinitionVersion ),
mType(LLWearableType::WT_INVALID)
LLWearable()
{
mAssetID = asset_id;
mTransactionID.setNull();
@@ -106,416 +90,47 @@ LLViewerWearable::~LLViewerWearable()
{
}
const std::string& LLViewerWearable::getTypeLabel() const
// virtual
LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
{
return LLWearableType::getTypeLabel(mType);
}
const std::string& LLViewerWearable::getTypeName() const
{
return LLWearableType::getTypeName(mType);
}
LLAssetType::EType LLViewerWearable::getAssetType() const
{
return LLWearableType::getAssetType(mType);
}
const LLUUID LLViewerWearable::getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
const std::string &default_image_name = texture_dict->mDefaultImageName;
if (default_image_name == "")
{
return IMG_DEFAULT_AVATAR;
}
else
{
return LLUUID(gSavedSettings.getString(default_image_name));
}
}
// reX: new function
BOOL LLViewerWearable::FileExportParams( FILE* file )
{
// wearable type
S32 type = (S32)mType;
fprintf( file, "type %d\n", type );
// parameters
S32 num_parameters = mVisualParamIndexMap.size();
fprintf( file, "parameters %d\n", num_parameters );
for (visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end(); ++iter)
{
S32 param_id = iter->first;
F32 param_weight = iter->second->getWeight();
fprintf( file, "%d %s\n", param_id, terse_F32_to_string(param_weight).c_str() );
}
return TRUE;
}
// reX: new function
BOOL LLViewerWearable::FileExportTextures( FILE* file )
{
// wearable type
S32 type = (S32)mType;
fprintf( file, "type %d\n", type );
// texture entries
S32 num_textures = mTEMap.size();
fprintf( file, "textures %d\n", num_textures );
for (te_map_t::iterator iter = mTEMap.begin();
iter != mTEMap.end(); ++iter)
{
S32 te = iter->first;
fprintf( file, "%d %s\n", te, iter->second->getID().asString().c_str() );
}
return TRUE;
}
BOOL LLViewerWearable::exportFile(LLFILE* file) const
{
// header and version
if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
{
return FALSE;
}
// name
if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
{
return FALSE;
}
// description
if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
{
return FALSE;
}
// permissions
if( !mPermissions.exportFile( file ) )
{
return FALSE;
}
// sale info
if( !mSaleInfo.exportFile( file ) )
{
return FALSE;
}
// wearable type
S32 type = (S32)mType;
if( fprintf( file, "type %d\n", type ) < 0 )
{
return FALSE;
}
// parameters
S32 num_parameters = mVisualParamIndexMap.size();
if( fprintf( file, "parameters %d\n", num_parameters ) < 0 )
{
return FALSE;
}
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end();
++iter)
{
S32 param_id = iter->first;
const LLVisualParam* param = iter->second;
F32 param_weight = param->getWeight();
if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 )
{
return FALSE;
}
}
// texture entries
S32 num_textures = mTEMap.size();
if( fprintf( file, "textures %d\n", num_textures ) < 0 )
{
return FALSE;
}
for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
{
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 LLViewerWearable::createVisualParams()
{
for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
param;
param = (LLViewerVisualParam*) gAgentAvatarp->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();
param_iter != mVisualParamIndexMap.end();
++param_iter)
{
LLVisualParam* param = param_iter->second;
LLVisualParam*(LLViewerWearable::*wearable_function)(S32)const = &LLViewerWearable::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,(LLViewerWearable*)this, _1), false))
{
if( !param->linkDrivenParams(boost::bind(avatar_function,gAgentAvatarp.get(),_1 ), true))
{
llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
continue;
}
}
}
}
BOOL LLViewerWearable::importFile( LLFILE* file )
{
// *NOTE: changing the type or size of this buffer will require
// changes in the fscanf() code below. You would be better off
// rewriting this to use streams and not require an open FILE.
char text_buffer[2048]; /* Flawfinder: ignore */
S32 fields_read = 0;
// suppress texlayerset updates while wearables are being imported. Layersets will be updated
// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
LLOverrideBakedTextureUpdate stop_bakes(false);
// read header and version
fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
if( fields_read != 1 )
LLWearable::EImportResult result = LLWearable::importStream(input_stream, avatarp);
if (LLWearable::FAILURE == result) return result;
if (LLWearable::BAD_HEADER == result)
{
// Shouldn't really log the asset id for security reasons, but
// we need it in this case.
llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
//gVFS->dumpMap();
return FALSE;
return result;
}
LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
// Temoprary 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 > LLViewerWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
te_map_t::const_iterator iter = mTEMap.begin();
te_map_t::const_iterator end = mTEMap.end();
for (; iter != end; ++iter)
{
llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLViewerWearable::sCurrentDefinitionVersion << ")" << llendl;
return FALSE;
}
// name
int next_char = fgetc( file ); /* Flawfinder: ignore */
if( '\n' == next_char )
{
// no name
mName = "";
}
else
{
ungetc( next_char, file );
fields_read = fscanf( /* Flawfinder: ignore */
file,
"%2047[^\n]",
text_buffer);
if( (1 != fields_read) || (fgetc( file ) != '\n') ) /* Flawfinder: ignore */
S32 te = iter->first;
LLLocalTextureObject* lto = iter->second;
LLUUID textureid = LLUUID::null;
if (lto)
{
llwarns << "Bad Wearable asset: early end of file" << llendl;
return FALSE;
}
mName = text_buffer;
LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
}
// description
next_char = fgetc( file ); /* Flawfinder: ignore */
if( '\n' == next_char )
{
// no description
mDescription = "";
}
else
{
ungetc( next_char, file );
fields_read = fscanf( /* Flawfinder: ignore */
file,
"%2047[^\n]",
text_buffer );
if( (1 != fields_read) || (fgetc( file ) != '\n') ) /* Flawfinder: ignore */
{
llwarns << "Bad Wearable asset: early end of file" << llendl;
return FALSE;
}
mDescription = text_buffer;
LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
}
// permissions
S32 perm_version;
fields_read = fscanf( file, " permissions %d\n", &perm_version );
if( (fields_read != 1) || (perm_version != 0) )
{
llwarns << "Bad Wearable asset: missing permissions" << llendl;
return FALSE;
}
if( !mPermissions.importFile( file ) )
{
return FALSE;
}
// sale info
S32 sale_info_version;
fields_read = fscanf( file, " sale_info %d\n", &sale_info_version );
if( (fields_read != 1) || (sale_info_version != 0) )
{
llwarns << "Bad Wearable asset: missing sale_info" << llendl;
return FALSE;
}
// 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.importFile(file, has_perm_mask, perm_mask) )
{
return FALSE;
}
if(has_perm_mask)
{
// fair use fix.
if(!(perm_mask & PERM_COPY))
{
perm_mask |= PERM_TRANSFER;
}
mPermissions.setMaskNext(perm_mask);
}
// wearable type
S32 type = -1;
fields_read = fscanf( file, "type %d\n", &type );
if( fields_read != 1 )
{
llwarns << "Bad Wearable asset: bad type" << llendl;
return FALSE;
}
if( 0 <= type && type < LLWearableType::WT_COUNT )
{
setType((LLWearableType::EType)type);
}
else
{
mType = LLWearableType::WT_COUNT;
llwarns << "Bad Wearable asset: bad type #" << type << llendl;
return FALSE;
}
// parameters header
S32 num_parameters = 0;
fields_read = fscanf( file, "parameters %d\n", &num_parameters );
if( fields_read != 1 )
{
llwarns << "Bad Wearable asset: missing parameters block" << llendl;
return FALSE;
}
if( num_parameters != mVisualParamIndexMap.size() )
{
llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " << mType << llendl;
}
// parameters
S32 i;
for( i = 0; i < num_parameters; i++ )
{
S32 param_id = 0;
F32 param_weight = 0.f;
fields_read = fscanf( file, "%d %f\n", &param_id, &param_weight );
if( fields_read != 2 )
{
llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
return FALSE;
}
mSavedVisualParamMap[param_id] = param_weight;
}
// textures header
S32 num_textures = 0;
fields_read = fscanf( file, "textures %d\n", &num_textures);
if( fields_read != 1 )
{
llwarns << "Bad Wearable asset: missing textures block" << llendl;
return FALSE;
}
// textures
for( i = 0; i < num_textures; i++ )
{
S32 te = 0;
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 FALSE;
}
if( !LLUUID::validate( text_buffer ) )
{
llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
return FALSE;
}
LLUUID id = LLUUID(text_buffer);
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( id );
if( mTEMap.find(te) != mTEMap.end() )
{
delete mTEMap[te];
}
if( mSavedTEMap.find(te) != mSavedTEMap.end() )
{
delete mSavedTEMap[te];
textureid = lto->getID();
}
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( textureid );
if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
{
image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLAvatarAppearanceDefines::ETextureIndex)te), NULL);
image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(textureid, (LLAvatarAppearanceDefines::ETextureIndex)te), NULL);
}
LLUUID textureid(text_buffer);
mTEMap[te] = new LLLocalTextureObject(image, textureid);
mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
createLayers(te);
}
// copy all saved param values to working params
revertValues();
return TRUE;
return result;
}
@@ -526,13 +141,13 @@ BOOL LLViewerWearable::isOldVersion() const
{
if (!isAgentAvatarValid()) return FALSE;
if( LLViewerWearable::sCurrentDefinitionVersion < mDefinitionVersion )
if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
{
llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLViewerWearable::sCurrentDefinitionVersion << ")" << llendl;
llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
llassert(0);
}
if( LLViewerWearable::sCurrentDefinitionVersion != mDefinitionVersion )
if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
{
return TRUE;
}
@@ -667,7 +282,7 @@ void LLViewerWearable::setTexturesToDefaults()
if( mTEMap.find(te) == mTEMap.end() )
{
mTEMap[te] = new LLLocalTextureObject(image, id);
createLayers(te);
createLayers(te, gAgentAvatarp);
}
else
{
@@ -680,6 +295,23 @@ void LLViewerWearable::setTexturesToDefaults()
}
}
// virtual
const LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
const std::string &default_image_name = texture_dict->mDefaultImageName;
if (default_image_name == "")
{
return IMG_DEFAULT_AVATAR;
}
else
{
return LLUUID(gSavedSettings.getString(default_image_name));
}
}
// Updates the user's avatar's appearance
//virtual
void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp)
@@ -692,19 +324,8 @@ void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp)
ESex old_sex = avatarp->getSex();
// Pull params
for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->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);
LLWearable::writeToAvatar(avatarp);
gAgentAvatarp->setVisualParamWeight( param_id, weight, FALSE );
}
}
// Pull texture entries
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
@@ -780,14 +401,14 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
{
if (!isAgentAvatarValid()) return;
mDefinitionVersion = LLViewerWearable::sCurrentDefinitionVersion;
mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
mName = src->mName;
mDescription = src->mDescription;
mPermissions = src->mPermissions;
mSaleInfo = src->mSaleInfo;
setType(src->mType);
setType(src->mType, gAgentAvatarp);
mSavedVisualParamMap.clear();
// Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
@@ -828,7 +449,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
mTEMap[te] = new LLLocalTextureObject(image, image_id);
mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
}
createLayers(te);
createLayers(te, gAgentAvatarp);
}
}
@@ -842,195 +463,9 @@ void LLViewerWearable::setItemID(const LLUUID& item_id)
mItemID = item_id;
}
const LLUUID& LLViewerWearable::getItemID() const
{
return mItemID;
}
void LLViewerWearable::setType(LLWearableType::EType type)
{
mType = type;
createVisualParams();
}
LLLocalTextureObject* LLViewerWearable::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* LLViewerWearable::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 LLViewerWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
{
if( mTEMap.find(index) != mTEMap.end() )
{
mTEMap.erase(index);
}
mTEMap[index] = new LLLocalTextureObject(lto);
}
void LLViewerWearable::addVisualParam(LLVisualParam *param)
{
if( mVisualParamIndexMap[param->getID()] )
{
delete mVisualParamIndexMap[param->getID()];
}
param->setIsDummy(FALSE);
param->setParamLocation(LOC_WEARABLE);
mVisualParamIndexMap[param->getID()] = param;
mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
}
void LLViewerWearable::setVisualParams()
{
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
{
S32 id = iter->first;
LLVisualParam *wearable_param = iter->second;
F32 value = wearable_param->getWeight();
gAgentAvatarp->setVisualParamWeight(id, value, FALSE);
}
}
void LLViewerWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
{
if( is_in_map(mVisualParamIndexMap, param_index ) )
{
LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
wearable_param->setWeight(value, upload_bake);
}
else
{
llerrs << "LLViewerWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
}
}
F32 LLViewerWearable::getVisualParamWeight(S32 param_index) const
{
if( is_in_map(mVisualParamIndexMap, param_index ) )
{
const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
return wearable_param->getWeight();
}
else
{
llwarns << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
}
return (F32)-1.0;
}
LLVisualParam* LLViewerWearable::getVisualParam(S32 index) const
{
visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
}
void LLViewerWearable::getVisualParams(visual_param_vec_t &list)
{
visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
// add all visual params to the passed-in vector
for( ; iter != end; ++iter )
{
list.push_back(iter->second);
}
}
void LLViewerWearable::animateParams(F32 delta, BOOL upload_bake)
{
for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
iter != mVisualParamIndexMap.end();
++iter)
{
LLVisualParam *param = (LLVisualParam*) iter->second;
param->animate(delta, upload_bake);
}
}
LLColor4 LLViewerWearable::getClothesColor(S32 te) const
{
LLColor4 color;
U32 param_name[3];
if( LLVOAvatar::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
{
for( U8 index = 0; index < 3; index++ )
{
color.mV[index] = getVisualParamWeight(param_name[index]);
}
}
return color;
}
void LLViewerWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
{
U32 param_name[3];
if( LLVOAvatar::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
{
for( U8 index = 0; index < 3; index++ )
{
setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
}
}
}
void LLViewerWearable::revertValues()
{
//update saved settings so wearable is no longer dirty
// non-driver params first
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
{
S32 id = iter->first;
F32 value = iter->second;
LLVisualParam *param = getVisualParam(id);
if(param && !dynamic_cast<LLDriverParam*>(param) )
{
setVisualParamWeight(id, value, TRUE);
}
}
//then driver params
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
{
S32 id = iter->first;
F32 value = iter->second;
LLVisualParam *param = getVisualParam(id);
if(param && dynamic_cast<LLDriverParam*>(param) )
{
setVisualParamWeight(id, value, TRUE);
}
}
// make sure that saved values are sane
for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
{
S32 id = iter->first;
LLVisualParam *param = getVisualParam(id);
if( param )
{
mSavedVisualParamMap[id] = param->getWeight();
}
}
syncImages(mSavedTEMap, mTEMap);
LLWearable::revertValues();
/*LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
@@ -1043,39 +478,9 @@ void LLViewerWearable::revertValues()
}
BOOL LLViewerWearable::isOnTop() const
{
return (this == gAgentWearables.getTopWearable(mType));
}
void LLViewerWearable::createLayers(S32 te)
{
LLViewerTexLayerSet *layer_set = dynamic_cast<LLViewerTexLayerSet*>(gAgentAvatarp->getLayerSet((ETextureIndex)te));
if (layer_set)
{
layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
}
else
{
llerrs << "could not find layerset for LTO in wearable!" << llendl;
}
}
void LLViewerWearable::saveValues()
{
//update saved settings so wearable is no longer dirty
mSavedVisualParamMap.clear();
for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.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);
LLWearable::saveValues();
/*LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
if( panel )
@@ -1087,69 +492,6 @@ void LLViewerWearable::saveValues()
gFloaterCustomize->updateScrollingPanelList();
}
void LLViewerWearable::syncImages(te_map_t &src, te_map_t &dst)
{
// Deep copy of src (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's 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 defaults values for populating the destination image map.
image_id = getDefaultTextureImageID((ETextureIndex) te);
image = LLViewerTextureManager::getFetchedTexture( image_id );
}
if( dst.find(te) != dst.end() )
{
// there's 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 LLViewerWearable::destroyTextures()
{
for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
{
LLLocalTextureObject *lto = iter->second;
delete lto;
}
mTEMap.clear();
for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
{
LLLocalTextureObject *lto = iter->second;
delete lto;
}
mSavedTEMap.clear();
}
/*void LLViewerWearable::readFromAvatar()
{
LLVOAvatar* avatar = gAgentAvatarp;
@@ -1189,7 +531,7 @@ void LLViewerWearable::destroyTextures()
//}
}*/
// virtual
void LLViewerWearable::setUpdated() const
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
@@ -1310,7 +652,7 @@ std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w)
//w.mSaleInfo
s << " Params:" << "\n";
for (LLViewerWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
iter != w.mVisualParamIndexMap.end(); ++iter)
{
S32 param_id = iter->first;
@@ -1330,37 +672,6 @@ std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w)
return s;
}
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 && ('0' == r[len - 1]))
{
r.erase(len-1, 1);
len--;
}
if ('.' == r[len - 1])
{
// "24." -> "24"
r.erase(len-1, 1);
}
else if (('-' == r[0]) && ('0' == r[1]))
{
// "-0.59" -> "-.59"
r.erase(1, 1);
}
else if ('0' == r[0])
{
// "0.59" -> ".59"
r.erase(0, 1);
}
return r;
}
std::string asset_id_to_filename(const LLUUID &asset_id)
{
std::string asset_id_string;

View File

@@ -27,21 +27,10 @@
#ifndef LL_VIEWER_WEARABLE_H
#define LL_VIEWER_WEARABLE_H
#include "lluuid.h"
#include "llstring.h"
#include "llpermissions.h"
#include "llsaleinfo.h"
#include "llassetstorage.h"
#include "llwearabletype.h"
#include "llfile.h"
#include "lllocaltextureobject.h"
#include "llwearable.h"
#include "llavatarappearancedefines.h"
class LLViewerInventoryItem;
class LLVisualParam;
class LLTexGlobalColorInfo;
class LLTexGlobalColor;
class LLVOAvatar;
class LLViewerWearable : public LLWearable
{
@@ -61,76 +50,37 @@ public:
// Accessors
//--------------------------------------------------------------------
public:
const LLUUID& getItemID() const;
const LLUUID& getItemID() const { return mItemID; }
const LLAssetID& getAssetID() const { return mAssetID; }
const LLTransactionID& getTransactionID() const { return mTransactionID; }
BOOL FileExportParams(FILE* file);
BOOL FileExportTextures(FILE* file);
LLWearableType::EType getType() const { return mType; }
void setType( LLWearableType::EType type );
const std::string& getName() const { return mName; }
void setName( const std::string& name ) { mName = name; }
const std::string& getDescription() const { return mDescription; }
void setDescription(const std::string& desc) { mDescription = desc; }
const LLPermissions& getPermissions() const { return mPermissions; }
void setPermissions(const LLPermissions& p) { mPermissions = p; }
const LLSaleInfo& getSaleInfo() const { return mSaleInfo; }
void setSaleInfo(const LLSaleInfo& info) { mSaleInfo = info; }
const std::string& getTypeLabel() const;
const std::string& getTypeName() const;
LLAssetType::EType getAssetType() const;
S32 getDefinitionVersion() const { return mDefinitionVersion; }
void setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
virtual const LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index);
void setItemID(const LLUUID& item_id);
public:
typedef std::vector<LLVisualParam*> visual_param_vec_t;
BOOL isDirty() const;
BOOL isOldVersion() const;
/*virtual*/ void writeToAvatar(LLAvatarAppearance* avatarp);
/*virtual*/ void writeToAvatar(LLAvatarAppearance *avatarp);
void removeFromAvatar( BOOL upload_bake ) { LLViewerWearable::removeFromAvatar( mType, upload_bake ); }
static void removeFromAvatar( LLWearableType::EType type, BOOL upload_bake );
BOOL exportFile(LLFILE* file) const;
BOOL importFile(LLFILE* file);
/*virtual*/ EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
void setParamsToDefaults();
void setTexturesToDefaults();
/*virtual*/ const LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const;
void saveNewAsset() const;
static void onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
void copyDataFrom(const LLViewerWearable* src);
static void setCurrentDefinitionVersion( S32 version ) { LLViewerWearable::sCurrentDefinitionVersion = version; }
friend std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w);
void setItemID(const LLUUID& item_id);
LLLocalTextureObject* getLocalTextureObject(S32 index);
const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
void setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
void addVisualParam(LLVisualParam *param);
void setVisualParams();
void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
F32 getVisualParamWeight(S32 index) const;
LLVisualParam* getVisualParam(S32 index) const;
void getVisualParams(visual_param_vec_t &list);
void animateParams(F32 delta, BOOL upload_bake);
LLColor4 getClothesColor(S32 te) const;
void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
void revertValues();
void saveValues();
BOOL isOnTop() const;
/*virtual*/ void revertValues();
/*virtual*/ void saveValues();
// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
void setUpdated() const;
@@ -141,32 +91,11 @@ public:
// Update the baked texture hash.
/*virtual*/void addToBakedTextureHash(LLMD5& hash) const;
private:
typedef std::map<S32, LLLocalTextureObject*> te_map_t;
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
void createLayers(S32 te);
void createVisualParams();
void syncImages(te_map_t &src, te_map_t &dst);
void destroyTextures();
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.
std::string mName;
std::string mDescription;
LLPermissions mPermissions;
LLSaleInfo mSaleInfo;
LLAssetID mAssetID;
protected:
LLAssetID mAssetID;
LLTransactionID mTransactionID;
LLWearableType::EType mType;
typedef std::map<S32, F32> param_map_t;
param_map_t mSavedVisualParamMap; // last saved version of visual params
visual_param_index_map_t mVisualParamIndexMap;
te_map_t mTEMap; // maps TE to LocalTextureObject
te_map_t mSavedTEMap; // last saved version of TEMap
LLUUID mItemID; // ID of the inventory item in the agent's inventory
};

View File

@@ -8073,82 +8073,6 @@ void LLVOAvatar::releaseComponentTextures()
}
}
//static
BOOL LLVOAvatar::teToColorParams( ETextureIndex te, U32 *param_name )
{
switch( te )
{
case TEX_UPPER_SHIRT:
param_name[0] = 803; //"shirt_red";
param_name[1] = 804; //"shirt_green";
param_name[2] = 805; //"shirt_blue";
break;
case TEX_LOWER_PANTS:
param_name[0] = 806; //"pants_red";
param_name[1] = 807; //"pants_green";
param_name[2] = 808; //"pants_blue";
break;
case TEX_LOWER_SHOES:
param_name[0] = 812; //"shoes_red";
param_name[1] = 813; //"shoes_green";
param_name[2] = 817; //"shoes_blue";
break;
case TEX_LOWER_SOCKS:
param_name[0] = 818; //"socks_red";
param_name[1] = 819; //"socks_green";
param_name[2] = 820; //"socks_blue";
break;
case TEX_UPPER_JACKET:
case TEX_LOWER_JACKET:
param_name[0] = 834; //"jacket_red";
param_name[1] = 835; //"jacket_green";
param_name[2] = 836; //"jacket_blue";
break;
case TEX_UPPER_GLOVES:
param_name[0] = 827; //"gloves_red";
param_name[1] = 829; //"gloves_green";
param_name[2] = 830; //"gloves_blue";
break;
case TEX_UPPER_UNDERSHIRT:
param_name[0] = 821; //"undershirt_red";
param_name[1] = 822; //"undershirt_green";
param_name[2] = 823; //"undershirt_blue";
break;
case TEX_LOWER_UNDERPANTS:
param_name[0] = 824; //"underpants_red";
param_name[1] = 825; //"underpants_green";
param_name[2] = 826; //"underpants_blue";
break;
case TEX_SKIRT:
param_name[0] = 921; //"skirt_red";
param_name[1] = 922; //"skirt_green";
param_name[2] = 923; //"skirt_blue";
break;
case TEX_HEAD_TATTOO:
case TEX_LOWER_TATTOO:
case TEX_UPPER_TATTOO:
param_name[0] = 1071; //"tattoo_red";
param_name[1] = 1072; //"tattoo_green";
param_name[2] = 1073; //"tattoo_blue";
break;
default:
llassert(0);
return FALSE;
}
return TRUE;
}
void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
{
U32 param_name[3];
@@ -8252,6 +8176,16 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
return FALSE;
}
LLTexLayerSet* LLVOAvatar::getAvatarLayerSet(EBakedTextureIndex baked_index) const
{
/* switch(index)
case TEX_HEAD_BAKED:
case TEX_HEAD_BODYPAINT:
return mHeadLayerSet; */
return mBakedTextureDatas[baked_index].mTexLayerSet;
}
//-----------------------------------------------------------------------------
// clampAttachmentPositions()
//-----------------------------------------------------------------------------

View File

@@ -756,7 +756,6 @@ public:
public:
virtual void setClothesColor(LLAvatarAppearanceDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
virtual LLColor4 getClothesColor(LLAvatarAppearanceDefines::ETextureIndex te);
static BOOL teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name);
//--------------------------------------------------------------------
// Global colors
@@ -798,6 +797,7 @@ public:
void cleanupAttachedMesh( LLViewerObject* pVO );
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
virtual BOOL isWearingWearableType(LLWearableType::EType type ) const;
virtual LLTexLayerSet* getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
protected:
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
void lazyAttach();

View File

@@ -112,16 +112,17 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
else if (status >= 0)
{
// read the file
LLFILE* fp = LLFile::fopen(std::string(filename), "rb"); /*Flawfinder: ignore*/
if( !fp )
llifstream ifs(filename, llifstream::binary);
if( !ifs.is_open() )
{
LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;
}
else
{
wearable = new LLViewerWearable(uuid);
bool res = wearable->importFile( fp );
if (!res)
LLWearable::EImportResult result = wearable->importStream(
ifs, avatarp );
if (LLWearable::SUCCESS != result)
{
if (wearable->getType() == LLWearableType::WT_COUNT)
{
@@ -131,9 +132,12 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
wearable = NULL;
}
fclose( fp );
if(filename)
{
if (ifs.is_open())
{
ifs.close();
}
LLFile::remove(std::string(filename));
}
}
@@ -235,7 +239,7 @@ LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type,
lldebugs << "LLWearableList::createNewWearable()" << llendl;
LLViewerWearable *wearable = generateNewWearable();
wearable->setType( type );
wearable->setType( type, avatarp );
std::string name = LLTrans::getString( LLWearableType::getTypeDefaultNewName(wearable->getType()) );
wearable->setName( name );