From 79412de233caec646d453a461b95851b353c6ab0 Mon Sep 17 00:00:00 2001 From: Beeks Date: Mon, 27 Sep 2010 00:20:34 -0400 Subject: [PATCH] Serious fix for the Tintable tattoos! Signed-off-by: Beeks --- indra/llcharacter/llcharacter.cpp | 4 +- indra/llcharacter/llvisualparam.cpp | 4 +- indra/llcharacter/llvisualparam.h | 6 +- indra/newview/character/avatar_lad.xml | 8 +- indra/newview/llagent.cpp | 2 +- indra/newview/llao.cpp | 2 +- indra/newview/llfloatercustomize.cpp | 2 +- indra/newview/llfloaterexport.cpp | 1808 ++++++++++++------------ indra/newview/llvoavatar.cpp | 43 +- indra/newview/llwearable.cpp | 14 +- 10 files changed, 947 insertions(+), 946 deletions(-) diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index dcdfe074e..b479ed0d1 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -378,7 +378,7 @@ void LLCharacter::clearVisualParamWeights() param; param = getNextVisualParam()) { - if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (param->isTweakable()) { param->setWeight( param->getDefaultWeight(), FALSE ); } @@ -394,7 +394,7 @@ BOOL LLCharacter::visualParamWeightsAreDefault() param; param = getNextVisualParam()) { - if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (param->isTweakable()) { if (param->getWeight() != param->getDefaultWeight()) return false; diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index d7a144e00..9579ff8af 100644 --- a/indra/llcharacter/llvisualparam.cpp +++ b/indra/llcharacter/llvisualparam.cpp @@ -238,7 +238,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL set_by_user) { if (mInfo) { - if (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (isTweakable()) { mTargetWeight = llclamp(target_value, mInfo->mMinWeight, mInfo->mMaxWeight); } @@ -282,7 +282,7 @@ void LLVisualParam::animate( F32 delta, BOOL set_by_user ) //----------------------------------------------------------------------------- void LLVisualParam::stopAnimating(BOOL set_by_user) { - if (mIsAnimating && getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (mIsAnimating && isTweakable()) { mIsAnimating = FALSE; setWeight(mTargetWeight, set_by_user); diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index 3a0c1bbc7..e8fa6d1c5 100644 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -51,6 +51,7 @@ enum EVisualParamGroup { VISUAL_PARAM_GROUP_TWEAKABLE, VISUAL_PARAM_GROUP_ANIMATABLE, + VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT, NUM_VISUAL_PARAM_GROUPS }; @@ -124,7 +125,7 @@ public: void setMaxDisplayName(const std::string& s) { mInfo->mMaxName = s; } void setMinDisplayName(const std::string& s) { mInfo->mMinName = s; } - EVisualParamGroup getGroup() { return mInfo->mGroup; } + EVisualParamGroup getGroup() const { return mInfo->mGroup; } F32 getMinWeight() { return mInfo->mMinWeight; } F32 getMaxWeight() { return mInfo->mMaxWeight; } F32 getDefaultWeight() { return mInfo->mDefaultWeight; } @@ -133,7 +134,8 @@ public: F32 getWeight() { return mIsAnimating ? mTargetWeight : mCurWeight; } F32 getCurrentWeight() { return mCurWeight; } F32 getLastWeight() { return mLastWeight; } - BOOL isAnimating() { return mIsAnimating; } + BOOL isAnimating() { return mIsAnimating; } + BOOL isTweakable() { return (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) || (getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT); } LLVisualParam* getNextParam() { return mNext; } void setNextParam( LLVisualParam *next ); diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index d0dab6aea..245b393cd 100755 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -1099,7 +1099,7 @@ camera_distance=".8" camera_angle="15"> - + @@ -11424,7 +11424,7 @@ id="876" /> - @@ -11432,7 +11432,7 @@ - @@ -11440,7 +11440,7 @@ - diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index eb3d75275..6ac6575b2 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -7586,7 +7586,7 @@ void LLAgent::sendAgentSetAppearance() param; param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam()) { - if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) // do not transmit params of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT { msg->nextBlockFast(_PREHASH_VisualParam ); diff --git a/indra/newview/llao.cpp b/indra/newview/llao.cpp index 5dfc9d236..269a1d552 100644 --- a/indra/newview/llao.cpp +++ b/indra/newview/llao.cpp @@ -17,7 +17,7 @@ Rewritten by Hg Beeks #include "llviewercontrol.h" #include "llvoavatar.h" //this is for debugging ;D -#define AO_DEBUG +//#define AO_DEBUG //static variables std::list LLAO::mStandOverrides; diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index 6f310d813..0c7357541 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -547,7 +547,7 @@ void LLPanelEditWearable::setSubpart( ESubpart subpart ) param = (LLViewerVisualParam *)avatar->getNextVisualParam()) { if (param->getID() == -1 - || param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE + || !param->isTweakable() || param->getEditGroup() != part->mEditGroup || !(param->getSex() & avatar_sex)) { diff --git a/indra/newview/llfloaterexport.cpp b/indra/newview/llfloaterexport.cpp index 9ff78e8c8..2d1cfc29f 100644 --- a/indra/newview/llfloaterexport.cpp +++ b/indra/newview/llfloaterexport.cpp @@ -1,904 +1,904 @@ -// - -#include "llviewerprecompiledheaders.h" -#include "llfloaterexport.h" -#include "lluictrlfactory.h" -#include "llsdutil.h" -#include "llsdserialize.h" -#include "llselectmgr.h" -#include "llscrolllistctrl.h" -#include "llchat.h" -#include "llfloaterchat.h" -#include "llfilepicker.h" -#include "llagent.h" -#include "llvoavatar.h" -#include "llvoavatardefines.h" -#include "llimportobject.h" -#include "llviewerobjectlist.h" -#include "llviewerregion.h" -#include "llwindow.h" -#include "llviewerimagelist.h" -#include "lltexturecache.h" -#include "llimage.h" -#include "llappviewer.h" - -std::vector LLFloaterExport::instances; - -class CacheReadResponder : public LLTextureCache::ReadResponder -{ -public: -CacheReadResponder(const LLUUID& id, const std::string& filename) -: mID(id) -{ - mFormattedImage = new LLImageJ2C; - setImage(mFormattedImage); - mFilename = filename; -} -void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) -{ - if(imageformat==IMG_CODEC_TGA && mFormattedImage->getCodec()==IMG_CODEC_J2C) - { - llwarns<<"Bleh its a tga not saving"<getCodec() == imageformat); - mFormattedImage->appendData(data, datasize); - } - else - { - mFormattedImage = LLImageFormatted::createFromType(imageformat); - mFormattedImage->setData(data,datasize); - } - mImageSize = imagesize; - mImageLocal = imagelocal; -} - -virtual void completed(bool success) -{ - if(success && (mFormattedImage.notNull()) && mImageSize>0) - { - - llinfos << "SUCCESS getting texture "<save(mFilename)) - { - llinfos << "FAIL saving texture "< mFormattedImage; - LLUUID mID; - std::string mFilename; -}; - - -LLExportable::LLExportable(LLViewerObject* object, std::string name, std::map& primNameMap) -: mObject(object), - mType(EXPORTABLE_OBJECT), - mPrimNameMap(&primNameMap) -{ -} - -LLExportable::LLExportable(LLVOAvatar* avatar, EWearableType type, std::map& primNameMap) -: mAvatar(avatar), - mType(EXPORTABLE_WEARABLE), - mWearableType(type), - mPrimNameMap(&primNameMap) -{ -} - -LLSD LLExportable::asLLSD() -{ - if(mType == EXPORTABLE_OBJECT) - { - std::list prims; - - prims.push_back(mObject); - - LLViewerObject::child_list_t child_list = mObject->getChildren(); - for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) - { - LLViewerObject* child = *i; - if(child->getPCode() < LL_PCODE_APP) - { - prims.push_back(child); - } - } - - LLSD llsd; - - std::list::iterator prim_iter = prims.begin(); - std::list::iterator prims_end = prims.end(); - for( ; prim_iter != prims_end; ++prim_iter) - { - LLViewerObject* object = (*prim_iter); - - LLSD prim_llsd; - - prim_llsd["type"] = "prim"; - - if (!object->isRoot()) - { - if(!object->getSubParent()->isAvatar()) - { - // Parent id - prim_llsd["parent"] = llformat("%d", object->getSubParent()->getLocalID()); - } - } - if(object->getSubParent()) - { - if(object->getSubParent()->isAvatar()) - { - // attachment-specific - U8 state = object->getState(); - S32 attachpt = ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4))); - prim_llsd["attach"] = attachpt; - } - } - - // Transforms - prim_llsd["position"] = object->getPosition().getValue(); - prim_llsd["scale"] = object->getScale().getValue(); - prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); - - // Flags - prim_llsd["shadows"] = object->flagCastShadows(); - prim_llsd["phantom"] = object->flagPhantom(); - prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS); - - // Volume params - LLVolumeParams params = object->getVolume()->getParams(); - prim_llsd["volume"] = params.asLLSD(); - - // Extra params - if (object->isFlexible()) - { - // Flexible - LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); - prim_llsd["flexible"] = flex->asLLSD(); - } - if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) - { - // Light - LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); - prim_llsd["light"] = light->asLLSD(); - } - if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) - { - // Sculpt - LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); - prim_llsd["sculpt"] = sculpt->asLLSD(); - } - - // Textures - LLSD te_llsd; - U8 te_count = object->getNumTEs(); - for (U8 i = 0; i < te_count; i++) - { - te_llsd.append(object->getTE(i)->asLLSD()); - } - prim_llsd["textures"] = te_llsd; - - std::map::iterator pos = (*mPrimNameMap).find(object->getLocalID()); - if(pos != (*mPrimNameMap).end()) - prim_llsd["name"] = (*mPrimNameMap)[object->getLocalID()]; - - llsd[llformat("%d", object->getLocalID())] = prim_llsd; - } - - return llsd; - } - else if(mType == EXPORTABLE_WEARABLE) - { - LLSD llsd; // pointless map with single key/value - - LLSD item_sd; // map for wearable - - item_sd["type"] = "wearable"; - - S32 type_s32 = (S32)mWearableType; - std::string wearable_name = LLWearable::typeToTypeName( mWearableType ); - - item_sd["name"] = mAvatar->getFullname() + " " + wearable_name; - item_sd["wearabletype"] = type_s32; - - LLSD param_map; - - for( LLVisualParam* param = mAvatar->getFirstVisualParam(); param; param = mAvatar->getNextVisualParam() ) - { - LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - if( (viewer_param->getWearableType() == type_s32) && - (viewer_param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) ) - { - param_map[llformat("%d", viewer_param->getID())] = viewer_param->getWeight(); - } - } - - item_sd["params"] = param_map; - - LLSD textures_map; - - for( S32 te = 0; te < LLVOAvatarDefines::TEX_NUM_INDICES; te++ ) - { - if( LLVOAvatar::getTEWearableType( (LLVOAvatarDefines::ETextureIndex)te ) == mWearableType ) - { - LLViewerImage* te_image = mAvatar->getTEImage( te ); - if( te_image ) - { - textures_map[llformat("%d", te)] = te_image->getID(); - } - } - } - - item_sd["textures"] = textures_map; - - // Generate a unique ID for it... - LLUUID myid; - myid.generate(); - - llsd[myid.asString()] = item_sd; - - return llsd; - } - return LLSD(); -} - - - -LLFloaterExport::LLFloaterExport() -: LLFloater() -{ - mSelection = LLSelectMgr::getInstance()->getSelection(); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_export.xml"); - LLFloaterExport::instances.push_back(this); -} - - -LLFloaterExport::~LLFloaterExport() -{ - std::vector::iterator pos = std::find(LLFloaterExport::instances.begin(), LLFloaterExport::instances.end(), this); - if(pos != LLFloaterExport::instances.end()) - { - LLFloaterExport::instances.erase(pos); - } -} - -BOOL LLFloaterExport::postBuild(void) -{ - if(!mSelection) return TRUE; - if(mSelection->getRootObjectCount() < 1) return TRUE; - - // New stuff: Populate prim name map - - for (LLObjectSelection::valid_iterator iter = mSelection->valid_begin(); - iter != mSelection->valid_end(); iter++) - { - LLSelectNode* nodep = *iter; - LLViewerObject* objectp = nodep->getObject(); - U32 localid = objectp->getLocalID(); - std::string name = nodep->mName; - mPrimNameMap[localid] = name; - } - - // Older stuff - - LLScrollListCtrl* list = getChild("export_list"); - - std::map avatars; - - for (LLObjectSelection::valid_root_iterator iter = mSelection->valid_root_begin(); - iter != mSelection->valid_root_end(); iter++) - { - LLSelectNode* nodep = *iter; - LLViewerObject* objectp = nodep->getObject(); - std::string objectp_id = llformat("%d", objectp->getLocalID()); - - if(list->getItemIndex(objectp->getID()) == -1) - { - bool is_attachment = false; - bool is_root = true; - LLViewerObject* parentp = objectp->getSubParent(); - if(parentp) - { - if(!parentp->isAvatar()) - { - // parent is a prim I guess - is_root = false; - } - else - { - // parent is an avatar - is_attachment = true; - if(!avatars[parentp]) avatars[parentp] = true; - } - } - - bool is_prim = true; - if(objectp->getPCode() >= LL_PCODE_APP) - { - is_prim = false; - } - - bool is_avatar = objectp->isAvatar(); - - - if(is_root && is_prim) - { - LLSD element; - element["id"] = objectp->getID(); - - LLSD& check_column = element["columns"][LIST_CHECKED]; - check_column["column"] = "checked"; - check_column["type"] = "checkbox"; - check_column["value"] = true; - - LLSD& type_column = element["columns"][LIST_TYPE]; - type_column["column"] = "type"; - type_column["type"] = "icon"; - type_column["value"] = "inv_item_object.tga"; - - LLSD& name_column = element["columns"][LIST_NAME]; - name_column["column"] = "name"; - if(is_attachment) - name_column["value"] = nodep->mName + " (worn on " + utf8str_tolower(objectp->getAttachmentPointName()) + ")"; - else - name_column["value"] = nodep->mName; - - LLSD& avatarid_column = element["columns"][LIST_AVATARID]; - avatarid_column["column"] = "avatarid"; - if(is_attachment) - avatarid_column["value"] = parentp->getID(); - else - avatarid_column["value"] = LLUUID::null; - - LLExportable* exportable = new LLExportable(objectp, nodep->mName, mPrimNameMap); - mExportables[objectp->getID()] = exportable->asLLSD(); - - list->addElement(element, ADD_BOTTOM); - - addToPrimList(objectp); - } - else if(is_avatar) - { - if(!avatars[objectp]) - { - avatars[objectp] = true; - } - } - } - } - std::map::iterator avatar_iter = avatars.begin(); - std::map::iterator avatars_end = avatars.end(); - for( ; avatar_iter != avatars_end; avatar_iter++) - { - LLViewerObject* avatar = (*avatar_iter).first; - addAvatarStuff((LLVOAvatar*)avatar); - } - - updateNamesProgress(); - - childSetAction("select_all_btn", onClickSelectAll, this); - childSetAction("select_objects_btn", onClickSelectObjects, this); - childSetAction("select_wearables_btn", onClickSelectWearables, this); - - childSetAction("save_as_btn", onClickSaveAs, this); - childSetAction("make_copy_btn", onClickMakeCopy, this); - - return TRUE; -} - -void LLFloaterExport::addAvatarStuff(LLVOAvatar* avatarp) -{ - LLScrollListCtrl* list = getChild("export_list"); - for( S32 type = WT_SHAPE; type < WT_COUNT; type++ ) - { - // guess whether this wearable actually exists - // by checking whether it has any textures that aren't default - bool exists = false; - if(type == WT_SHAPE) - { - exists = true; - } - else if (type == WT_ALPHA || type == WT_TATTOO) //alpha layers and tattos are unsupported for now - { - continue; - } - else - { - for( S32 te = 0; te < LLVOAvatarDefines::TEX_NUM_INDICES; te++ ) - { - if( (S32)LLVOAvatar::getTEWearableType( (LLVOAvatarDefines::ETextureIndex)te ) == type ) - { - LLViewerImage* te_image = avatarp->getTEImage( te ); - if( te_image->getID() != IMG_DEFAULT_AVATAR) - { - exists = true; - break; - } - } - } - } - - if(exists) - { - std::string wearable_name = LLWearable::typeToTypeName( (EWearableType)type ); - std::string name = avatarp->getFullname() + " " + wearable_name; - LLUUID myid; - myid.generate(); - - LLSD element; - element["id"] = myid; - - LLSD& check_column = element["columns"][LIST_CHECKED]; - check_column["column"] = "checked"; - check_column["type"] = "checkbox"; - check_column["value"] = false; - - LLSD& type_column = element["columns"][LIST_TYPE]; - type_column["column"] = "type"; - type_column["type"] = "icon"; - type_column["value"] = "inv_item_" + wearable_name + ".tga"; - - LLSD& name_column = element["columns"][LIST_NAME]; - name_column["column"] = "name"; - name_column["value"] = name; - - LLSD& avatarid_column = element["columns"][LIST_AVATARID]; - avatarid_column["column"] = "avatarid"; - avatarid_column["value"] = avatarp->getID(); - - LLExportable* exportable = new LLExportable(avatarp, (EWearableType)type, mPrimNameMap); - mExportables[myid] = exportable->asLLSD(); - - list->addElement(element, ADD_BOTTOM); - } - } - - // Add attachments - LLViewerObject::child_list_t child_list = avatarp->getChildren(); - for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) - { - LLViewerObject* childp = *i; - if(list->getItemIndex(childp->getID()) == -1) - { - LLSD element; - element["id"] = childp->getID(); - - LLSD& check_column = element["columns"][LIST_CHECKED]; - check_column["column"] = "checked"; - check_column["type"] = "checkbox"; - check_column["value"] = false; - - LLSD& type_column = element["columns"][LIST_TYPE]; - type_column["column"] = "type"; - type_column["type"] = "icon"; - type_column["value"] = "inv_item_object.tga"; - - LLSD& name_column = element["columns"][LIST_NAME]; - name_column["column"] = "name"; - name_column["value"] = "Object (worn on " + utf8str_tolower(childp->getAttachmentPointName()) + ")"; - - LLSD& avatarid_column = element["columns"][LIST_AVATARID]; - avatarid_column["column"] = "avatarid"; - avatarid_column["value"] = avatarp->getID(); - - LLExportable* exportable = new LLExportable(childp, "Object", mPrimNameMap); - mExportables[childp->getID()] = exportable->asLLSD(); - - list->addElement(element, ADD_BOTTOM); - - addToPrimList(childp); - //LLSelectMgr::getInstance()->selectObjectAndFamily(childp, false); - //LLSelectMgr::getInstance()->deselectObjectAndFamily(childp, true, true); - - LLViewerObject::child_list_t select_list = childp->getChildren(); - LLViewerObject::child_list_t::iterator select_iter; - int block_counter; - - gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID()); - block_counter = 0; - for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter) - { - block_counter++; - if(block_counter >= 254) - { - // start a new message - gMessageSystem->sendReliable(childp->getRegion()->getHost()); - gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); - } - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID()); - } - gMessageSystem->sendReliable(childp->getRegion()->getHost()); - - gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID()); - block_counter = 0; - for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter) - { - block_counter++; - if(block_counter >= 254) - { - // start a new message - gMessageSystem->sendReliable(childp->getRegion()->getHost()); - gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); - } - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID()); - } - gMessageSystem->sendReliable(childp->getRegion()->getHost()); - } - } -} - -//static -void LLFloaterExport::onClickSelectAll(void* user_data) -{ - LLFloaterExport* floater = (LLFloaterExport*)user_data; - LLScrollListCtrl* list = floater->getChild("export_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::iterator items_end = items.end(); - bool new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue()); - for( ; item_iter != items_end; ++item_iter) - { - LLScrollListItem* item = (*item_iter); - item->getColumn(LIST_CHECKED)->setValue(new_value); - } -} - -//static -void LLFloaterExport::onClickSelectObjects(void* user_data) -{ - LLFloaterExport* floater = (LLFloaterExport*)user_data; - LLScrollListCtrl* list = floater->getChild("export_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::iterator items_end = items.end(); - bool new_value = false; - for( ; item_iter != items_end; ++item_iter) - { - if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga") - { - new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue()); - break; - } - } - for(item_iter = items.begin(); item_iter != items_end; ++item_iter) - { - if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga") - { - LLScrollListItem* item = (*item_iter); - item->getColumn(LIST_CHECKED)->setValue(new_value); - } - } -} - -//static -void LLFloaterExport::onClickSelectWearables(void* user_data) -{ - LLFloaterExport* floater = (LLFloaterExport*)user_data; - LLScrollListCtrl* list = floater->getChild("export_list"); - std::vector items = list->getAllData(); - std::vector::iterator item_iter = items.begin(); - std::vector::iterator items_end = items.end(); - bool new_value = false; - for( ; item_iter != items_end; ++item_iter) - { - if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga") - { - new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue()); - break; - } - } - for(item_iter = items.begin(); item_iter != items_end; ++item_iter) - { - if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga") - { - LLScrollListItem* item = (*item_iter); - item->getColumn(LIST_CHECKED)->setValue(new_value); - } - } -} - -LLSD LLFloaterExport::getLLSD() -{ - LLScrollListCtrl* list = getChild("export_list"); - std::vector items = list->getAllData(); - LLSD sd; - std::vector::iterator item_iter = items.begin(); - std::vector::iterator items_end = items.end(); - for( ; item_iter != items_end; ++item_iter) - { - LLScrollListItem* item = (*item_iter); - if(item->getColumn(LIST_CHECKED)->getValue()) - { - LLSD item_sd = mExportables[item->getUUID()]; - LLSD::map_iterator map_iter = item_sd.beginMap(); - LLSD::map_iterator map_end = item_sd.endMap(); - for( ; map_iter != map_end; ++map_iter) - { - std::string key((*map_iter).first); - LLSD data = (*map_iter).second; - // copy it... - sd[key] = data; - } - } - } - return sd; -} - -//static -void LLFloaterExport::onClickSaveAs(void* user_data) -{ - LLFloaterExport* floater = (LLFloaterExport*)user_data; - LLSD sd = floater->getLLSD(); - - if(sd.size()) - { - std::string default_filename = "untitled"; - - // count the number of selected items - LLScrollListCtrl* list = floater->getChild("export_list"); - std::vector items = list->getAllData(); - int item_count = 0; - LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID(); - bool all_same_avatarid = true; - std::vector::iterator item_iter = items.begin(); - std::vector::iterator items_end = items.end(); - for( ; item_iter != items_end; ++item_iter) - { - LLScrollListItem* item = (*item_iter); - if(item->getColumn(LIST_CHECKED)->getValue()) - { - item_count++; - if(item->getColumn(LIST_AVATARID)->getValue().asUUID() != avatarid) - { - all_same_avatarid = false; - } - } - } - - if(item_count == 1) - { - // Exporting one item? Use its name for the filename. - // But make sure it's a root! - LLSD target = (*(sd.beginMap())).second; - if(target.has("parent")) - { - std::string parentid = target["parent"].asString(); - target = sd[parentid]; - } - if(target.has("name")) - { - if(target["name"].asString().length() > 0) - { - default_filename = target["name"].asString(); - } - } - } - else - { - // Multiple items? - // If they're all part of the same avatar, use the avatar's name as filename. - if(all_same_avatarid) - { - std::string fullname; - if(gCacheName->getFullName(avatarid, fullname)) - { - default_filename = fullname; - } - } - } - - LLFilePicker& file_picker = LLFilePicker::instance(); - if(file_picker.getSaveFile( LLFilePicker::FFSAVE_XML, LLDir::getScrubbedFileName(default_filename + ".xml"))) - { - std::string file_name = file_picker.getFirstFile(); - std::string path = file_name.substr(0,file_name.find_last_of(".")) + "_assets"; - BOOL download_texture = floater->childGetValue("download_textures"); - if(download_texture) - { - if(!LLFile::isdir(path)) - { - LLFile::mkdir(path); - }else - { - U32 response = OSMessageBox("Directory "+path+" already exists, would you like to continue and override files?", "Directory Already Exists", OSMB_YESNO); - if(response) - { - return; - } - } - path.append(gDirUtilp->getDirDelimiter()); //lets add the Delimiter now - } - // set correct names within llsd and download textures - LLSD::map_iterator map_iter = sd.beginMap(); - LLSD::map_iterator map_end = sd.endMap(); - std::list textures; - - for( ; map_iter != map_end; ++map_iter) - { - std::istringstream keystr((*map_iter).first); - U32 key; - keystr >> key; - LLSD item = (*map_iter).second; - if(item["type"].asString() == "prim") - { - std::string name = floater->mPrimNameMap[key]; - item["name"] = name; - // I don't understand C++ :( - sd[(*map_iter).first] = item; - - if(download_texture) - { - //textures - LLSD::array_iterator tex_iter = item["textures"].beginArray(); - for( ; tex_iter != item["textures"].endArray(); ++tex_iter) - { - textures.push_back((*tex_iter)["imageid"].asUUID()); - } - if(item.has("sculpt")) - { - textures.push_back(item["sculpt"]["texture"].asUUID()); - } - } - } - else if(download_texture && item["type"].asString() == "wearable") - { - LLSD::map_iterator tex_iter = item["textures"].beginMap(); - for( ; tex_iter != item["textures"].endMap(); ++tex_iter) - { - textures.push_back((*tex_iter).second.asUUID()); - } - } - } - if(download_texture) - { - textures.unique(); - while(!textures.empty()) - { - llinfos << "Requesting texture " << textures.front().asString() << llendl; - LLViewerImage* img = gImageList.getImage(textures.front(), MIPMAP_TRUE, FALSE); - img->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAX_LEVEL); - - CacheReadResponder* responder = new CacheReadResponder(textures.front(), std::string(path + textures.front().asString() + ".j2c")); - LLAppViewer::getTextureCache()->readFromCache(textures.front(),LLWorkerThread::PRIORITY_HIGH,0,999999,responder); - textures.pop_front(); - } - } - - llofstream export_file(file_name); - LLSDSerialize::toPrettyXML(sd, export_file); - export_file.close(); - - std::string msg = "Saved "; - msg.append(file_name); - if(download_texture) msg.append(" (Content might take some time to download)"); - LLChat chat(msg); - LLFloaterChat::addChat(chat); - } - } - else - { - std::string msg = "No exportable items selected"; - LLChat chat(msg); - LLFloaterChat::addChat(chat); - return; - } - - floater->close(); -} - -//static -void LLFloaterExport::onClickMakeCopy(void* user_data) -{ - LLFloaterExport* floater = (LLFloaterExport*)user_data; - LLSD sd = floater->getLLSD(); - - if(sd.size()) - { - LLXmlImport::import(new LLXmlImportOptions(sd)); - } - else - { - std::string msg = "No copyable items selected"; - LLChat chat(msg); - LLFloaterChat::addChat(chat); - return; - } - - // I guess close the floater because only one import is allowed at once anyway - floater->close(); -} - -void LLFloaterExport::addToPrimList(LLViewerObject* object) -{ - mPrimList.push_back(object->getLocalID()); - LLViewerObject::child_list_t child_list = object->getChildren(); - for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) - { - LLViewerObject* child = *i; - if(child->getPCode() < LL_PCODE_APP) - { - mPrimList.push_back(child->getLocalID()); - } - } -} - -void LLFloaterExport::updateNamesProgress() -{ - childSetText("names_progress_text", llformat("Names retrieved: %d of %d", mPrimNameMap.size(), mPrimList.size())); -} - -void LLFloaterExport::receivePrimName(LLViewerObject* object, std::string name) -{ - LLUUID fullid = object->getID(); - U32 localid = object->getLocalID(); - if(std::find(mPrimList.begin(), mPrimList.end(), localid) != mPrimList.end()) - { - mPrimNameMap[localid] = name; - LLScrollListCtrl* list = getChild("export_list"); - S32 item_index = list->getItemIndex(fullid); - if(item_index != -1) - { - std::vector items = list->getAllData(); - std::vector::iterator iter = items.begin(); - std::vector::iterator end = items.end(); - for( ; iter != end; ++iter) - { - if((*iter)->getUUID() == fullid) - { - (*iter)->getColumn(LIST_NAME)->setValue(name + " (worn on " + utf8str_tolower(object->getAttachmentPointName()) + ")"); - break; - } - } - } - updateNamesProgress(); - } -} - -// static -void LLFloaterExport::receiveObjectProperties(LLUUID fullid, std::string name, std::string desc) -{ - LLViewerObject* object = gObjectList.findObject(fullid); - std::vector::iterator iter = LLFloaterExport::instances.begin(); - std::vector::iterator end = LLFloaterExport::instances.end(); - for( ; iter != end; ++iter) - { - (*iter)->receivePrimName(object, name); - } -} - -// +// + +#include "llviewerprecompiledheaders.h" +#include "llfloaterexport.h" +#include "lluictrlfactory.h" +#include "llsdutil.h" +#include "llsdserialize.h" +#include "llselectmgr.h" +#include "llscrolllistctrl.h" +#include "llchat.h" +#include "llfloaterchat.h" +#include "llfilepicker.h" +#include "llagent.h" +#include "llvoavatar.h" +#include "llvoavatardefines.h" +#include "llimportobject.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llwindow.h" +#include "llviewerimagelist.h" +#include "lltexturecache.h" +#include "llimage.h" +#include "llappviewer.h" + +std::vector LLFloaterExport::instances; + +class CacheReadResponder : public LLTextureCache::ReadResponder +{ +public: +CacheReadResponder(const LLUUID& id, const std::string& filename) +: mID(id) +{ + mFormattedImage = new LLImageJ2C; + setImage(mFormattedImage); + mFilename = filename; +} +void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) +{ + if(imageformat==IMG_CODEC_TGA && mFormattedImage->getCodec()==IMG_CODEC_J2C) + { + llwarns<<"Bleh its a tga not saving"<getCodec() == imageformat); + mFormattedImage->appendData(data, datasize); + } + else + { + mFormattedImage = LLImageFormatted::createFromType(imageformat); + mFormattedImage->setData(data,datasize); + } + mImageSize = imagesize; + mImageLocal = imagelocal; +} + +virtual void completed(bool success) +{ + if(success && (mFormattedImage.notNull()) && mImageSize>0) + { + + llinfos << "SUCCESS getting texture "<save(mFilename)) + { + llinfos << "FAIL saving texture "< mFormattedImage; + LLUUID mID; + std::string mFilename; +}; + + +LLExportable::LLExportable(LLViewerObject* object, std::string name, std::map& primNameMap) +: mObject(object), + mType(EXPORTABLE_OBJECT), + mPrimNameMap(&primNameMap) +{ +} + +LLExportable::LLExportable(LLVOAvatar* avatar, EWearableType type, std::map& primNameMap) +: mAvatar(avatar), + mType(EXPORTABLE_WEARABLE), + mWearableType(type), + mPrimNameMap(&primNameMap) +{ +} + +LLSD LLExportable::asLLSD() +{ + if(mType == EXPORTABLE_OBJECT) + { + std::list prims; + + prims.push_back(mObject); + + LLViewerObject::child_list_t child_list = mObject->getChildren(); + for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) + { + LLViewerObject* child = *i; + if(child->getPCode() < LL_PCODE_APP) + { + prims.push_back(child); + } + } + + LLSD llsd; + + std::list::iterator prim_iter = prims.begin(); + std::list::iterator prims_end = prims.end(); + for( ; prim_iter != prims_end; ++prim_iter) + { + LLViewerObject* object = (*prim_iter); + + LLSD prim_llsd; + + prim_llsd["type"] = "prim"; + + if (!object->isRoot()) + { + if(!object->getSubParent()->isAvatar()) + { + // Parent id + prim_llsd["parent"] = llformat("%d", object->getSubParent()->getLocalID()); + } + } + if(object->getSubParent()) + { + if(object->getSubParent()->isAvatar()) + { + // attachment-specific + U8 state = object->getState(); + S32 attachpt = ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4))); + prim_llsd["attach"] = attachpt; + } + } + + // Transforms + prim_llsd["position"] = object->getPosition().getValue(); + prim_llsd["scale"] = object->getScale().getValue(); + prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); + + // Flags + prim_llsd["shadows"] = object->flagCastShadows(); + prim_llsd["phantom"] = object->flagPhantom(); + prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS); + + // Volume params + LLVolumeParams params = object->getVolume()->getParams(); + prim_llsd["volume"] = params.asLLSD(); + + // Extra params + if (object->isFlexible()) + { + // Flexible + LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); + prim_llsd["flexible"] = flex->asLLSD(); + } + if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) + { + // Light + LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); + prim_llsd["light"] = light->asLLSD(); + } + if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) + { + // Sculpt + LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + prim_llsd["sculpt"] = sculpt->asLLSD(); + } + + // Textures + LLSD te_llsd; + U8 te_count = object->getNumTEs(); + for (U8 i = 0; i < te_count; i++) + { + te_llsd.append(object->getTE(i)->asLLSD()); + } + prim_llsd["textures"] = te_llsd; + + std::map::iterator pos = (*mPrimNameMap).find(object->getLocalID()); + if(pos != (*mPrimNameMap).end()) + prim_llsd["name"] = (*mPrimNameMap)[object->getLocalID()]; + + llsd[llformat("%d", object->getLocalID())] = prim_llsd; + } + + return llsd; + } + else if(mType == EXPORTABLE_WEARABLE) + { + LLSD llsd; // pointless map with single key/value + + LLSD item_sd; // map for wearable + + item_sd["type"] = "wearable"; + + S32 type_s32 = (S32)mWearableType; + std::string wearable_name = LLWearable::typeToTypeName( mWearableType ); + + item_sd["name"] = mAvatar->getFullname() + " " + wearable_name; + item_sd["wearabletype"] = type_s32; + + LLSD param_map; + + for( LLVisualParam* param = mAvatar->getFirstVisualParam(); param; param = mAvatar->getNextVisualParam() ) + { + LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; + if( (viewer_param->getWearableType() == type_s32) && + (viewer_param->isTweakable()) ) + { + param_map[llformat("%d", viewer_param->getID())] = viewer_param->getWeight(); + } + } + + item_sd["params"] = param_map; + + LLSD textures_map; + + for( S32 te = 0; te < LLVOAvatarDefines::TEX_NUM_INDICES; te++ ) + { + if( LLVOAvatar::getTEWearableType( (LLVOAvatarDefines::ETextureIndex)te ) == mWearableType ) + { + LLViewerImage* te_image = mAvatar->getTEImage( te ); + if( te_image ) + { + textures_map[llformat("%d", te)] = te_image->getID(); + } + } + } + + item_sd["textures"] = textures_map; + + // Generate a unique ID for it... + LLUUID myid; + myid.generate(); + + llsd[myid.asString()] = item_sd; + + return llsd; + } + return LLSD(); +} + + + +LLFloaterExport::LLFloaterExport() +: LLFloater() +{ + mSelection = LLSelectMgr::getInstance()->getSelection(); + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_export.xml"); + LLFloaterExport::instances.push_back(this); +} + + +LLFloaterExport::~LLFloaterExport() +{ + std::vector::iterator pos = std::find(LLFloaterExport::instances.begin(), LLFloaterExport::instances.end(), this); + if(pos != LLFloaterExport::instances.end()) + { + LLFloaterExport::instances.erase(pos); + } +} + +BOOL LLFloaterExport::postBuild(void) +{ + if(!mSelection) return TRUE; + if(mSelection->getRootObjectCount() < 1) return TRUE; + + // New stuff: Populate prim name map + + for (LLObjectSelection::valid_iterator iter = mSelection->valid_begin(); + iter != mSelection->valid_end(); iter++) + { + LLSelectNode* nodep = *iter; + LLViewerObject* objectp = nodep->getObject(); + U32 localid = objectp->getLocalID(); + std::string name = nodep->mName; + mPrimNameMap[localid] = name; + } + + // Older stuff + + LLScrollListCtrl* list = getChild("export_list"); + + std::map avatars; + + for (LLObjectSelection::valid_root_iterator iter = mSelection->valid_root_begin(); + iter != mSelection->valid_root_end(); iter++) + { + LLSelectNode* nodep = *iter; + LLViewerObject* objectp = nodep->getObject(); + std::string objectp_id = llformat("%d", objectp->getLocalID()); + + if(list->getItemIndex(objectp->getID()) == -1) + { + bool is_attachment = false; + bool is_root = true; + LLViewerObject* parentp = objectp->getSubParent(); + if(parentp) + { + if(!parentp->isAvatar()) + { + // parent is a prim I guess + is_root = false; + } + else + { + // parent is an avatar + is_attachment = true; + if(!avatars[parentp]) avatars[parentp] = true; + } + } + + bool is_prim = true; + if(objectp->getPCode() >= LL_PCODE_APP) + { + is_prim = false; + } + + bool is_avatar = objectp->isAvatar(); + + + if(is_root && is_prim) + { + LLSD element; + element["id"] = objectp->getID(); + + LLSD& check_column = element["columns"][LIST_CHECKED]; + check_column["column"] = "checked"; + check_column["type"] = "checkbox"; + check_column["value"] = true; + + LLSD& type_column = element["columns"][LIST_TYPE]; + type_column["column"] = "type"; + type_column["type"] = "icon"; + type_column["value"] = "inv_item_object.tga"; + + LLSD& name_column = element["columns"][LIST_NAME]; + name_column["column"] = "name"; + if(is_attachment) + name_column["value"] = nodep->mName + " (worn on " + utf8str_tolower(objectp->getAttachmentPointName()) + ")"; + else + name_column["value"] = nodep->mName; + + LLSD& avatarid_column = element["columns"][LIST_AVATARID]; + avatarid_column["column"] = "avatarid"; + if(is_attachment) + avatarid_column["value"] = parentp->getID(); + else + avatarid_column["value"] = LLUUID::null; + + LLExportable* exportable = new LLExportable(objectp, nodep->mName, mPrimNameMap); + mExportables[objectp->getID()] = exportable->asLLSD(); + + list->addElement(element, ADD_BOTTOM); + + addToPrimList(objectp); + } + else if(is_avatar) + { + if(!avatars[objectp]) + { + avatars[objectp] = true; + } + } + } + } + std::map::iterator avatar_iter = avatars.begin(); + std::map::iterator avatars_end = avatars.end(); + for( ; avatar_iter != avatars_end; avatar_iter++) + { + LLViewerObject* avatar = (*avatar_iter).first; + addAvatarStuff((LLVOAvatar*)avatar); + } + + updateNamesProgress(); + + childSetAction("select_all_btn", onClickSelectAll, this); + childSetAction("select_objects_btn", onClickSelectObjects, this); + childSetAction("select_wearables_btn", onClickSelectWearables, this); + + childSetAction("save_as_btn", onClickSaveAs, this); + childSetAction("make_copy_btn", onClickMakeCopy, this); + + return TRUE; +} + +void LLFloaterExport::addAvatarStuff(LLVOAvatar* avatarp) +{ + LLScrollListCtrl* list = getChild("export_list"); + for( S32 type = WT_SHAPE; type < WT_COUNT; type++ ) + { + // guess whether this wearable actually exists + // by checking whether it has any textures that aren't default + bool exists = false; + if(type == WT_SHAPE) + { + exists = true; + } + else if (type == WT_ALPHA || type == WT_TATTOO) //alpha layers and tattos are unsupported for now + { + continue; + } + else + { + for( S32 te = 0; te < LLVOAvatarDefines::TEX_NUM_INDICES; te++ ) + { + if( (S32)LLVOAvatar::getTEWearableType( (LLVOAvatarDefines::ETextureIndex)te ) == type ) + { + LLViewerImage* te_image = avatarp->getTEImage( te ); + if( te_image->getID() != IMG_DEFAULT_AVATAR) + { + exists = true; + break; + } + } + } + } + + if(exists) + { + std::string wearable_name = LLWearable::typeToTypeName( (EWearableType)type ); + std::string name = avatarp->getFullname() + " " + wearable_name; + LLUUID myid; + myid.generate(); + + LLSD element; + element["id"] = myid; + + LLSD& check_column = element["columns"][LIST_CHECKED]; + check_column["column"] = "checked"; + check_column["type"] = "checkbox"; + check_column["value"] = false; + + LLSD& type_column = element["columns"][LIST_TYPE]; + type_column["column"] = "type"; + type_column["type"] = "icon"; + type_column["value"] = "inv_item_" + wearable_name + ".tga"; + + LLSD& name_column = element["columns"][LIST_NAME]; + name_column["column"] = "name"; + name_column["value"] = name; + + LLSD& avatarid_column = element["columns"][LIST_AVATARID]; + avatarid_column["column"] = "avatarid"; + avatarid_column["value"] = avatarp->getID(); + + LLExportable* exportable = new LLExportable(avatarp, (EWearableType)type, mPrimNameMap); + mExportables[myid] = exportable->asLLSD(); + + list->addElement(element, ADD_BOTTOM); + } + } + + // Add attachments + LLViewerObject::child_list_t child_list = avatarp->getChildren(); + for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) + { + LLViewerObject* childp = *i; + if(list->getItemIndex(childp->getID()) == -1) + { + LLSD element; + element["id"] = childp->getID(); + + LLSD& check_column = element["columns"][LIST_CHECKED]; + check_column["column"] = "checked"; + check_column["type"] = "checkbox"; + check_column["value"] = false; + + LLSD& type_column = element["columns"][LIST_TYPE]; + type_column["column"] = "type"; + type_column["type"] = "icon"; + type_column["value"] = "inv_item_object.tga"; + + LLSD& name_column = element["columns"][LIST_NAME]; + name_column["column"] = "name"; + name_column["value"] = "Object (worn on " + utf8str_tolower(childp->getAttachmentPointName()) + ")"; + + LLSD& avatarid_column = element["columns"][LIST_AVATARID]; + avatarid_column["column"] = "avatarid"; + avatarid_column["value"] = avatarp->getID(); + + LLExportable* exportable = new LLExportable(childp, "Object", mPrimNameMap); + mExportables[childp->getID()] = exportable->asLLSD(); + + list->addElement(element, ADD_BOTTOM); + + addToPrimList(childp); + //LLSelectMgr::getInstance()->selectObjectAndFamily(childp, false); + //LLSelectMgr::getInstance()->deselectObjectAndFamily(childp, true, true); + + LLViewerObject::child_list_t select_list = childp->getChildren(); + LLViewerObject::child_list_t::iterator select_iter; + int block_counter; + + gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID()); + block_counter = 0; + for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter) + { + block_counter++; + if(block_counter >= 254) + { + // start a new message + gMessageSystem->sendReliable(childp->getRegion()->getHost()); + gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + } + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID()); + } + gMessageSystem->sendReliable(childp->getRegion()->getHost()); + + gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID()); + block_counter = 0; + for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter) + { + block_counter++; + if(block_counter >= 254) + { + // start a new message + gMessageSystem->sendReliable(childp->getRegion()->getHost()); + gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + } + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID()); + } + gMessageSystem->sendReliable(childp->getRegion()->getHost()); + } + } +} + +//static +void LLFloaterExport::onClickSelectAll(void* user_data) +{ + LLFloaterExport* floater = (LLFloaterExport*)user_data; + LLScrollListCtrl* list = floater->getChild("export_list"); + std::vector items = list->getAllData(); + std::vector::iterator item_iter = items.begin(); + std::vector::iterator items_end = items.end(); + bool new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue()); + for( ; item_iter != items_end; ++item_iter) + { + LLScrollListItem* item = (*item_iter); + item->getColumn(LIST_CHECKED)->setValue(new_value); + } +} + +//static +void LLFloaterExport::onClickSelectObjects(void* user_data) +{ + LLFloaterExport* floater = (LLFloaterExport*)user_data; + LLScrollListCtrl* list = floater->getChild("export_list"); + std::vector items = list->getAllData(); + std::vector::iterator item_iter = items.begin(); + std::vector::iterator items_end = items.end(); + bool new_value = false; + for( ; item_iter != items_end; ++item_iter) + { + if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga") + { + new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue()); + break; + } + } + for(item_iter = items.begin(); item_iter != items_end; ++item_iter) + { + if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga") + { + LLScrollListItem* item = (*item_iter); + item->getColumn(LIST_CHECKED)->setValue(new_value); + } + } +} + +//static +void LLFloaterExport::onClickSelectWearables(void* user_data) +{ + LLFloaterExport* floater = (LLFloaterExport*)user_data; + LLScrollListCtrl* list = floater->getChild("export_list"); + std::vector items = list->getAllData(); + std::vector::iterator item_iter = items.begin(); + std::vector::iterator items_end = items.end(); + bool new_value = false; + for( ; item_iter != items_end; ++item_iter) + { + if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga") + { + new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue()); + break; + } + } + for(item_iter = items.begin(); item_iter != items_end; ++item_iter) + { + if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga") + { + LLScrollListItem* item = (*item_iter); + item->getColumn(LIST_CHECKED)->setValue(new_value); + } + } +} + +LLSD LLFloaterExport::getLLSD() +{ + LLScrollListCtrl* list = getChild("export_list"); + std::vector items = list->getAllData(); + LLSD sd; + std::vector::iterator item_iter = items.begin(); + std::vector::iterator items_end = items.end(); + for( ; item_iter != items_end; ++item_iter) + { + LLScrollListItem* item = (*item_iter); + if(item->getColumn(LIST_CHECKED)->getValue()) + { + LLSD item_sd = mExportables[item->getUUID()]; + LLSD::map_iterator map_iter = item_sd.beginMap(); + LLSD::map_iterator map_end = item_sd.endMap(); + for( ; map_iter != map_end; ++map_iter) + { + std::string key((*map_iter).first); + LLSD data = (*map_iter).second; + // copy it... + sd[key] = data; + } + } + } + return sd; +} + +//static +void LLFloaterExport::onClickSaveAs(void* user_data) +{ + LLFloaterExport* floater = (LLFloaterExport*)user_data; + LLSD sd = floater->getLLSD(); + + if(sd.size()) + { + std::string default_filename = "untitled"; + + // count the number of selected items + LLScrollListCtrl* list = floater->getChild("export_list"); + std::vector items = list->getAllData(); + int item_count = 0; + LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID(); + bool all_same_avatarid = true; + std::vector::iterator item_iter = items.begin(); + std::vector::iterator items_end = items.end(); + for( ; item_iter != items_end; ++item_iter) + { + LLScrollListItem* item = (*item_iter); + if(item->getColumn(LIST_CHECKED)->getValue()) + { + item_count++; + if(item->getColumn(LIST_AVATARID)->getValue().asUUID() != avatarid) + { + all_same_avatarid = false; + } + } + } + + if(item_count == 1) + { + // Exporting one item? Use its name for the filename. + // But make sure it's a root! + LLSD target = (*(sd.beginMap())).second; + if(target.has("parent")) + { + std::string parentid = target["parent"].asString(); + target = sd[parentid]; + } + if(target.has("name")) + { + if(target["name"].asString().length() > 0) + { + default_filename = target["name"].asString(); + } + } + } + else + { + // Multiple items? + // If they're all part of the same avatar, use the avatar's name as filename. + if(all_same_avatarid) + { + std::string fullname; + if(gCacheName->getFullName(avatarid, fullname)) + { + default_filename = fullname; + } + } + } + + LLFilePicker& file_picker = LLFilePicker::instance(); + if(file_picker.getSaveFile( LLFilePicker::FFSAVE_XML, LLDir::getScrubbedFileName(default_filename + ".xml"))) + { + std::string file_name = file_picker.getFirstFile(); + std::string path = file_name.substr(0,file_name.find_last_of(".")) + "_assets"; + BOOL download_texture = floater->childGetValue("download_textures"); + if(download_texture) + { + if(!LLFile::isdir(path)) + { + LLFile::mkdir(path); + }else + { + U32 response = OSMessageBox("Directory "+path+" already exists, would you like to continue and override files?", "Directory Already Exists", OSMB_YESNO); + if(response) + { + return; + } + } + path.append(gDirUtilp->getDirDelimiter()); //lets add the Delimiter now + } + // set correct names within llsd and download textures + LLSD::map_iterator map_iter = sd.beginMap(); + LLSD::map_iterator map_end = sd.endMap(); + std::list textures; + + for( ; map_iter != map_end; ++map_iter) + { + std::istringstream keystr((*map_iter).first); + U32 key; + keystr >> key; + LLSD item = (*map_iter).second; + if(item["type"].asString() == "prim") + { + std::string name = floater->mPrimNameMap[key]; + item["name"] = name; + // I don't understand C++ :( + sd[(*map_iter).first] = item; + + if(download_texture) + { + //textures + LLSD::array_iterator tex_iter = item["textures"].beginArray(); + for( ; tex_iter != item["textures"].endArray(); ++tex_iter) + { + textures.push_back((*tex_iter)["imageid"].asUUID()); + } + if(item.has("sculpt")) + { + textures.push_back(item["sculpt"]["texture"].asUUID()); + } + } + } + else if(download_texture && item["type"].asString() == "wearable") + { + LLSD::map_iterator tex_iter = item["textures"].beginMap(); + for( ; tex_iter != item["textures"].endMap(); ++tex_iter) + { + textures.push_back((*tex_iter).second.asUUID()); + } + } + } + if(download_texture) + { + textures.unique(); + while(!textures.empty()) + { + llinfos << "Requesting texture " << textures.front().asString() << llendl; + LLViewerImage* img = gImageList.getImage(textures.front(), MIPMAP_TRUE, FALSE); + img->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAX_LEVEL); + + CacheReadResponder* responder = new CacheReadResponder(textures.front(), std::string(path + textures.front().asString() + ".j2c")); + LLAppViewer::getTextureCache()->readFromCache(textures.front(),LLWorkerThread::PRIORITY_HIGH,0,999999,responder); + textures.pop_front(); + } + } + + llofstream export_file(file_name); + LLSDSerialize::toPrettyXML(sd, export_file); + export_file.close(); + + std::string msg = "Saved "; + msg.append(file_name); + if(download_texture) msg.append(" (Content might take some time to download)"); + LLChat chat(msg); + LLFloaterChat::addChat(chat); + } + } + else + { + std::string msg = "No exportable items selected"; + LLChat chat(msg); + LLFloaterChat::addChat(chat); + return; + } + + floater->close(); +} + +//static +void LLFloaterExport::onClickMakeCopy(void* user_data) +{ + LLFloaterExport* floater = (LLFloaterExport*)user_data; + LLSD sd = floater->getLLSD(); + + if(sd.size()) + { + LLXmlImport::import(new LLXmlImportOptions(sd)); + } + else + { + std::string msg = "No copyable items selected"; + LLChat chat(msg); + LLFloaterChat::addChat(chat); + return; + } + + // I guess close the floater because only one import is allowed at once anyway + floater->close(); +} + +void LLFloaterExport::addToPrimList(LLViewerObject* object) +{ + mPrimList.push_back(object->getLocalID()); + LLViewerObject::child_list_t child_list = object->getChildren(); + for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) + { + LLViewerObject* child = *i; + if(child->getPCode() < LL_PCODE_APP) + { + mPrimList.push_back(child->getLocalID()); + } + } +} + +void LLFloaterExport::updateNamesProgress() +{ + childSetText("names_progress_text", llformat("Names retrieved: %d of %d", mPrimNameMap.size(), mPrimList.size())); +} + +void LLFloaterExport::receivePrimName(LLViewerObject* object, std::string name) +{ + LLUUID fullid = object->getID(); + U32 localid = object->getLocalID(); + if(std::find(mPrimList.begin(), mPrimList.end(), localid) != mPrimList.end()) + { + mPrimNameMap[localid] = name; + LLScrollListCtrl* list = getChild("export_list"); + S32 item_index = list->getItemIndex(fullid); + if(item_index != -1) + { + std::vector items = list->getAllData(); + std::vector::iterator iter = items.begin(); + std::vector::iterator end = items.end(); + for( ; iter != end; ++iter) + { + if((*iter)->getUUID() == fullid) + { + (*iter)->getColumn(LIST_NAME)->setValue(name + " (worn on " + utf8str_tolower(object->getAttachmentPointName()) + ")"); + break; + } + } + } + updateNamesProgress(); + } +} + +// static +void LLFloaterExport::receiveObjectProperties(LLUUID fullid, std::string name, std::string desc) +{ + LLViewerObject* object = gObjectList.findObject(fullid); + std::vector::iterator iter = LLFloaterExport::instances.begin(); + std::vector::iterator end = LLFloaterExport::instances.end(); + for( ; iter != end; ++iter) + { + (*iter)->receivePrimName(object, name); + } +} + +// diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index dc188edfc..9b050b9b5 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2968,7 +2968,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation() param; param = getNextVisualParam()) { - if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (param->isTweakable()) { param->stopAnimating(mAppearanceAnimSetByUser); } @@ -3007,7 +3007,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation() param; param = getNextVisualParam()) { - if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + if (param->isTweakable()) { param->animate(morph_amt, mAppearanceAnimSetByUser); } @@ -6252,6 +6252,7 @@ BOOL LLVOAvatar::loadAvatar() if (sAvatarXmlInfo->mLayerInfoList.empty()) { llwarns << "avatar file: missing node" << llendl; + return FALSE; } else { @@ -6292,23 +6293,21 @@ BOOL LLVOAvatar::loadAvatar() } // avatar_lad.xml : + LLVOAvatarXmlInfo::driver_info_list_t::iterator iter; + for (iter = sAvatarXmlInfo->mDriverInfoList.begin(); + iter != sAvatarXmlInfo->mDriverInfoList.end(); iter++) { - LLVOAvatarXmlInfo::driver_info_list_t::iterator iter; - for (iter = sAvatarXmlInfo->mDriverInfoList.begin(); - iter != sAvatarXmlInfo->mDriverInfoList.end(); iter++) + LLDriverParamInfo *info = *iter; + LLDriverParam* driver_param = new LLDriverParam( this ); + if (driver_param->setInfo(info)) { - LLDriverParamInfo *info = *iter; - LLDriverParam* driver_param = new LLDriverParam( this ); - if (driver_param->setInfo(info)) - { - addVisualParam( driver_param ); - } - else - { - delete driver_param; - llwarns << "avatar file: driver_param->parseData() failed" << llendl; - return FALSE; - } + addVisualParam( driver_param ); + } + else + { + delete driver_param; + llwarns << "avatar file: driver_param->parseData() failed" << llendl; + return FALSE; } } @@ -9147,7 +9146,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) for( S32 i = 0; i < num_blocks; i++ ) { - while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) + while( param && (!param->isTweakable()) ) { param = getNextVisualParam(); } @@ -9155,7 +9154,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) if( !param ) { llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file for " << getFullname() << " (Too many)." << llendl; - return; + break; } U8 value; @@ -9198,7 +9197,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } } - while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) + while( param && (!param->isTweakable()) ) { param = getNextVisualParam(); } @@ -9476,8 +9475,8 @@ void LLVOAvatar::dumpArchetypeXML( void* ) for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; - if( (viewer_param->getWearableType() == type) && - (viewer_param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) ) + if( (viewer_param->getWearableType() == type) && + (viewer_param->isTweakable() ) ) { apr_file_printf( file, "\t\t\n", viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight() ); diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index d95d4086e..d64ae5eaa 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -494,7 +494,7 @@ BOOL LLWearable::isOldVersion() param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { - if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (param->getWearableType() == mType) && (param->isTweakable()) ) { param_count++; if( !is_in_map(mVisualParamMap, param->getID() ) ) @@ -550,7 +550,7 @@ BOOL LLWearable::isDirty() param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { - if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (param->getWearableType() == mType) && (param->isTweakable()) ) { F32 weight = get_if_there(mVisualParamMap, param->getID(), param->getDefaultWeight()); weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); @@ -651,7 +651,7 @@ void LLWearable::setParamsToDefaults() mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { - if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable()) ) { mVisualParamMap[param->getID()] = param->getDefaultWeight(); } @@ -685,7 +685,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) // Pull params for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { - if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->isTweakable()) ) { S32 param_id = param->getID(); F32 weight = get_if_there(mVisualParamMap, param_id, param->getDefaultWeight()); @@ -786,7 +786,7 @@ void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user ) // Pull params for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { - if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable()) ) { S32 param_id = param->getID(); avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user ); @@ -834,7 +834,7 @@ void LLWearable::readFromAvatar() mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { - if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->isTweakable()) ) { //pretty sure is right @@ -899,7 +899,7 @@ void LLWearable::copyDataFrom( LLWearable* src ) param; param = (LLViewerVisualParam*) avatar->getNextVisualParam() ) { - if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) + if( (param->getWearableType() == mType) && (param->isTweakable()) ) { S32 id = param->getID(); F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() );