diff options
-rw-r--r-- | indra/llappearance/llavatarappearancedefines.cpp | 79 | ||||
-rw-r--r-- | indra/llappearance/llavatarappearancedefines.h | 4 | ||||
-rw-r--r-- | indra/llcommon/indra_constants.cpp | 7 | ||||
-rw-r--r-- | indra/llcommon/indra_constants.h | 7 | ||||
-rw-r--r-- | indra/newview/lldynamictexture.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llpanelface.cpp | 88 | ||||
-rw-r--r-- | indra/newview/llselectmgr.cpp | 3 | ||||
-rw-r--r-- | indra/newview/lltexturectrl.cpp | 185 | ||||
-rw-r--r-- | indra/newview/lltexturectrl.h | 8 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 92 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 4 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 171 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 3 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_texture_ctrl.xml | 72 |
14 files changed, 670 insertions, 55 deletions
diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp index b5282d4f6f..c9b975a9cc 100644 --- a/indra/llappearance/llavatarappearancedefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -26,9 +26,10 @@ #include "linden_common.h" #include "llavatarappearancedefines.h" +#include "indra_constants.h" -const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512; -const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512; +const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 1024; +const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 1024; const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2; using namespace LLAvatarAppearanceDefines; @@ -265,3 +266,77 @@ LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIn { return getInstance()->getTexture(index)->mWearableType; } + +// static +BOOL LLAvatarAppearanceDictionary::isBakedImageId(const LLUUID& id) +{ + if ((id == IMG_USE_BAKED_EYES) || (id == IMG_USE_BAKED_HAIR) || (id == IMG_USE_BAKED_HEAD) || (id == IMG_USE_BAKED_LOWER) || (id == IMG_USE_BAKED_SKIRT) || (id == IMG_USE_BAKED_UPPER)) + { + return TRUE; + } + + return FALSE; +} + +// static +EBakedTextureIndex LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(const LLUUID& id) +{ + if (id == IMG_USE_BAKED_EYES) + { + return BAKED_EYES; + } + else if (id == IMG_USE_BAKED_HAIR) + { + return BAKED_HAIR; + } + else if (id == IMG_USE_BAKED_HEAD) + { + return BAKED_HEAD; + } + else if (id == IMG_USE_BAKED_LOWER) + { + return BAKED_LOWER; + } + else if (id == IMG_USE_BAKED_SKIRT) + { + return BAKED_SKIRT; + } + else if (id == IMG_USE_BAKED_UPPER) + { + return BAKED_UPPER; + } + + return BAKED_NUM_INDICES; +} + +//static +LLUUID LLAvatarAppearanceDictionary::localTextureIndexToMagicId(ETextureIndex t) +{ + LLUUID id = LLUUID::null; + + switch (t) + { + case LLAvatarAppearanceDefines::TEX_HEAD_BAKED: + id = IMG_USE_BAKED_HEAD; + break; + case LLAvatarAppearanceDefines::TEX_UPPER_BAKED: + id = IMG_USE_BAKED_UPPER; + break; + case LLAvatarAppearanceDefines::TEX_LOWER_BAKED: + id = IMG_USE_BAKED_LOWER; + break; + case LLAvatarAppearanceDefines::TEX_EYES_BAKED: + id = IMG_USE_BAKED_EYES; + break; + case LLAvatarAppearanceDefines::TEX_SKIRT_BAKED: + id = IMG_USE_BAKED_SKIRT; + break; + case LLAvatarAppearanceDefines::TEX_HAIR_BAKED: + id = IMG_USE_BAKED_HAIR; + break; + default: + break; + } + + return id; +} diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h index d6223bb4d2..af94ea94f2 100644 --- a/indra/llappearance/llavatarappearancedefines.h +++ b/indra/llappearance/llavatarappearancedefines.h @@ -223,6 +223,10 @@ public: // Given a texture entry, determine which wearable type owns it. static LLWearableType::EType getTEWearableType(ETextureIndex index); + static BOOL isBakedImageId(const LLUUID& id); + static EBakedTextureIndex assetIdToBakedTextureIndex(const LLUUID& id); + static LLUUID localTextureIndexToMagicId(ETextureIndex t); + }; // End LLAvatarAppearanceDictionary } // End namespace LLAvatarAppearanceDefines diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp index 7ea42a3fc0..a9bdab9f4e 100644 --- a/indra/llcommon/indra_constants.cpp +++ b/indra/llcommon/indra_constants.cpp @@ -72,3 +72,10 @@ const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // V const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER +const LLUUID IMG_USE_BAKED_HEAD ("11c5d053-0ea9-a529-46cb-351d4e84d17a"); +const LLUUID IMG_USE_BAKED_UPPER ("149e7c88-74ef-995b-5e23-a27208de3193"); +const LLUUID IMG_USE_BAKED_LOWER ("066d5659-0856-748e-a6de-495d896fe93b"); +const LLUUID IMG_USE_BAKED_EYES ("136c0789-b42c-4c6c-134b-63669d981fcb"); +const LLUUID IMG_USE_BAKED_SKIRT ("baf656f8-0b45-a85a-244e-f3bdb835f1a2"); +const LLUUID IMG_USE_BAKED_HAIR ("1ba5b07f-2d59-21ed-066c-1e188f9a8cad"); + diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index fda84aa5a8..28e55b2091 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -207,6 +207,13 @@ LL_COMMON_API extern const LLUUID TERRAIN_GRASS_DETAIL; LL_COMMON_API extern const LLUUID TERRAIN_MOUNTAIN_DETAIL; LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_HEAD; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_UPPER; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_LOWER; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_EYES; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_SKIRT; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_HAIR; + LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index fa9a0712fa..8ef0dd2865 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -125,7 +125,7 @@ BOOL LLViewerDynamicTexture::render() //----------------------------------------------------------------------------- void LLViewerDynamicTexture::preRender(BOOL clear_depth) { - //only images up to 512x512 are supported + //only images up to 1024*1024 are supported llassert(mFullHeight <= 512); llassert(mFullWidth <= 512); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 7e75dca908..5689c44e21 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -867,41 +867,75 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } updateAlphaControls(); - - if(texture_ctrl) - { + + if (texture_ctrl) + { if (identical_diffuse) { - texture_ctrl->setTentative( FALSE ); - texture_ctrl->setEnabled( editable ); - texture_ctrl->setImageAssetID( id ); + texture_ctrl->setTentative(FALSE); + texture_ctrl->setEnabled(editable); + texture_ctrl->setImageAssetID(id); getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); getChildView("label alphamode")->setEnabled(editable && mIsAlpha); getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); - } - else if (id.isNull()) + + bool allAttachments = true; + for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); + iter != LLSelectMgr::getInstance()->getSelection()->end();iter++) { - // None selected - texture_ctrl->setTentative( FALSE ); - texture_ctrl->setEnabled( FALSE ); - texture_ctrl->setImageAssetID( LLUUID::null ); - getChildView("combobox alphamode")->setEnabled( FALSE ); - getChildView("label alphamode")->setEnabled( FALSE ); - getChildView("maskcutoff")->setEnabled( FALSE); - getChildView("label maskcutoff")->setEnabled( FALSE ); + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if (!object->isAttachment()) + { + allAttachments = false; + break; + } } - else - { - // Tentative: multiple selected with different textures - texture_ctrl->setTentative( TRUE ); - texture_ctrl->setEnabled( editable ); - texture_ctrl->setImageAssetID( id ); + + texture_ctrl->setBakeTextureEnabled(allAttachments); + + } + else if (id.isNull()) + { + // None selected + texture_ctrl->setTentative(FALSE); + texture_ctrl->setEnabled(FALSE); + texture_ctrl->setImageAssetID(LLUUID::null); + getChildView("combobox alphamode")->setEnabled(FALSE); + getChildView("label alphamode")->setEnabled(FALSE); + getChildView("maskcutoff")->setEnabled(FALSE); + getChildView("label maskcutoff")->setEnabled(FALSE); + + texture_ctrl->setBakeTextureEnabled(false); + } + else + { + // Tentative: multiple selected with different textures + texture_ctrl->setTentative(TRUE); + texture_ctrl->setEnabled(editable); + texture_ctrl->setImageAssetID(id); getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); getChildView("label alphamode")->setEnabled(editable && mIsAlpha); getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + + bool allAttachments = true; + for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); + iter != LLSelectMgr::getInstance()->getSelection()->end();iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if (!object->isAttachment()) + { + allAttachments = false; + break; + } + } + + texture_ctrl->setBakeTextureEnabled(allAttachments); } + } if (shinytexture_ctrl) @@ -2467,6 +2501,15 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) { LLUUID get(LLViewerObject* object, S32 te_index) { + LLTextureEntry *te = object->getTE(te_index); + if (te) + { + if ((te->getID() == IMG_USE_BAKED_EYES) || (te->getID() == IMG_USE_BAKED_HAIR) || (te->getID() == IMG_USE_BAKED_HEAD) || (te->getID() == IMG_USE_BAKED_LOWER) || (te->getID() == IMG_USE_BAKED_SKIRT) || (te->getID() == IMG_USE_BAKED_UPPER)) + { + return te->getID(); + } + } + LLUUID id; LLViewerTexture* image = object->getTEImage(te_index); if (image) @@ -2476,7 +2519,6 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) { - LLTextureEntry *te = object->getTE(te_index); if (te) { LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index c44aca6fa5..1eddf92ddf 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -95,6 +95,7 @@ #include "llviewershadermgr.h" #include "llpanelface.h" #include "llglheaders.h" +#include "llinventoryobserver.h" LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; // @@ -1647,6 +1648,7 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) // * Can just apply the texture and be done with it. objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); } + return true; } }; @@ -1846,6 +1848,7 @@ BOOL LLSelectMgr::selectionRevertTextures() else { object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + } } } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index c7adaa908f..0c823931c1 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -32,6 +32,7 @@ #include "llrender.h" #include "llagent.h" #include "llviewertexturelist.h" +#include "llselectmgr.h" #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llbutton.h" @@ -404,6 +405,10 @@ BOOL LLFloaterTexturePicker::postBuild() LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); + getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this); + getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setCommitCallback(onHideBaseMeshRegionCheck, this); + + setBakeTextureEnabled(FALSE); return TRUE; } @@ -478,7 +483,24 @@ void LLFloaterTexturePicker::draw() mTexturep = NULL; if(mImageAssetID.notNull()) { - mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID); + LLPointer<LLViewerFetchedTexture> texture = NULL; + + if ((mImageAssetID == IMG_USE_BAKED_EYES) || (mImageAssetID == IMG_USE_BAKED_HAIR) || (mImageAssetID == IMG_USE_BAKED_HEAD) || (mImageAssetID == IMG_USE_BAKED_LOWER) || (mImageAssetID == IMG_USE_BAKED_SKIRT) || (mImageAssetID == IMG_USE_BAKED_UPPER)) + { + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (obj) + { + LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); + texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL; + } + } + + if (texture.isNull()) + { + texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID); + } + + mTexturep = texture; mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); } @@ -760,22 +782,58 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - bool mode = (self->mModeSelector->getSelectedIndex() == 0); + int mode = self->mModeSelector->getSelectedIndex(); - self->getChild<LLButton>("Default")->setVisible(mode); - self->getChild<LLButton>("Blank")->setVisible(mode); - self->getChild<LLButton>("None")->setVisible(mode); - self->getChild<LLButton>("Pipette")->setVisible(mode); - self->getChild<LLFilterEditor>("inventory search editor")->setVisible(mode); - self->getChild<LLInventoryPanel>("inventory panel")->setVisible(mode); + self->getChild<LLButton>("Default")->setVisible(mode == 0); + self->getChild<LLButton>("Blank")->setVisible(mode == 0); + self->getChild<LLButton>("None")->setVisible(mode == 0); + self->getChild<LLButton>("Pipette")->setVisible(mode == 0); + self->getChild<LLFilterEditor>("inventory search editor")->setVisible(mode == 0); + self->getChild<LLInventoryPanel>("inventory panel")->setVisible(mode == 0); /*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode); no idea under which conditions the above is even shown, needs testing. */ - self->getChild<LLButton>("l_add_btn")->setVisible(!mode); - self->getChild<LLButton>("l_rem_btn")->setVisible(!mode); - self->getChild<LLButton>("l_upl_btn")->setVisible(!mode); - self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(!mode); + self->getChild<LLButton>("l_add_btn")->setVisible(mode == 1); + self->getChild<LLButton>("l_rem_btn")->setVisible(mode == 1); + self->getChild<LLButton>("l_upl_btn")->setVisible(mode == 1); + self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(mode == 1); + + self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setVisible(mode == 2); + self->getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setVisible(false);// mode == 2); + + if (mode == 2) + { + S8 val = -1; + + LLUUID imageID = self->mImageAssetID; + if (imageID == IMG_USE_BAKED_HEAD) + { + val = 0; + } + else if (imageID == IMG_USE_BAKED_UPPER) + { + val = 1; + } + else if (imageID == IMG_USE_BAKED_LOWER) + { + val = 2; + } + else if (imageID == IMG_USE_BAKED_EYES) + { + val = 3; + } + else if (imageID == IMG_USE_BAKED_SKIRT) + { + val = 4; + } + else if (imageID == IMG_USE_BAKED_HAIR) + { + val = 5; + } + + self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setSelectedByValue(val, TRUE); + } } // static @@ -896,6 +954,66 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da picker->commitIfImmediateSet(); } +//static +void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)user_data; + LLComboBox* combo_box = (LLComboBox*)ctrl; + + S8 type = combo_box->getValue().asInteger(); + + LLUUID imageID = self->mDefaultImageAssetID; + if (type == 0) + { + imageID = IMG_USE_BAKED_HEAD; + } + else if (type == 1) + { + imageID = IMG_USE_BAKED_UPPER; + } + else if (type == 2) + { + imageID = IMG_USE_BAKED_LOWER; + } + else if (type == 3) + { + imageID = IMG_USE_BAKED_EYES; + } + else if (type == 4) + { + imageID = IMG_USE_BAKED_SKIRT; + } + else if (type == 5) + { + imageID = IMG_USE_BAKED_HAIR; + } + + self->setImageID(imageID); + self->mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? + + if (!self->mPreviewSettingChanged) + { + self->mCanPreview = gSavedSettings.getBOOL("TextureLivePreview"); + } + else + { + self->mPreviewSettingChanged = false; + } + + if (self->mCanPreview) + { + // only commit intentional selections, not implicit ones + self->commitIfImmediateSet(); + } +} + +//static +void LLFloaterTexturePicker::onHideBaseMeshRegionCheck(LLUICtrl* ctrl, void *user_data) +{ + //LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data; + //LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; +} + void LLFloaterTexturePicker::updateFilterPermMask() { //mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss. @@ -951,6 +1069,13 @@ void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled) mModeSelector->setIndexEnabled(1,enabled); } +void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) +{ + mModeSelector->setIndexEnabled(2, enabled); + mModeSelector->setSelectedIndex(mModeSelector->getSelectedIndex(), 0); + onModeSelect(0, this); +} + void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) { LLUUID inventory_item_id = findItemID(te.getID(), TRUE); @@ -999,7 +1124,8 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) mImageAssetID(p.image_id), mDefaultImageAssetID(p.default_image_id), mDefaultImageName(p.default_image_name), - mFallbackImage(p.fallback_image) + mFallbackImage(p.fallback_image), + mBakeTextureEnabled(FALSE) { // Default of defaults is white image for diff tex @@ -1191,6 +1317,10 @@ void LLTextureCtrl::showPicker(BOOL take_focus) { texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1)); } + if (texture_floaterp) + { + texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled); + } LLFloater* root_floater = gFloaterView->getParentFloater(this); if (root_floater) @@ -1359,6 +1489,17 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) } } +void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled) +{ + mBakeTextureEnabled = enabled; + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + if (floaterp) + { + floaterp->setBakeTextureEnabled(enabled); + floaterp->resetDirty(); + } +} + BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, @@ -1413,7 +1554,23 @@ void LLTextureCtrl::draw() } else if (!mImageAssetID.isNull()) { - LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES,LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LLPointer<LLViewerFetchedTexture> texture = NULL; + + if ((mImageAssetID == IMG_USE_BAKED_EYES) || (mImageAssetID == IMG_USE_BAKED_HAIR) || (mImageAssetID == IMG_USE_BAKED_HEAD) || (mImageAssetID == IMG_USE_BAKED_LOWER) || (mImageAssetID == IMG_USE_BAKED_SKIRT) || (mImageAssetID == IMG_USE_BAKED_UPPER)) + { + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (obj) + { + LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); + texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL; + } + + } + + if (texture.isNull()) + { + texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW); texture->forceToSaveRawImage(0) ; diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 840feddfaf..b43ad69687 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -198,6 +198,8 @@ public: LLViewerFetchedTexture* getTexture() { return mTexturep; } + void setBakeTextureEnabled(BOOL enabled); + private: BOOL allowDrop(LLInventoryItem* item); BOOL doDrop(LLInventoryItem* item); @@ -233,6 +235,7 @@ private: BOOL mShowLoadingPlaceholder; std::string mLoadingPlaceholderString; S32 mLabelWidth; + BOOL mBakeTextureEnabled; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -322,7 +325,11 @@ public: static void onBtnUpload(void* userdata); static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata); + static void onBakeTextureSelect(LLUICtrl* ctrl, void *userdata); + static void onHideBaseMeshRegionCheck(LLUICtrl* ctrl, void *userdata); + void setLocalTextureEnabled(BOOL enabled); + void setBakeTextureEnabled(BOOL enabled); protected: LLPointer<LLViewerTexture> mTexturep; @@ -364,6 +371,7 @@ private: bool mCanPreview; bool mPreviewSettingChanged; + texture_selected_callback mTextureSelectedCallback; floater_close_callback mOnFloaterCloseCallback; floater_commit_callback mOnFloaterCommitCallback; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 5d49c888cf..37e6fa080a 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4366,29 +4366,106 @@ void LLViewerObject::sendTEUpdate() const msg->sendReliable( regionp->getHost() ); } +LLViewerTexture* LLViewerObject::getBakedTextureForMagicId(const LLUUID& id) +{ + if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) + { + return NULL; + } + + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + LLAvatarAppearanceDefines::ETextureIndex texIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(id)); + LLViewerTexture* bakedTexture = avatar->getBakedTextureImage(texIndex, avatar->getTE(texIndex)->getID()); + if (bakedTexture == NULL || bakedTexture->isMissingAsset()) + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } + else + { + return bakedTexture; + } + } + else + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } + + return NULL; +} + +void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id) +{ + if (id == old_id) + { + return; + } + + if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(old_id) && !LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) + { + return; + } + + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + avatar->updateMeshVisibility(); + } +} + void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) { + LLUUID old_image_id; + if (getTE(te)) + { + old_image_id = getTE(te)->getID(); + } + LLPrimitive::setTE(te, texture_entry); - const LLUUID& image_id = getTE(te)->getID(); - mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + const LLUUID& image_id = getTE(te)->getID(); + LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); + mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + updateAvatarMeshVisibility(image_id,old_image_id); + if (getTE(te)->getMaterialParams().notNull()) { const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - + const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); } } +void LLViewerObject::refreshBakeTexture() +{ + for (int face_index = 0; face_index < getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = getTE(face_index); + if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) + { + const LLUUID& image_id = tex_entry->getID(); + LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); + changeTEImage(face_index, bakedTexture); + } + } +} + void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) { if (mTEImages[te] != imagep) { - mTEImages[te] = imagep; + LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null; + LLPrimitive::setTETexture(te, imagep->getID()); + + LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID()); + mTEImages[te] = baked_texture ? baked_texture : imagep; + updateAvatarMeshVisibility(imagep->getID(), old_image_id); setChanged(TEXTURE); if (mDrawable.notNull()) { @@ -4399,13 +4476,16 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image) { + LLUUID old_image_id = getTE(te)->getID(); const LLUUID& uuid = image->getID(); S32 retval = 0; if (uuid != getTE(te)->getID() || uuid == LLUUID::null) { retval = LLPrimitive::setTETexture(te, uuid); - mTEImages[te] = image; + LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid); + mTEImages[te] = baked_texture ? baked_texture : image; + updateAvatarMeshVisibility(uuid,old_image_id); setChanged(TEXTURE); if (mDrawable.notNull()) { @@ -4496,7 +4576,7 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid) // Invalid host == get from the agent's sim LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture( uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); - return setTETextureCore(te,image); + return setTETextureCore(te, image); } S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 21c95d5533..a9035c71e1 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -569,6 +569,10 @@ public: friend class LLViewerMediaList; public: + LLViewerTexture* getBakedTextureForMagicId(const LLUUID& id); + void updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id); + void refreshBakeTexture(); +public: static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name); static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name); static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index eae8f2cc56..5951733634 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2224,6 +2224,7 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU { result->setIsMissingAsset(false); } + } return result; } @@ -6429,6 +6430,22 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o LLSelectMgr::getInstance()->updatePointAt(); } + viewer_object->refreshBakeTexture(); + + + LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + + updateMeshVisibility(); + return attachment; } @@ -6568,7 +6585,6 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) //----------------------------------------------------------------------------- BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) @@ -6577,10 +6593,25 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) if (attachment->isObjectAttached(viewer_object)) { - updateVisualComplexity(); - cleanupAttachedMesh( viewer_object ); - + updateVisualComplexity(); + cleanupAttachedMesh(viewer_object); + attachment->removeObject(viewer_object); + viewer_object->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectp = *iter1; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + + updateMeshVisibility(); + LL_DEBUGS() << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << LL_ENDL; return TRUE; } @@ -7196,6 +7227,105 @@ void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color) } } + +//----------------------------------------------------------------------------- +// updateMeshVisibility() +// Hide the mesh joints if attachments are using baked textures +//----------------------------------------------------------------------------- +void LLVOAvatar::updateMeshVisibility() +{ + bool bake_flag[BAKED_NUM_INDICES]; + memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool)); + + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *objectp = (*attachment_iter); + if (objectp) + { + for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = objectp->getTE(face_index); + bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); + } + } + + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectchild = *iter1; + if (objectchild) + { + for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = objectchild->getTE(face_index); + bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); + } + } + } + } + } + } + + LL_INFOS() << "head " << bake_flag[BAKED_HEAD] << "eyes " << bake_flag[BAKED_EYES] << "hair " << bake_flag[BAKED_HAIR] << "lower " << bake_flag[BAKED_LOWER] << "upper " << bake_flag[BAKED_UPPER] << "skirt " << bake_flag[BAKED_SKIRT] << LL_ENDL; + + for (S32 i = 0; i < mMeshLOD.size(); i++) + { + LLAvatarJoint* joint = mMeshLOD[i]; + if (i == MESH_ID_HAIR) + { + joint->setVisible(!bake_flag[BAKED_HAIR], TRUE); + } + else if (i == MESH_ID_HEAD) + { + joint->setVisible(!bake_flag[BAKED_HEAD], TRUE); + } + else if (i == MESH_ID_SKIRT) + { + joint->setVisible(!bake_flag[BAKED_SKIRT], TRUE); + } + else if (i == MESH_ID_UPPER_BODY) + { + joint->setVisible(!bake_flag[BAKED_UPPER], TRUE); + } + else if (i == MESH_ID_LOWER_BODY) + { + joint->setVisible(!bake_flag[BAKED_LOWER], TRUE); + } + else if (i == MESH_ID_EYEBALL_LEFT) + { + joint->setVisible(!bake_flag[BAKED_EYES], TRUE); + } + else if (i == MESH_ID_EYEBALL_RIGHT) + { + joint->setVisible(!bake_flag[BAKED_EYES], TRUE); + } + else if (i == MESH_ID_EYELASH) + { + joint->setVisible(!bake_flag[BAKED_EYES], TRUE); + } + } +} + //----------------------------------------------------------------------------- // updateMeshTextures() // Uses the current TE values to set the meshes' and layersets' textures. @@ -7413,6 +7543,9 @@ void LLVOAvatar::updateMeshTextures() removeMissingBakedTextures(); // May call back into this function if anything is removed call_remove_missing = true; } + + + } // virtual @@ -8189,6 +8322,36 @@ void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& conte } updateMeshTextures(); + + //refresh bakes on any attached objects + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = (*attachment_iter); + attached_object->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + } + } + + updateMeshVisibility(); + } // static diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index bd89d4ef23..1b0044201f 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -569,6 +569,7 @@ public: public: /*virtual*/ LLTexLayerSet* createTexLayerSet(); // Return LLViewerTexLayerSet void releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY ! + protected: static void onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); static void onInitialBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); @@ -653,6 +654,8 @@ public: void updateSexDependentLayerSets(); virtual void dirtyMesh(); // Dirty the avatar mesh void updateMeshData(); + void updateMeshVisibility(); + protected: void releaseMeshData(); virtual void restoreMeshData(); diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index 53618b684b..9bce037cba 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -52,7 +52,7 @@ control_name="mode_selection" height="20" layout="topleft" - left="18" + left="0" top_pad="80" name="mode_selection" follows="left|top"> @@ -64,7 +64,7 @@ height="16" left="0" value="0" - width="80" /> + width="70" /> <radio_item label="Local" left_pad="0" @@ -73,7 +73,16 @@ height="16" name="local" value="1" - width="75" /> + width="50" /> + <radio_item + label="Bake" + left_pad="0" + layout="topleft" + top_delta="0" + height="16" + name="bake" + value="2" + width="50" /> </radio_group> <!-- --> @@ -83,7 +92,7 @@ follows="left|top" height="14" layout="topleft" - left_delta="-12" + left_delta="12" name="unknown" top_pad="4"> Size: [DIMENSIONS] @@ -225,7 +234,60 @@ <column name="unit_name" label="Name" dynamicwidth="true" /> <column name="unit_id_HIDDEN" label="ID" width="0" /> </scroll_list> - + +<!-- middle: bake mode --> + <combo_box + left="180" + top="30" + height="19" + top_delta="15" + layout="topleft" + follows="left|top" + name="l_bake_use_texture_combo_box" + tool_tip="Choose the bake texture" + width="108" + visible="false"> + <combo_box.item + label="None" + name="None" + value="-1" /> + <combo_box.item + label="BAKED_HEAD" + name="BAKED_HEAD" + value="0" /> + <combo_box.item + label="BAKED_UPPER" + name="BAKED_UPPER" + value="1" /> + <combo_box.item + label="BAKED_LOWER" + name="BAKED_LOWER" + value="2" /> + <combo_box.item + label="BAKED_EYES" + name="BAKED_EYES" + value="3" /> + <combo_box.item + label="BAKED_SKIRT" + name="BAKED_SKIRT" + value="4" /> + <combo_box.item + label="BAKED_HAIR" + name="BAKED_HAIR" + value="5" /> + </combo_box> + <check_box + follows="left|top" + height="20" + initial_value="false" + label="Hide Base Mesh Region" + layout="topleft" + name="hide_base_mesh_region" + left_delta="0" + top_pad="10" + top_delta="0" + width="120" + visible="false"/> <!-- bottom static --> <button follows="bottom" |