From 04f607ec08a572f7a98f267677f127a01a5369c3 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Mon, 12 Oct 2009 05:18:32 -0700 Subject: Added avatar shape import and export from Meerkat viewer --- linden/indra/newview/llfloatercustomize.cpp | 155 +++++++++++++++++++++ linden/indra/newview/llfloatercustomize.h | 4 + linden/indra/newview/llwearable.cpp | 69 +++++++-- linden/indra/newview/llwearable.h | 4 + .../skins/default/xui/en-us/floater_customize.xml | 10 +- 5 files changed, 227 insertions(+), 15 deletions(-) (limited to 'linden/indra') diff --git a/linden/indra/newview/llfloatercustomize.cpp b/linden/indra/newview/llfloatercustomize.cpp index 432af73..c542b37 100644 --- a/linden/indra/newview/llfloatercustomize.cpp +++ b/linden/indra/newview/llfloatercustomize.cpp @@ -1597,6 +1597,10 @@ BOOL LLFloaterCustomize::postBuild() childSetAction("Save All", LLFloaterCustomize::onBtnSaveAll, (void*)this); childSetAction("Close", LLFloater::onClickClose, (void*)this); + // reX + childSetAction("Import", LLFloaterCustomize::onBtnImport, (void*)this); + childSetAction("Export", LLFloaterCustomize::onBtnExport, (void*)this); + // Wearable panels initWearablePanels(); @@ -1657,6 +1661,157 @@ void LLFloaterCustomize::setCurrentWearableType( EWearableType type ) } } + +// reX: new function +void LLFloaterCustomize::onBtnImport( void* userdata ) +{ + LLFilePicker& file_picker = LLFilePicker::instance(); + if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_XML ) ) + { + // User canceled import. + return; + } + + const std::string filename = file_picker.getFirstFile(); + + FILE* fp = LLFile::fopen(filename, "rb"); + + //char text_buffer[2048]; /* Flawfinder: ignore */ + S32 c; + S32 typ; + S32 count; + S32 param_id=0; + F32 param_weight=0; + S32 fields_read; + + for( S32 i=0; i < WT_COUNT; i++ ) + { + fields_read = fscanf( fp, "type %d\n", &typ); + if( fields_read != 1 ) + { + llwarns << "Bad asset type: early end of file" << llendl; + return; + } + + fields_read = fscanf( fp, "parameters %d\n", &count); + if( fields_read != 1 ) + { + llwarns << "Bad parameters : early end of file" << llendl; + return; + } + for(c=0;csetVisualParamWeight( param_id, param_weight, TRUE); + gAgent.getAvatarObject()->updateVisualParams(); + } + } + + + + //for( S32 i=0; i < WT_COUNT; i++ ) + //{ + // fields_read = fscanf( fp, "type %d\n", &typ); + // if( fields_read != 1 ) + // { + // llwarns << "Bad asset type: early end of file" << llendl; + // return; + // } + // fields_read = fscanf( fp, "textures %d\n", &count); + // if( fields_read != 1 ) + // { + // llwarns << "Bad textures: early end of file" << llendl; + // return; + // } + // + // for(c=0;cgetPermissions(); + is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID()); + } + } + if (is_modifiable) + { + old_wearable->FileExportParams(fp); + } + if (!is_modifiable) + { + fprintf( fp, "type %d\n",i); + fprintf( fp, "parameters 0\n"); + } + } + + for( S32 i=0; i < WT_COUNT; i++ ) + { + is_modifiable = FALSE; + LLWearable* old_wearable = gAgent.getWearable((EWearableType)i); + if( old_wearable ) + { + item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem((EWearableType)i); + if(item) + { + const LLPermissions& perm = item->getPermissions(); + is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID()); + } + } + if (is_modifiable) + { + old_wearable->FileExportTextures(fp); + } + if (!is_modifiable) + { + fprintf( fp, "type %d\n",i); + fprintf( fp, "textures 0\n"); + } + } + + fclose(fp); +} + // static void LLFloaterCustomize::onBtnSaveAll( void* userdata ) { diff --git a/linden/indra/newview/llfloatercustomize.h b/linden/indra/newview/llfloatercustomize.h index 15fc8f1..ffa943a 100644 --- a/linden/indra/newview/llfloatercustomize.h +++ b/linden/indra/newview/llfloatercustomize.h @@ -107,6 +107,10 @@ public: static EWearableType getCurrentWearableType() { return sCurrentWearableType; } // Callbacks + // reX: new function (thx dudes) + static void onBtnImport( void* userdata ); + // reX: new function + static void onBtnExport( void* userdata ); static void onBtnSaveAll( void* userdata ); static void onBtnSnapshot( void* userdata ); static void onBtnMakeOutfit( void* userdata ); diff --git a/linden/indra/newview/llwearable.cpp b/linden/indra/newview/llwearable.cpp index 6bdc50f..884cda5 100644 --- a/linden/indra/newview/llwearable.cpp +++ b/linden/indra/newview/llwearable.cpp @@ -150,41 +150,87 @@ EWearableType LLWearable::typeNameToType( const std::string& type_name ) return WT_INVALID; } - -std::string terse_F32_to_string( F32 f ) +const char* terse_F32_to_string( F32 f, char s[MAX_STRING] ) /* Flawfinder: ignore */ { - std::string r = llformat( "%.2f", f ); + char* r = s; + S32 len = snprintf( s, MAX_STRING, "%.2f", f ); /* Flawfinder: ignore */ // "1.20" -> "1.2" // "24.00" -> "24." - S32 len = r.length(); - while( len > 0 && '0' == r[len - 1] ) + while( '0' == r[len - 1] ) { - r.erase(len-1, 1); - len--; + len--; + r[len] = '\0'; } if( '.' == r[len - 1] ) { // "24." -> "24" - r.erase(len-1, 1); + len--; + r[len] = '\0'; } else if( ('-' == r[0]) && ('0' == r[1]) ) { // "-0.59" -> "-.59" - r.erase(1, 1); + r++; + r[0] = '-'; } else if( '0' == r[0] ) { // "0.59" -> ".59" - r.erase(0, 1); + r++; } return r; } +// reX: new function +BOOL LLWearable::FileExportParams( FILE* file ) +{ + // wearable type + S32 type = (S32)mType; + fprintf( file, "type %d\n", type ); + + // parameters + S32 num_parameters = mVisualParamMap.size(); + fprintf( file, "parameters %d\n", num_parameters ); + + char s[ MAX_STRING ]; /* Flawfinder: ignore */ + for (param_map_t::iterator iter = mVisualParamMap.begin(); + iter != mVisualParamMap.end(); ++iter) + { + S32 param_id = iter->first; + F32 param_weight = iter->second; + fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight, s ) ); + } + + return TRUE; +} + +// reX: new function +BOOL LLWearable::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; + LLUUID& image_id = iter->second; + fprintf( file, "%d %s\n", te, image_id.asString().c_str() ); + } + + return TRUE; +} + BOOL LLWearable::exportFile( LLFILE* file ) { // header and version @@ -231,12 +277,13 @@ BOOL LLWearable::exportFile( LLFILE* file ) return FALSE; } + char s[ MAX_STRING ]; /* Flawfinder: ignore */ for (param_map_t::iterator iter = mVisualParamMap.begin(); iter != mVisualParamMap.end(); ++iter) { S32 param_id = iter->first; F32 param_weight = iter->second; - if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 ) + if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight, s ) ) < 0 ) { return FALSE; } diff --git a/linden/indra/newview/llwearable.h b/linden/indra/newview/llwearable.h index ea16d20..9986e85 100644 --- a/linden/indra/newview/llwearable.h +++ b/linden/indra/newview/llwearable.h @@ -60,6 +60,10 @@ public: BOOL exportFile(LLFILE* file); BOOL importFile(LLFILE* file); + // reX: new function + BOOL FileExportParams(FILE* file); + // reX: new function + BOOL FileExportTextures(FILE* file); EWearableType getType() const { return mType; } void setType( EWearableType type ) { mType = type; } diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml b/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml index e02607c..527ec4e 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_customize.xml @@ -1077,12 +1077,14 @@ scratch and wear it.