Completed code migration from LLViewerWearable to LLWearable.
This commit is contained in:
@@ -40,7 +40,7 @@ set(llappearance_SOURCE_FILES
|
||||
lltexlayer.cpp
|
||||
lltexlayerparams.cpp
|
||||
lltexturemanagerbridge.cpp
|
||||
#llwearable.cpp
|
||||
llwearable.cpp
|
||||
llwearabledata.cpp
|
||||
llwearabletype.cpp
|
||||
llviewervisualparam.cpp
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
820
indra/llappearance/llwearable.cpp
Normal file
820
indra/llappearance/llwearable.cpp
Normal 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", ¶m_id, ¶m_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 <o)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -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 <o);
|
||||
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
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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$
|
||||
*/
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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", ¶m_id, ¶m_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 <o)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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 <o);
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
@@ -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()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user