From 722e7d09ff1a4c8623e4e430ad836ef26fcf154a Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 22 Oct 2011 20:36:04 -0500 Subject: [PATCH 1/7] Innitial commit. Majority of texture baking moved into LLVOAvatarSelf. Very WIP. Not advisable to build off of this, although it does compile and mostly work. --- indra/newview/ascentprefsvan.cpp | 6 +- indra/newview/cofmgr.cpp | 7 +- indra/newview/floaterlocalassetbrowse.cpp | 3 +- indra/newview/llagentcamera.cpp | 2 +- indra/newview/llagentwearables.cpp | 9 +- indra/newview/llfloatercustomize.cpp | 38 +- indra/newview/llinventorybridge.cpp | 53 +- indra/newview/llinventorymodel.cpp | 4 +- indra/newview/llmorphview.cpp | 28 +- indra/newview/llpreview.cpp | 5 +- indra/newview/llstartup.cpp | 2 +- indra/newview/lltexlayer.cpp | 22 +- indra/newview/lltexlayer.h | 12 +- indra/newview/lltooldraganddrop.cpp | 4 +- indra/newview/lltoolmorph.cpp | 46 +- indra/newview/llviewercontrol.cpp | 2 +- indra/newview/llviewerjointattachment.cpp | 4 +- indra/newview/llviewermenu.cpp | 183 +-- indra/newview/llviewerstats.cpp | 8 +- indra/newview/llvoavatar.cpp | 1812 +++------------------ indra/newview/llvoavatar.h | 141 +- indra/newview/llvoavatarself.cpp | 1416 ++++++++++++++++ indra/newview/llvoavatarself.h | 157 +- indra/newview/llwearable.cpp | 4 +- indra/newview/rlvhandler.cpp | 2 +- indra/newview/rlvhelper.cpp | 5 +- indra/newview/rlvinventory.cpp | 11 +- 27 files changed, 2018 insertions(+), 1968 deletions(-) diff --git a/indra/newview/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp index 411e159de..abfb5d42b 100644 --- a/indra/newview/ascentprefsvan.cpp +++ b/indra/newview/ascentprefsvan.cpp @@ -98,13 +98,11 @@ void LLPrefsAscentVan::onCommitClientTag(LLUICtrl* ctrl, void* userdata) gSavedSettings.setString("AscentReportClientUUID", client_uuid); gSavedSettings.setU32("AscentReportClientIndex", client_index); - LLVOAvatar* avatar = gAgentAvatarp; - - if (avatar) + if (isAgentAvatarValid()) { // Slam pending upload count to "unstick" things bool slam_for_debug = true; - avatar->forceBakeAllTextures(slam_for_debug); + gAgentAvatarp->forceBakeAllTextures(slam_for_debug); } } } diff --git a/indra/newview/cofmgr.cpp b/indra/newview/cofmgr.cpp index 9de7025f9..4c5abae38 100644 --- a/indra/newview/cofmgr.cpp +++ b/indra/newview/cofmgr.cpp @@ -360,8 +360,7 @@ void LLCOFMgr::onLinkAttachmentComplete(const LLUUID& idItem) void LLCOFMgr::updateAttachments() { - /*const*/ LLVOAvatar* pAvatar = gAgentAvatarp; - if (!pAvatar) + if (!isAgentAvatarValid()) return; const LLUUID idCOF = getCOF(); @@ -375,7 +374,7 @@ void LLCOFMgr::updateAttachments() while (itPendingAttachLink != m_PendingAttachLinks.end()) { const LLUUID& idItem = *itPendingAttachLink; - if ( (!pAvatar->isWearingAttachment(idItem)) || (isLinkInCOF(idItem)) ) + if ( (!gAgentAvatarp->isWearingAttachment(idItem)) || (isLinkInCOF(idItem)) ) { itPendingAttachLink = m_PendingAttachLinks.erase(itPendingAttachLink); continue; @@ -389,7 +388,7 @@ void LLCOFMgr::updateAttachments() } // Don't remove attachments until avatar is fully loaded (should reduce random attaching/detaching/reattaching at log-on) - LLAgentWearables::userUpdateAttachments(items, !pAvatar->isFullyLoaded()); + LLAgentWearables::userUpdateAttachments(items, !gAgentAvatarp->isFullyLoaded()); } // ============================================================================ diff --git a/indra/newview/floaterlocalassetbrowse.cpp b/indra/newview/floaterlocalassetbrowse.cpp index 5c67eea15..c004e200e 100644 --- a/indra/newview/floaterlocalassetbrowse.cpp +++ b/indra/newview/floaterlocalassetbrowse.cpp @@ -670,8 +670,7 @@ void LocalAssetBrowser::PerformTimedActions(void) // one of the layer bitmaps has been updated, we need to rebake. if ( mLayerUpdated ) { - LLVOAvatar* avatar = gAgentAvatarp; - if (avatar) { avatar->forceBakeAllTextures(SLAM_FOR_DEBUG); } + if (isAgentAvatarValid()) { gAgentAvatarp->forceBakeAllTextures(SLAM_FOR_DEBUG); } mLayerUpdated = false; } diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 59325ab3c..0d5625143 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2392,7 +2392,7 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came gFocusMgr.setKeyboardFocus( NULL ); gFocusMgr.setMouseCapture( NULL ); - LLVOAvatar::onCustomizeStart(); + LLVOAvatarSelf::onCustomizeStart(); if (isAgentAvatarValid()) { diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 886348d1a..a56a44e88 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -918,8 +918,7 @@ void LLAgentWearables::onInitialWearableAssetArrived( LLWearable* wearable, void LLUUID item_id = wearable_data->second; delete wearable_data; - LLVOAvatar* avatar = gAgentAvatarp; - if( !avatar ) + if( !isAgentAvatarValid() ) { return; } @@ -931,11 +930,11 @@ void LLAgentWearables::onInitialWearableAssetArrived( LLWearable* wearable, void gAgentWearables.setWearable(type,wearable); // disable composites if initial textures are baked - avatar->setupComposites(); + gAgentAvatarp->setupComposites(); gAgentWearables.queryWearableCache(); wearable->writeToAvatar( FALSE ); - avatar->setCompositeUpdatesEnabled(TRUE); + gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); gInventory.addChangedMask( LLInventoryObserver::LABEL, item_id ); } else @@ -969,7 +968,7 @@ void LLAgentWearables::onInitialWearableAssetArrived( LLWearable* wearable, void // If there are any, schedule them to be uploaded as soon as the layer textures they depend on arrive. if( !gAgentCamera.cameraCustomizeAvatar() ) { - avatar->requestLayerSetUploads(); + gAgentAvatarp->requestLayerSetUploads(); } } } diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index b43d47177..eca65a317 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -763,8 +763,7 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata) { LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; LLCheckBoxCtrl* checkbox_ctrl = (LLCheckBoxCtrl*) ctrl; - LLVOAvatar *avatar = gAgentAvatarp; - if (!avatar) + if (!isAgentAvatarValid()) { return; } @@ -775,13 +774,13 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata) if (new_invis_state) { LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(IMG_INVISIBLE); - const LLTextureEntry* current_te = avatar->getTE(te); + const LLTextureEntry* current_te = gAgentAvatarp->getTE(te); if (current_te) { self->mPreviousTextureList[(S32)te] = current_te->getID(); } - avatar->setLocTexTE(te, image, TRUE); - avatar->wearableUpdated(self->mType, FALSE); + gAgentAvatarp->setLocalTextureTE(te, image, TRUE); + gAgentAvatarp->wearableUpdated(self->mType, FALSE); } else { @@ -794,8 +793,8 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata) if (prev_id.notNull()) { LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(prev_id); - avatar->setLocTexTE(te, image, TRUE); - avatar->wearableUpdated(self->mType, FALSE); + gAgentAvatarp->setLocalTextureTE(te, image, TRUE); + gAgentAvatarp->wearableUpdated(self->mType, FALSE); } } @@ -813,23 +812,24 @@ void LLPanelEditWearable::onColorCommit( LLUICtrl* ctrl, void* userdata ) LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; LLColorSwatchCtrl* color_ctrl = (LLColorSwatchCtrl*) ctrl; - LLVOAvatar* avatar = gAgentAvatarp; - if( self && color_ctrl && avatar ) + if(!isAgentAvatarValid()) + return; + if( self && color_ctrl) { std::map::const_iterator cl_itr = self->mColorList.find(ctrl->getName()); if(cl_itr != self->mColorList.end()) { ETextureIndex te = (ETextureIndex)cl_itr->second; - LLColor4 old_color = avatar->getClothesColor( te ); + LLColor4 old_color = gAgentAvatarp->getClothesColor( te ); const LLColor4& new_color = color_ctrl->get(); if( old_color != new_color ) { // Set the new version - avatar->setClothesColor( te, new_color, TRUE ); + gAgentAvatarp->setClothesColor( te, new_color, TRUE ); LLVisualParamHint::requestHintUpdates(); - avatar->wearableUpdated(self->mType, FALSE); + gAgentAvatarp->wearableUpdated(self->mType, FALSE); } } } @@ -893,8 +893,7 @@ void LLPanelEditWearable::onTextureCommit( LLUICtrl* ctrl, void* userdata ) LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; LLTextureCtrl* texture_ctrl = (LLTextureCtrl*) ctrl; - LLVOAvatar* avatar = gAgentAvatarp; - if( avatar ) + if( isAgentAvatarValid() ) { ETextureIndex te = (ETextureIndex)(self->mTextureList[ctrl->getName()]); @@ -907,8 +906,8 @@ void LLPanelEditWearable::onTextureCommit( LLUICtrl* ctrl, void* userdata ) self->mTextureList[ctrl->getName()] = te; if (gAgentWearables.getWearable(self->mType)) { - avatar->setLocTexTE(te, image, TRUE); - avatar->wearableUpdated(self->mType, FALSE); + gAgentAvatarp->setLocalTextureTE(te, image, TRUE); + gAgentAvatarp->wearableUpdated(self->mType, FALSE); } if (self->mType == LLWearableType::WT_ALPHA && image->getID() != IMG_INVISIBLE) { @@ -1989,12 +1988,11 @@ void LLFloaterCustomize::onBtnOk( void* userdata ) LLFloaterCustomize* floater = (LLFloaterCustomize*) userdata; gAgentWearables.saveAllWearables(); - LLVOAvatar* avatar = gAgentAvatarp; - if ( avatar ) + if ( isAgentAvatarValid() ) { - avatar->invalidateAll(); + gAgentAvatarp->invalidateAll(); - avatar->requestLayerSetUploads(); + gAgentAvatarp->requestLayerSetUploads(); gAgent.sendAgentSetAppearance(); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 94e3a4d73..132470685 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1623,8 +1623,7 @@ BOOL LLFolderBridge::isItemRemovable() return FALSE; } - LLVOAvatar* avatar = gAgentAvatarp; - if( !avatar ) + if( !isAgentAvatarValid() ) { return FALSE; } @@ -1667,7 +1666,7 @@ BOOL LLFolderBridge::isItemRemovable() } else if (item->getType() == LLAssetType::AT_OBJECT && !item->getIsLinkType()) { - if( avatar->isWearingAttachment( item->getUUID() ) ) + if( gAgentAvatarp->isWearingAttachment( item->getUUID() ) ) { return FALSE; } @@ -4028,17 +4027,16 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model LLInventoryItem* item = gInventory.getItem(mUUID); if(item) { - LLVOAvatar::detachAttachmentIntoInventory(item->getLinkedUUID()); + LLVOAvatarSelf::detachAttachmentIntoInventory(item->getLinkedUUID()); } } else if ("edit" == action) { if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) return; - LLVOAvatar* avatarp = gAgentAvatarp; - if (!avatarp) + if (!isAgentAvatarValid()) return; - LLViewerObject* objectp = avatarp->getWornAttachment(mUUID); + LLViewerObject* objectp = gAgentAvatarp->getWornAttachment(mUUID); if (!objectp) return; @@ -4085,12 +4083,11 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model void LLObjectBridge::openItem() { - LLVOAvatar* avatar = gAgentAvatarp; - if (!avatar) + if (!isAgentAvatarValid()) { return; } - if (avatar->isWearingAttachment(mUUID)) + if (gAgentAvatarp->isWearingAttachment(mUUID)) { // [RLVa:KB] if ( !(rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(getItem()))) @@ -4105,12 +4102,11 @@ void LLObjectBridge::openItem() std::string LLObjectBridge::getLabelSuffix() const { - LLVOAvatar* avatar = gAgentAvatarp; - if( avatar && avatar->isWearingAttachment( mUUID ) ) + if( isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment( mUUID ) ) { - std::string attachment_point_name = avatar->getAttachedPointName(mUUID); + std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID); LLStringUtil::toLower(attachment_point_name); - LLViewerObject* pObj = (rlv_handler_t::isEnabled()) ? avatar->getWornAttachment( mUUID ) : NULL; + LLViewerObject* pObj = (rlv_handler_t::isEnabled()) ? gAgentAvatarp->getWornAttachment( mUUID ) : NULL; // [RLVa:KB] if ( pObj && (gRlvAttachmentLocks.isLockedAttachment(pObj) || gRlvAttachmentLocks.isLockedAttachmentPoint(RlvAttachPtLookup::getAttachPointIndex(pObj),RLV_LOCK_REMOVE))) @@ -4123,10 +4119,10 @@ std::string LLObjectBridge::getLabelSuffix() const else { // testzone attachpt - if(avatar) + if(isAgentAvatarValid()) { - std::map >::iterator iter = avatar->mUnsupportedAttachmentPoints.begin(); - std::map >::iterator end = avatar->mUnsupportedAttachmentPoints.end(); + std::map >::iterator iter = gAgentAvatarp->mUnsupportedAttachmentPoints.begin(); + std::map >::iterator end = gAgentAvatarp->mUnsupportedAttachmentPoints.end(); for( ; iter != end; ++iter) if((*iter).second.first == mUUID) { @@ -4247,8 +4243,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) LLInventoryItem* item = getItem(); if(item) { - LLVOAvatar *avatarp = gAgentAvatarp; - if( !avatarp ) + if( !isAgentAvatarValid() ) { return; } @@ -4266,7 +4261,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else // testzone attachpt - if( avatarp->isWearingUnsupportedAttachment( mUUID ) ) + if( gAgentAvatarp->isWearingUnsupportedAttachment( mUUID ) ) { items.push_back(std::string("Detach From Yourself")); } @@ -4278,7 +4273,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Object Wear")); if (gHippoGridManager->getConnectedGrid()->supportsInvLinks()) items.push_back(std::string("Object Add")); - if (!avatarp->canAttachMoreObjects()) + if (!gAgentAvatarp->canAttachMoreObjects()) { disabled_items.push_back(std::string("Object Add")); } @@ -4287,7 +4282,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) // commented out for DEV-32347 - AND Commented back in for non-morons. -HgB items.push_back(std::string("Restore to Last Position")); - if (!avatarp->canAttachMoreObjects()) + if (!gAgentAvatarp->canAttachMoreObjects()) { disabled_items.push_back(std::string("Object Wea")); disabled_items.push_back(std::string("Object Add")); @@ -4310,11 +4305,10 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if (attach_menu && (attach_menu->getChildCount() == 0) && attach_hud_menu - && (attach_hud_menu->getChildCount() == 0) - && avatarp) + && (attach_hud_menu->getChildCount() == 0)) { - for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); - iter != avatarp->mAttachmentPoints.end(); ) + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; @@ -4374,10 +4368,9 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name) model->updateItem(new_item); model->notifyObservers(); - LLVOAvatar* avatar = gAgentAvatarp; - if( avatar ) + if( isAgentAvatarValid() ) { - LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() ); + LLViewerObject* obj = gAgentAvatarp->getWornAttachment( item->getUUID() ); if( obj ) { LLSelectMgr::getInstance()->deselectAll(); @@ -5148,7 +5141,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata) LLViewerInventoryItem *obj_item = obj_item_array.get(i); if (get_is_item_worn(obj_item->getUUID())) { - LLVOAvatar::detachAttachmentIntoInventory(obj_item->getLinkedUUID()); + LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID()); } } } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index ecafb56b9..d3c0adf72 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3647,7 +3647,6 @@ bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(LLInventoryItem* ite return false; bool allowed = false; - LLVOAvatar* my_avatar = NULL; switch(item->getType()) { @@ -3656,8 +3655,7 @@ bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(LLInventoryItem* ite break; case LLAssetType::AT_OBJECT: - my_avatar = gAgentAvatarp; - if(my_avatar && !my_avatar->isWearingAttachment(item->getUUID())) + if(isAgentAvatarValid() && !gAgentAvatarp->isWearingAttachment(item->getUUID())) { allowed = true; } diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index ec7428918..11fa68536 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -91,15 +91,14 @@ void LLMorphView::initialize() mCameraYaw = 0.f; mCameraDist = -1.f; - LLVOAvatar *avatarp = gAgentAvatarp; - if (!avatarp || avatarp->isDead()) + if (!isAgentAvatarValid()) { gAgentCamera.changeCameraToDefault(); return; } - avatarp->stopMotion( ANIM_AGENT_BODY_NOISE ); - avatarp->mSpecialRenderMode = 3; + gAgentAvatarp->stopMotion( ANIM_AGENT_BODY_NOISE ); + gAgentAvatarp->mSpecialRenderMode = 3; // set up camera for close look at avatar mOldCameraNearClip = LLViewerCamera::getInstance()->getNear(); @@ -111,13 +110,12 @@ void LLMorphView::initialize() //----------------------------------------------------------------------------- void LLMorphView::shutdown() { - LLVOAvatar::onCustomizeEnd(); + LLVOAvatarSelf::onCustomizeEnd(); - LLVOAvatar *avatarp = gAgentAvatarp; - if(avatarp && !avatarp->isDead()) + if (isAgentAvatarValid()) { - avatarp->startMotion( ANIM_AGENT_BODY_NOISE ); - avatarp->mSpecialRenderMode = 0; + gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); + gAgentAvatarp->mSpecialRenderMode = 0; // reset camera LLViewerCamera::getInstance()->setNear(mOldCameraNearClip); } @@ -167,14 +165,10 @@ void LLMorphView::updateCamera() if (!mCameraTargetJoint) { setCameraTargetJoint(gAgentAvatarp->getJoint("mHead")); - } - - LLVOAvatar* avatar = gAgentAvatarp; - if( !avatar ) - { - return; - } - LLJoint* root_joint = avatar->getRootJoint(); + } + if (!isAgentAvatarValid()) return; + + LLJoint* root_joint = gAgentAvatarp->getRootJoint(); if( !root_joint ) { return; diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 5b2c9cfae..c4b6080b9 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -231,10 +231,9 @@ void LLPreview::onCommit() // update the object itself. if( item->getType() == LLAssetType::AT_OBJECT ) { - LLVOAvatar* avatar = gAgentAvatarp; - if( avatar ) + if( isAgentAvatarValid() ) { - LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() ); + LLViewerObject* obj = gAgentAvatarp->getWornAttachment( item->getUUID() ); if( obj ) { LLSelectMgr::getInstance()->deselectAll(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 11e310cb9..a9368f476 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3440,7 +3440,7 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFuncFast(_PREHASH_AvatarAnimation, process_avatar_animation); msg->setHandlerFuncFast(_PREHASH_AvatarAppearance, process_avatar_appearance); msg->setHandlerFunc("AgentCachedTextureResponse", LLAgent::processAgentCachedTextureResponse); - msg->setHandlerFunc("RebakeAvatarTextures", LLVOAvatar::processRebakeAvatarTextures); + msg->setHandlerFunc("RebakeAvatarTextures", LLVOAvatarSelf::processRebakeAvatarTextures); msg->setHandlerFuncFast(_PREHASH_CameraConstraint, process_camera_constraint); msg->setHandlerFuncFast(_PREHASH_AvatarSitResponse, process_avatar_sit_response); msg->setHandlerFunc("SetFollowCamProperties", process_set_follow_cam_properties); diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 846768928..0dd7614ba 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -71,7 +71,7 @@ S32 LLTexLayerSetBuffer::sGLByteCount = 0; //----------------------------------------------------------------------------- // LLBakedUploadData() //----------------------------------------------------------------------------- -LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar, +LLBakedUploadData::LLBakedUploadData( LLVOAvatarSelf* avatar, LLTexLayerSet* layerset, LLTexLayerSetBuffer* layerset_buffer, const LLUUID & id ) : @@ -218,12 +218,14 @@ void LLTexLayerSetBuffer::popProjection() BOOL LLTexLayerSetBuffer::needsRender() { - LLVOAvatar* avatar = mTexLayerSet->getAvatar(); + llassert(mTexLayerSet->getAvatar() == gAgentAvatarp); + if (!isAgentAvatarValid()) return FALSE; + BOOL upload_now = needsUploadNow(); - BOOL needs_update = (mNeedsUpdate || upload_now) && !avatar->getIsAppearanceAnimating(); + BOOL needs_update = (mNeedsUpdate || upload_now) && !gAgentAvatarp->getIsAppearanceAnimating(); if (needs_update) { - BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !avatar->isWearingWearableType(LLWearableType::WT_SKIRT); + BOOL invalid_skirt = gAgentAvatarp->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT); if (invalid_skirt) { // we were trying to create a skirt texture @@ -233,7 +235,7 @@ BOOL LLTexLayerSetBuffer::needsRender() } else { - needs_update &= (avatar->isSelf() || (avatar->isVisible() && !avatar->isCulled())); + needs_update &= ((gAgentAvatarp->isVisible() && !gAgentAvatarp->isCulled())); needs_update &= mTexLayerSet->isLocalTextureDataAvailable(); } } @@ -296,12 +298,8 @@ BOOL LLTexLayerSetBuffer::render() { mUploadPending = FALSE; mNeedsUpload = FALSE; - LLVOAvatar* avatar = mTexLayerSet->getAvatar(); - if (avatar) - { - avatar->setNewBakedTexture(avatar->getBakedTE(mTexLayerSet), IMG_INVISIBLE); - llinfos << "Invisible baked texture set for " << mTexLayerSet->getBodyRegion() << llendl; - } + mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getAvatar()->getBakedTE(mTexLayerSet), IMG_INVISIBLE); + llinfos << "Invisible baked texture set for " << mTexLayerSet->getBodyRegion() << llendl; } } } @@ -612,7 +610,7 @@ BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node) BOOL LLTexLayerSet::sHasCaches = FALSE; -LLTexLayerSet::LLTexLayerSet( LLVOAvatar* avatar ) +LLTexLayerSet::LLTexLayerSet( LLVOAvatarSelf* avatar ) : mComposite( NULL ), mAvatar( avatar ), diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index 7acc45be2..ae3633c39 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -260,7 +260,7 @@ class LLTexLayerSet { friend class LLTexLayerSetBuffer; public: - LLTexLayerSet( LLVOAvatar* avatar ); + LLTexLayerSet( LLVOAvatarSelf* avatar ); ~LLTexLayerSet(); //BOOL parseData(LLXmlTreeNode* node); @@ -275,7 +275,7 @@ public: void requestUpdate(); void requestUpload(); void cancelUpload(); - LLVOAvatar* getAvatar() { return mAvatar; } + LLVOAvatarSelf* getAvatar() { return mAvatar; } void updateComposite(); BOOL isLocalTextureDataAvailable(); BOOL isLocalTextureDataFinal(); @@ -301,7 +301,7 @@ protected: layer_list_t mMaskLayerList; LLPointer mComposite; // Backlink only; don't make this an LLPointer. - LLVOAvatar* mAvatar; + LLVOAvatarSelf* mAvatar; BOOL mUpdatesEnabled; BOOL mIsVisible; @@ -442,7 +442,7 @@ public: BOOL setInfo(LLTexGlobalColorInfo *info); void requstUpdate(); - LLVOAvatar* getAvatar() { return mAvatar; } + LLVOAvatar* getAvatar() { return mAvatar; } LLColor4 getColor(); const std::string& getName() { return mInfo->mName; } @@ -540,11 +540,11 @@ public: class LLBakedUploadData { public: - LLBakedUploadData( LLVOAvatar* avatar, LLTexLayerSet* layerset, LLTexLayerSetBuffer* layerset_buffer, const LLUUID & id); + LLBakedUploadData( LLVOAvatarSelf* avatar, LLTexLayerSet* layerset, LLTexLayerSetBuffer* layerset_buffer, const LLUUID & id); ~LLBakedUploadData() {} LLUUID mID; - LLVOAvatar* mAvatar; // just backlink, don't LLPointer + LLVOAvatarSelf* mAvatar; // just backlink, don't LLPointer LLTexLayerSet* mTexLayerSet; LLTexLayerSetBuffer* mLayerSetBuffer; LLUUID mWearableAssets[LLWearableType::WT_COUNT]; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index fa096d5a5..9f8760da5 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -2029,7 +2029,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL // gAgent.getGroupID()) // && (obj->mPermModify || obj->mFlagAllowInventoryAdd)); BOOL worn = FALSE; - LLVOAvatar* my_avatar = NULL; + LLVOAvatarSelf* my_avatar = NULL; switch(item->getType()) { case LLAssetType::AT_OBJECT: @@ -2858,7 +2858,7 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject( // cannot give away no-transfer objects return ACCEPT_NO; } - LLVOAvatar* avatar = gAgentAvatarp; + LLVOAvatarSelf* avatar = gAgentAvatarp; if(avatar && avatar->isWearingAttachment( item->getUUID() ) ) { // You can't give objects that are attached to you diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 2cdfe9e6c..ee7a21ff2 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -151,16 +151,14 @@ BOOL LLVisualParamHint::needsRender() void LLVisualParamHint::preRender(BOOL clear_depth) { - LLVOAvatar* avatarp = gAgentAvatarp; - - mLastParamWeight = avatarp->getVisualParamWeight(mVisualParam); - avatarp->setVisualParamWeight(mVisualParam, mVisualParamWeight); - avatarp->setVisualParamWeight("Blink_Left", 0.f); - avatarp->setVisualParamWeight("Blink_Right", 0.f); - avatarp->updateComposites(); - avatarp->updateVisualParams(); - avatarp->updateGeometry(avatarp->mDrawable); - avatarp->updateLOD(); + mLastParamWeight = gAgentAvatarp->getVisualParamWeight(mVisualParam); + gAgentAvatarp->setVisualParamWeight(mVisualParam, mVisualParamWeight); + gAgentAvatarp->setVisualParamWeight("Blink_Left", 0.f); + gAgentAvatarp->setVisualParamWeight("Blink_Right", 0.f); + gAgentAvatarp->updateComposites(); + gAgentAvatarp->updateVisualParams(); + gAgentAvatarp->updateGeometry(gAgentAvatarp->mDrawable); + gAgentAvatarp->updateLOD(); LLViewerDynamicTexture::preRender(clear_depth); } @@ -171,7 +169,6 @@ void LLVisualParamHint::preRender(BOOL clear_depth) BOOL LLVisualParamHint::render() { LLVisualParamReset::sDirty = TRUE; - LLVOAvatar* avatarp = gAgentAvatarp; glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -199,7 +196,7 @@ BOOL LLVisualParamHint::render() const std::string& cam_target_mesh_name = mVisualParam->getCameraTargetName(); if( !cam_target_mesh_name.empty() ) { - cam_target_joint = (LLViewerJointMesh*)avatarp->getJoint( cam_target_mesh_name ); + cam_target_joint = (LLViewerJointMesh*)gAgentAvatarp->getJoint( cam_target_mesh_name ); } if( !cam_target_joint ) { @@ -207,11 +204,11 @@ BOOL LLVisualParamHint::render() } if( !cam_target_joint ) { - cam_target_joint = (LLViewerJointMesh*)avatarp->getJoint("mHead"); + cam_target_joint = (LLViewerJointMesh*)gAgentAvatarp->getJoint("mHead"); } LLQuaternion avatar_rotation; - LLJoint* root_joint = avatarp->getRootJoint(); + LLJoint* root_joint = gAgentAvatarp->getRootJoint(); if( root_joint ) { avatar_rotation = root_joint->getWorldRotation(); @@ -233,23 +230,23 @@ BOOL LLVisualParamHint::render() LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / (F32)mFullHeight); LLViewerCamera::getInstance()->setOriginAndLookAt( - camera_pos, // camera - LLVector3(0.f, 0.f, 1.f), // up - target_pos ); // point of interest + camera_pos, // camera + LLVector3::z_axis, // up + target_pos ); // point of interest LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); - if (avatarp->mDrawable.notNull()) + if (gAgentAvatarp->mDrawable.notNull()) { - LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool(); + LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool(); LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); gGL.setAlphaRejectSettings(LLRender::CF_ALWAYS); gGL.setSceneBlendType(LLRender::BT_REPLACE); - avatarPoolp->renderAvatars(avatarp); // renders only one avatar + avatarPoolp->renderAvatars(gAgentAvatarp); // renders only one avatar gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } - avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight); + gAgentAvatarp->setVisualParamWeight(mVisualParam, mLastParamWeight); gGL.color4f(1,1,1,1); mGLTexturep->setGLTextureCreated(true); return TRUE; @@ -304,10 +301,9 @@ BOOL LLVisualParamReset::render() { if (sDirty) { - LLVOAvatar* avatarp = gAgentAvatarp; - avatarp->updateComposites(); - avatarp->updateVisualParams(); - avatarp->updateGeometry(avatarp->mDrawable); + gAgentAvatarp->updateComposites(); + gAgentAvatarp->updateVisualParams(); + gAgentAvatarp->updateGeometry(gAgentAvatarp->mDrawable); sDirty = FALSE; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index d89c17c87..c0f59f0bf 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -190,7 +190,7 @@ static bool handleAvatarBoobXYInfluence(const LLSD& newvalue) static bool handleSetSelfInvisible( const LLSD& newvalue) { - LLVOAvatar::onChangeSelfInvisible( newvalue.asBoolean() ); + LLVOAvatarSelf::onChangeSelfInvisible( newvalue.asBoolean() ); return true; } diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 8e8dcef98..5bd9b7ea1 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -40,7 +40,7 @@ #include "lldrawable.h" #include "llgl.h" #include "llrender.h" -#include "llvoavatar.h" +#include "llvoavatarself.h" #include "llvolume.h" #include "pipeline.h" #include "llspatialpartition.h" @@ -182,7 +182,7 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) object->markDead(); // If this happens to be attached to self, then detach. - LLVOAvatar::detachAttachmentIntoInventory(object->getAttachmentItemID()); + LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID()); return FALSE; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 481f6538c..4bf228c33 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -592,8 +592,8 @@ void handle_mesh_load_obj(void*); void handle_morph_save_obj(void*); void handle_morph_load_obj(void*); void handle_debug_avatar_textures(void*); -void handle_grab_texture(void*); -BOOL enable_grab_texture(void*); +void handle_grab_baked_texture(void*); +BOOL enable_grab_baked_texture(void*); void handle_dump_region_object_cache(void*); BOOL menu_ui_enabled(void *user_data); @@ -1654,12 +1654,12 @@ void init_debug_avatar_menu(LLMenuGL* menu) void init_debug_baked_texture_menu(LLMenuGL* menu) { - menu->append(new LLMenuItemCallGL("Iris", handle_grab_texture, enable_grab_texture, (void*) TEX_EYES_BAKED)); - menu->append(new LLMenuItemCallGL("Head", handle_grab_texture, enable_grab_texture, (void*) TEX_HEAD_BAKED)); - menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_texture, enable_grab_texture, (void*) TEX_UPPER_BAKED)); - menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_texture, enable_grab_texture, (void*) TEX_LOWER_BAKED)); - menu->append(new LLMenuItemCallGL("Skirt", handle_grab_texture, enable_grab_texture, (void*) TEX_SKIRT_BAKED)); - menu->append(new LLMenuItemCallGL("Hair", handle_grab_texture, enable_grab_texture, (void*) TEX_HAIR_BAKED)); + menu->append(new LLMenuItemCallGL("Iris", handle_grab_baked_texture, enable_grab_baked_texture, (void*) BAKED_EYES)); + menu->append(new LLMenuItemCallGL("Head", handle_grab_baked_texture, enable_grab_baked_texture, (void*) BAKED_HEAD)); + menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_baked_texture, enable_grab_baked_texture, (void*) BAKED_UPPER)); + menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_baked_texture, enable_grab_baked_texture, (void*) BAKED_LOWER)); + menu->append(new LLMenuItemCallGL("Skirt", handle_grab_baked_texture, enable_grab_baked_texture, (void*) BAKED_SKIRT)); + menu->append(new LLMenuItemCallGL("Hair", handle_grab_baked_texture, enable_grab_baked_texture, (void*) BAKED_HAIR)); menu->createJumpKeys(); } @@ -3052,9 +3052,9 @@ class LLAvatarDebug : public view_listener_t bool handleEvent(LLPointer event, const LLSD& userdata) { LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() ); - if( avatar ) + if( avatar == gAgentAvatarp ) { - avatar->dumpLocalTextures(); + gAgentAvatarp->dumpLocalTextures(); // hell no don't tell them about that /* llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl; @@ -8274,10 +8274,9 @@ void slow_mo_animations(void*) void handle_dump_avatar_local_textures(void*) { - LLVOAvatar* avatar = gAgentAvatarp; - if( avatar ) + if( isAgentAvatarValid() ) { - avatar->dumpLocalTextures(); + gAgentAvatarp->dumpLocalTextures(); } } @@ -8701,106 +8700,79 @@ void handle_debug_avatar_textures(void*) // } -void handle_grab_texture(void* data) +void handle_grab_baked_texture(void* data) { - ETextureIndex index = (ETextureIndex)((intptr_t)data); - LLVOAvatar* avatar = gAgentAvatarp; - if ( avatar ) + EBakedTextureIndex baked_tex_index = (EBakedTextureIndex)((intptr_t)data); + if (!isAgentAvatarValid()) return; + + const LLUUID& asset_id = gAgentAvatarp->grabBakedTexture(baked_tex_index); + LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << llendl; + LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE; + LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE; + const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type)); + if(folder_id.notNull()) { - const LLUUID& asset_id = avatar->grabLocalTexture(index); - LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << llendl; - LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE; - LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE; - LLUUID folder_id(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE)); - if(folder_id.notNull()) - { - std::string name = "Baked "; - switch (index) + std::string name; + name = "Baked " + LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture"; + + LLUUID item_id; + item_id.generate(); + LLPermissions perm; + perm.init(gAgentID, + gAgentID, + LLUUID::null, + LLUUID::null); + U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER; + perm.initMasks(PERM_ALL, + PERM_ALL, + PERM_NONE, + PERM_NONE, + next_owner_perm); + time_t creation_date_now = time_corrected(); + LLPointer item + = new LLViewerInventoryItem(item_id, + folder_id, + perm, + asset_id, + asset_type, + inv_type, + name, + LLStringUtil::null, + LLSaleInfo::DEFAULT, + LLInventoryItemFlags::II_FLAGS_NONE, + creation_date_now); + + item->updateServer(TRUE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + + LLInventoryView* view = LLInventoryView::getActiveInventory(); + + // Show the preview panel for textures to let + // user know that the image is now in inventory. + if(view) { - case TEX_EYES_BAKED: - name.append("Iris"); - break; - case TEX_HEAD_BAKED: - name.append("Head"); - break; - case TEX_UPPER_BAKED: - name.append("Upper Body"); - break; - case TEX_LOWER_BAKED: - name.append("Lower Body"); - break; - case TEX_SKIRT_BAKED: - name.append("Skirt"); - break; - case TEX_HAIR_BAKED: - name.append("Hair"); - break; - default: - name.append("Unknown"); - break; - } - name.append(" Texture"); + LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - LLUUID item_id; - item_id.generate(); - LLPermissions perm; - perm.init(gAgentID, - gAgentID, - LLUUID::null, - LLUUID::null); - U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER; - perm.initMasks(PERM_ALL, - PERM_ALL, - PERM_NONE, - PERM_NONE, - next_owner_perm); - time_t creation_date_now = time_corrected(); - LLPointer item - = new LLViewerInventoryItem(item_id, - folder_id, - perm, - asset_id, - asset_type, - inv_type, - name, - LLStringUtil::null, - LLSaleInfo::DEFAULT, - LLInventoryItemFlags::II_FLAGS_NONE, - creation_date_now); - - item->updateServer(TRUE); - gInventory.updateItem(item); - gInventory.notifyObservers(); - - LLInventoryView* view = LLInventoryView::getActiveInventory(); - - // Show the preview panel for textures to let - // user know that the image is now in inventory. - if(view) - { - LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - - view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO); - view->getPanel()->openSelected(); - //LLInventoryView::dumpSelectionInformation((void*)view); - // restore keyboard focus - gFocusMgr.setKeyboardFocus(focus_ctrl); - } - } - else - { - llwarns << "Can't find a folder to put it in" << llendl; + view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO); + view->getPanel()->openSelected(); + //LLInventoryView::dumpSelectionInformation((void*)view); + // restore keyboard focus + gFocusMgr.setKeyboardFocus(focus_ctrl); } } + else + { + llwarns << "Can't find a folder to put it in" << llendl; + } } -BOOL enable_grab_texture(void* data) +BOOL enable_grab_baked_texture(void* data) { - ETextureIndex index = (ETextureIndex)((intptr_t)data); - LLVOAvatar* avatar = gAgentAvatarp; - if ( avatar ) + EBakedTextureIndex index = (EBakedTextureIndex)((intptr_t)data); + if (isAgentAvatarValid()) { - return avatar->canGrabLocalTexture(index); + return gAgentAvatarp->canGrabBakedTexture(index); } return FALSE; } @@ -9038,12 +9010,11 @@ void handle_buy_currency_test(void*) void handle_rebake_textures(void*) { - LLVOAvatar* avatar = gAgentAvatarp; - if (!avatar) return; + if (!isAgentAvatarValid()) return; // Slam pending upload count to "unstick" things bool slam_for_debug = true; - avatar->forceBakeAllTextures(slam_for_debug); + gAgentAvatarp->forceBakeAllTextures(slam_for_debug); } void toggle_visibility(void* user_data) diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index ca4606f7c..7a7cd1660 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -55,7 +55,7 @@ #include "lldebugview.h" #include "llfasttimerview.h" #include "llviewerregion.h" -#include "llvoavatar.h" +#include "llvoavatarself.h" #include "llviewerwindow.h" // *TODO: remove, only used for width/height #include "llworld.h" #include "llfeaturemanager.h" @@ -526,11 +526,11 @@ void output_statistics(void*) llinfos << "--------------------------------" << llendl; llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl; gTexStaticImageList.dumpByteCount(); - LLVOAvatar::dumpScratchTextureByteCount(); + LLVOAvatarSelf::dumpScratchTextureByteCount(); LLTexLayerSetBuffer::dumpTotalByteCount(); - LLVOAvatar::dumpTotalLocalTextureByteCount(); + LLVOAvatarSelf::dumpTotalLocalTextureByteCount(); LLTexLayerParamAlpha::dumpCacheByteCount(); - LLVOAvatar::dumpBakedStatus(); + LLVOAvatarSelf::dumpBakedStatus(); llinfos << llendl; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 045e513eb..19ee949c6 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -220,14 +220,6 @@ enum ERenderName //----------------------------------------------------------------------------- // Callback data //----------------------------------------------------------------------------- -struct LLAvatarTexData -{ - LLAvatarTexData( const LLUUID& id, ETextureIndex index ) - : mAvatarID(id), mIndex(index) {} - LLUUID mAvatarID; - ETextureIndex mIndex; -}; - struct LLTextureMaskData { LLTextureMaskData( const LLUUID& id ) : @@ -972,12 +964,6 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars) return res; } -// static -void LLVOAvatar::dumpScratchTextureByteCount() -{ - llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl; -} - // static void LLVOAvatar::getMeshInfo (mesh_info_t* mesh_info) { @@ -1100,17 +1086,14 @@ void LLVOAvatar::dumpBakedStatus() //static void LLVOAvatar::restoreGL() { - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) + if (!isAgentAvatarValid()) return; + + gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); + for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++) { - LLVOAvatar* inst = (LLVOAvatar*) *iter; - inst->setCompositeUpdatesEnabled( TRUE ); - for (U32 i = 0; i < inst->mBakedTextureDatas.size(); i++) - { - inst->invalidateComposite( inst->mBakedTextureDatas[i].mTexLayerSet, FALSE ); - } - inst->updateMeshTextures(); + gAgentAvatarp->invalidateComposite(gAgentAvatarp->mBakedTextureDatas[i].mTexLayerSet, FALSE); } + gAgentAvatarp->updateMeshTextures(); } //static @@ -1135,49 +1118,6 @@ void LLVOAvatar::resetImpostors() // static void LLVOAvatar::deleteCachedImages(bool clearAll) { -if(gAuditTexture) - { - S32 total_tex_size = sScratchTexBytes ; - S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; - - if( LLVOAvatar::sScratchTexNames.checkData( GL_LUMINANCE ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( LLVOAvatar::sScratchTexNames.checkData( GL_ALPHA ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( LLVOAvatar::sScratchTexNames.checkData( GL_COLOR_INDEX ) ) - { - LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= tex_size ; - } - if( LLVOAvatar::sScratchTexNames.checkData( GL_LUMINANCE_ALPHA ) ) - { - LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 2 * tex_size ; - } - if( LLVOAvatar::sScratchTexNames.checkData( GL_RGB ) ) - { - LLImageGL::decTextureCounter(tex_size, 3, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 3 * tex_size ; - } - if( LLVOAvatar::sScratchTexNames.checkData( GL_RGBA ) ) - { - LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 4 * tex_size ; - } - //others - while(total_tex_size > 0) - { - LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - total_tex_size -= 4 * tex_size ; - } - } - if (LLTexLayerSet::sHasCaches) { lldebugs << "Deleting layer set caches" << llendl; @@ -1189,25 +1129,8 @@ if(gAuditTexture) } LLTexLayerSet::sHasCaches = FALSE; } - - for( LLGLuint* namep = sScratchTexNames.getFirstData(); - namep; - namep = sScratchTexNames.getNextData() ) - { - LLImageGL::deleteTextures(1, (U32 *)namep ); - stop_glerror(); - } - - if( sScratchTexBytes ) - { - lldebugs << "Clearing Scratch Textures " << (sScratchTexBytes/1024) << "KB" << llendl; - - sScratchTexNames.deleteAllData(); - LLVOAvatar::sScratchTexLastBindTime.deleteAllData(); - LLImageGL::sGlobalTextureMemoryInBytes -= sScratchTexBytes; - sScratchTexBytes = 0; - } - + + LLVOAvatarSelf::deleteScratchTextures(); gTexStaticImageList.deleteCachedImages(); } @@ -1397,7 +1320,7 @@ void LLVOAvatar::initInstance(void) //------------------------------------------------------------------------- for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin(); iter != LLVOAvatarDictionary::getInstance()->getMeshes().end(); - iter++) + ++iter) { const EMeshIndex mesh_index = iter->first; const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second; @@ -1407,7 +1330,8 @@ void LLVOAvatar::initInstance(void) if (baked_texture_index == BAKED_NUM_INDICES) continue; for (std::vector::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin(); - iter != mMeshLOD[mesh_index]->mMeshParts.end(); iter++) + iter != mMeshLOD[mesh_index]->mMeshParts.end(); + ++iter) { LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter; mBakedTextureDatas[(int)baked_texture_index].mMeshes.push_back(mesh); @@ -2595,41 +2519,10 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) idleUpdateNameTag( root_pos_last ); idleUpdateRenderCost(); + return TRUE; } -// static -BOOL LLVOAvatar::detachAttachmentIntoInventory(const LLUUID &item_id) -{ - LLInventoryItem* item = gInventory.getLinkedItem(item_id); - if ( (item) && (gAgentAvatarp) && (!gAgentAvatarp->isWearingAttachment(item->getUUID())) ) - { - LLCOFMgr::instance().removeAttachment(item->getUUID()); - return FALSE; - } -// if (item) -// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1c) | Added: RLVa-1.2.1c - if ( (item) && ((!rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(item))) ) -// [/RLVa:KB] - { - gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); - gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); - - // This object might have been selected, so let the selection manager know it's gone now - LLViewerObject *found_obj = gObjectList.findObject(item_id); - if (found_obj) - { - LLSelectMgr::getInstance()->remove(found_obj); - } - - return TRUE; - } - return FALSE; -} - void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) { bool render_visualizer = voice_enabled; @@ -2725,19 +2618,19 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing) //-------------------------------------------------------------------------------------------- #if MESH_ENABLED - if( !mIsSitting ) - { - LLVector3 tagPos = mRoot.getWorldPosition(); - tagPos[VZ] -= mPelvisToFoot; - tagPos[VZ] += ( mBodySize[VZ] + 0.125f ); - mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos ); - } - else + if( !mIsSitting ) + { + LLVector3 tagPos = mRoot.getWorldPosition(); + tagPos[VZ] -= mPelvisToFoot; + tagPos[VZ] += ( mBodySize[VZ] + 0.125f ); + mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos ); + } + else #endif //MESH_ENABLED - { - LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); - mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); - } + { + LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); + mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); + } }//if ( voiceEnabled ) } @@ -3631,26 +3524,11 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) avatar_name_color.setAlpha(alpha); mNameText->setColor(avatar_name_color); - LLQuaternion root_rot = mRoot.getWorldRotation(); mNameText->setUsePixelSize(TRUE); - LLVector3 pixel_right_vec; - LLVector3 pixel_up_vec; - LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); - LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin(); - camera_to_av.normalize(); - LLVector3 local_camera_at = camera_to_av * ~root_rot; - LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); - local_camera_up.normalize(); - local_camera_up = local_camera_up * ~root_rot; - - local_camera_up.scaleVec(mBodySize * 0.5f); - local_camera_at.scaleVec(mBodySize * 0.5f); + LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); - LLVector3 name_position = mRoot.getWorldPosition() + - (local_camera_up * root_rot) - - (projected_vec(local_camera_at * root_rot, camera_to_av)); - name_position += pixel_up_vec * 15.f; mNameText->setPositionAgent(name_position); + } else if (mNameText) { @@ -3695,11 +3573,11 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); - if(mNameAway && ! is_away) mIdleTimer.reset(); bool is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end(); - if(mNameBusy && ! is_busy) mIdleTimer.reset(); bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); - if(mNameAppearance && ! is_appearance) mIdleTimer.reset(); + if( (mNameAway && ! is_away) || (mNameBusy && ! is_busy) || (mNameAppearance && ! is_appearance)) + mIdleTimer.reset(); + bool is_muted; if (isSelf()) { @@ -4017,6 +3895,29 @@ void LLVOAvatar::invalidateNameTags() } } +// Compute name tag position during idle update +LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) +{ + LLQuaternion root_rot = mRoot.getWorldRotation(); + LLVector3 pixel_right_vec; + LLVector3 pixel_up_vec; + LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); + LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin(); + camera_to_av.normalize(); + LLVector3 local_camera_at = camera_to_av * ~root_rot; + LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); + local_camera_up.normalize(); + local_camera_up = local_camera_up * ~root_rot; + + local_camera_up.scaleVec(mBodySize * 0.5f); + local_camera_at.scaleVec(mBodySize * 0.5f); + + LLVector3 name_position = mRoot.getWorldPosition(); + name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av)); + name_position += pixel_up_vec * 15.f; + return name_position; +} + void LLVOAvatar::idleUpdateBelowWater() { F32 avatar_height = (F32)(getPositionGlobal().mdV[VZ]); @@ -4925,7 +4826,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) } } - if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) + if (/*should_alpha_mask && */!LLGLSLShader::sNoFixedFunction) { gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } @@ -5022,7 +4923,7 @@ U32 LLVOAvatar::renderRigid() num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy); } - if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) + if (/*should_alpha_mask && */!LLGLSLShader::sNoFixedFunction) { gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } @@ -5183,9 +5084,9 @@ void LLVOAvatar::updateTextures() mMaxPixelArea = 0.f; mMinPixelArea = 99999999.f; mHasGrey = FALSE; // debug - for (U32 index = 0; index < getNumTEs(); index++) + for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++) { - LLViewerFetchedTexture *imagep = LLViewerTextureManager::staticCastToFetchedTexture(getTEImage(index)); + LLViewerFetchedTexture *imagep = LLViewerTextureManager::staticCastToFetchedTexture(getTEImage(texture_index)); if (imagep) { // Debugging code - maybe non-self avatars are downloading textures? @@ -5197,12 +5098,12 @@ void LLVOAvatar::updateTextures() // << " desired " << imagep->getDesiredDiscardLevel() // << llendl; - const LLTextureEntry *te = getTE(index); + const LLTextureEntry *te = getTE(texture_index); F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); - S32 boost_level = isSelf() ? LLViewerTexture::BOOST_AVATAR_BAKED_SELF : LLViewerTexture::BOOST_AVATAR_BAKED; + const S32 boost_level = getAvatarBakedBoostLevel(); // Spam if this is a baked texture, not set to default image, without valid host info - if (isIndexBakedTexture((ETextureIndex)index) + if (isIndexBakedTexture((ETextureIndex)texture_index) && imagep->getID() != IMG_DEFAULT_AVATAR && imagep->getID() != IMG_INVISIBLE && !imagep->getTargetHost().isOk()) @@ -5216,13 +5117,13 @@ void LLVOAvatar::updateTextures() /* switch(index) case TEX_HEAD_BODYPAINT: addLocalTextureStats( LOCTEX_HEAD_BODYPAINT, imagep, texel_area_ratio, render_avatar, head_baked ); */ - const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)index); + const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)texture_index); if (texture_dict->mIsUsedByBakedTexture) { const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; if (texture_dict->mIsLocalTexture) { - addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); + addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); } else if (texture_dict->mIsBakedTexture) { @@ -5247,44 +5148,11 @@ void LLVOAvatar::updateTextures() } -void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerTexture* imagep, +void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked ) { - if (!isIndexLocalTexture(idx)) return; - - if (!covered_by_baked && render_avatar) // render_avatar is always true if isSelf() - { - if (getLocalTextureID(idx) != IMG_DEFAULT_AVATAR) - { - F32 desired_pixels; - if( isSelf() ) - { - desired_pixels = llmax(mPixelArea, (F32)TEX_IMAGE_AREA_SELF ); - imagep->setBoostLevel(LLViewerTexture::BOOST_AVATAR_SELF); - // SNOW-8 : temporary snowglobe1.0 fix for baked textures - if (render_avatar && !gGLManager.mIsDisabled ) - { - // bind the texture so that its boost level won't be slammed - gGL.getTexUnit(0)->bind(imagep); - } - } - else - { - desired_pixels = llmin(mPixelArea, (F32)TEX_IMAGE_AREA_OTHER ); - imagep->setBoostLevel(LLViewerTexture::BOOST_AVATAR); - } - imagep->addTextureStats( desired_pixels / texel_area_ratio ); - if (imagep->getDiscardLevel() < 0) - { - mHasGrey = TRUE; // for statistics gathering - } - } - else - { - // texture asset is missing - mHasGrey = TRUE; // for statistics gathering - } - } + // No local texture stats for non-self avatars + return; } const F32 SELF_ADDITIONAL_PRI = 0.75f ; @@ -6094,43 +5962,45 @@ BOOL LLVOAvatar::loadAvatar() LLVOAvatarXmlInfo::layer_info_list_t::iterator iter; for (iter = sAvatarXmlInfo->mLayerInfoList.begin(); iter != sAvatarXmlInfo->mLayerInfoList.end(); iter++) - { - LLTexLayerSetInfo *info = *iter; - LLTexLayerSet* layer_set = new LLTexLayerSet( this ); - if (!layer_set->setInfo(info)) { - stop_glerror(); - delete layer_set; - llwarns << "avatar file: layer_set->parseData() failed" << llendl; - return FALSE; - } - bool found_baked_entry = false; - for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); - baked_iter++) - { - const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; - if (layer_set->isBodyRegion(baked_dict->mName)) + LLTexLayerSetInfo *info = *iter; + + LLTexLayerSet* layer_set = new LLTexLayerSet((LLVOAvatarSelf*)this ); + if (layer_set && !layer_set->setInfo(info)) { - mBakedTextureDatas[baked_iter->first].mTexLayerSet = layer_set; - layer_set->setBakedTexIndex(baked_iter->first); - found_baked_entry = true; - break; + stop_glerror(); + delete layer_set; + llwarns << "avatar file: layer_set->parseData() failed" << llendl; + return FALSE; + } + bool found_baked_entry = false; + for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + baked_iter++) + { + const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; + if (layer_set && layer_set->isBodyRegion(baked_dict->mName)) + { + mBakedTextureDatas[baked_iter->first].mTexLayerSet = layer_set; + layer_set->setBakedTexIndex(baked_iter->first); + found_baked_entry = true; + break; + } + } + if (layer_set && !found_baked_entry) + { + llwarns << " has invalid body_region attribute" << llendl; + delete layer_set; + return FALSE; } } - if (!found_baked_entry) - { - llwarns << " has invalid body_region attribute" << llendl; - delete layer_set; - return FALSE; - } } - } + // avatar_lad.xml : - LLVOAvatarXmlInfo::driver_info_list_t::iterator iter; - for (iter = sAvatarXmlInfo->mDriverInfoList.begin(); - iter != sAvatarXmlInfo->mDriverInfoList.end(); iter++) + for (LLVOAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin(); + iter != sAvatarXmlInfo->mDriverInfoList.end(); + ++iter) { LLDriverParamInfo *info = *iter; LLDriverParam* driver_param = new LLDriverParam( this ); @@ -6481,7 +6351,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) // We always want to look good to ourselves if( isSelf() ) { - mPixelArea = llmax( mPixelArea, F32(TEX_IMAGE_SIZE_SELF / 16) ); + mPixelArea = llmax( mPixelArea, F32(getTexImageSize() / 16) ); } } @@ -6742,26 +6612,6 @@ LLPolyMesh* LLVOAvatar::getMesh( LLPolyMeshSharedData *shared_data ) return NULL; } -//----------------------------------------------------------------------------- -// requestLayerSetUpdate() -//----------------------------------------------------------------------------- -void LLVOAvatar::requestLayerSetUpdate(ETextureIndex index ) -{ - /* switch(index) - case LOCTEX_UPPER_BODYPAINT: - case LOCTEX_UPPER_SHIRT: - if( mUpperBodyLayerSet ) - mUpperBodyLayerSet->requestUpdate(); */ - const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); - if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) - return; - const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; - if (mBakedTextureDatas[baked_index].mTexLayerSet) - { - mBakedTextureDatas[baked_index].mTexLayerSet->requestUpdate(); - } -} - BOOL LLVOAvatar::setParent(LLViewerObject* parent) { BOOL ret ; @@ -6802,7 +6652,10 @@ void LLVOAvatar::addChild(LLViewerObject *childp) void LLVOAvatar::removeChild(LLViewerObject *childp) { LLViewerObject::removeChild(childp); - detachObject(childp); + if (!detachObject(childp)) + { + llwarns << "Calling detach on non-attached object " << llendl; + } } //LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* viewer_object) @@ -6840,47 +6693,13 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(const LLViewerObje //----------------------------------------------------------------------------- // attachObject() //----------------------------------------------------------------------------- -BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object) +const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_object) { LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object); - // testzone attachpt - if(!attachment) - { - S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState()); - LLUUID item_id; - LLNameValue* item_id_nv = viewer_object->getNVPair("AttachItemID"); - if( item_id_nv ) - { - const char* s = item_id_nv->getString(); - if(s) - item_id.set(s); - } - if(!item_id.isNull()) - { - mUnsupportedAttachmentPoints[attachmentID] = std::pair(item_id,viewer_object->getID()); - if (viewer_object->isSelected()) - { - LLSelectMgr::getInstance()->updateSelectionCenter(); - LLSelectMgr::getInstance()->updatePointAt(); - } - - if (isSelf()) - { - updateAttachmentVisibility(gAgentCamera.getCameraMode()); - - // Then make sure the inventory is in sync with the avatar. - gInventory.addChangedMask( LLInventoryObserver::LABEL, item_id ); - gInventory.notifyObservers(); - } - } - else - llwarns << "No item ID" << llendl; - } - // if (!attachment || !attachment->addObject(viewer_object)) { - return FALSE; + return 0; } if (viewer_object->isSelected()) @@ -6889,35 +6708,7 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object) LLSelectMgr::getInstance()->updatePointAt(); } - if (isSelf()) - { - updateAttachmentVisibility(gAgentCamera.getCameraMode()); - -// [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a - // NOTE: RLVa event handlers should be invoked *after* LLVOAvatar::attachObject() calls LLViewerJointAttachment::addObject() - if (rlv_handler_t::isEnabled()) - { - RlvAttachmentLockWatchdog::instance().onAttach(viewer_object, attachment); - gRlvHandler.onAttach(viewer_object, attachment); - - if ( (attachment->getIsHUDAttachment()) && (!gRlvAttachmentLocks.hasLockedHUD()) ) - gRlvAttachmentLocks.updateLockedHUD(); - } -// [/RLVa:KB] - - // Then make sure the inventory is in sync with the avatar. - gInventory.addChangedMask(LLInventoryObserver::LABEL, viewer_object->getAttachmentItemID()); - gInventory.notifyObservers(); - - // Should just be the last object added - if (attachment->isObjectAttached(viewer_object)) - { - LLCOFMgr::instance().addAttachment(viewer_object->getAttachmentItemID()); - updateLODRiggedAttachments(); - } - } - - return TRUE; + return attachment; } U32 LLVOAvatar::getNumAttachments() const @@ -7073,100 +6864,10 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) } // [/RLVa:KB] cleanupAttachedMesh( viewer_object ); - LLUUID item_id = viewer_object->getAttachmentItemID(); attachment->removeObject(viewer_object); - if (isSelf()) - { - // the simulator should automatically handle - // permission revocation - - stopMotionFromSource(viewer_object->getID()); - LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE); - - 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* child_objectp = *iter; - // the simulator should automatically handle - // permissions revocation - - stopMotionFromSource(child_objectp->getID()); - LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE); - } - -// [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Added: RLVa-1.2.1a - if ( (rlv_handler_t::isEnabled()) && (viewer_object->isHUDAttachment()) && (gRlvAttachmentLocks.hasLockedHUD()) ) - gRlvAttachmentLocks.updateLockedHUD(); -// [/RLVa:KB] - } - lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl; - if (isSelf()) - { - // Then make sure the inventory is in sync with the avatar. - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - gInventory.notifyObservers(); - - // Update COF contents (unless the avatar is being destroyed) - if ( (getRegion()) && (!isDead()) ) - { - LLCOFMgr::instance().removeAttachment(item_id); - } - } return TRUE; } - } - - // testzone attachpt - LLUUID item_id; - LLNameValue* item_id_nv = viewer_object->getNVPair("AttachItemID"); - if( item_id_nv ) - { - const char* s = item_id_nv->getString(); - if(s) - item_id.set(s); - } - if(!item_id.isNull()) - { - std::map >::iterator iter = mUnsupportedAttachmentPoints.begin(); - std::map >::iterator end = mUnsupportedAttachmentPoints.end(); - for( ; iter != end; ++iter) - { - if((*iter).second.first == item_id) - { - mUnsupportedAttachmentPoints.erase((*iter).first); - if (isSelf()) - { - // the simulator should automatically handle - // permission revocation - - stopMotionFromSource(viewer_object->getID()); - LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE); - - 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* child_objectp = *iter; - // the simulator should automatically handle - // permissions revocation - - stopMotionFromSource(child_objectp->getID()); - LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE); - } - // Then make sure the inventory is in sync with the avatar. - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - gInventory.notifyObservers(); - } - return TRUE; - } - } - llwarns << "Not found" << llendl; - } - else - llwarns << "No item ID" << llendl; - // - + } return FALSE; } @@ -7322,16 +7023,6 @@ void LLVOAvatar::getOffObject() } } - - - - - - - - - - //----------------------------------------------------------------------------- // findAvatarFromAttachment() //----------------------------------------------------------------------------- @@ -7354,176 +7045,11 @@ LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj ) return NULL; } -//----------------------------------------------------------------------------- -// isWearingAttachment() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::isWearingAttachment( const LLUUID& inv_item_id ) +// warning: order(N) not order(1) +S32 LLVOAvatar::getAttachmentCount() { - const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); ) - { - attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if(attachment->getAttachedObject(base_inv_item_id)) - { - return TRUE; - } - } - return FALSE; -} - -// testzone attachpt -BOOL LLVOAvatar::isWearingUnsupportedAttachment( const LLUUID& inv_item_id ) -{ - std::map >::iterator end = mUnsupportedAttachmentPoints.end(); - for(std::map >::iterator iter = mUnsupportedAttachmentPoints.begin(); iter != end; ++iter) - { - if((*iter).second.first == inv_item_id) - { - return TRUE; - } - } - return FALSE; -} -//----------------------------------------------------------------------------- -// getWornAttachment() -//----------------------------------------------------------------------------- -LLViewerObject* LLVOAvatar::getWornAttachment( const LLUUID& inv_item_id ) -{ - const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); ) - { - attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if (LLViewerObject *attached_object = attachment->getAttachedObject(base_inv_item_id)) - { - return attached_object; - } - } - return NULL; -} - -// [RLVa:KB] - Checked: 2010-03-14 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a -LLViewerJointAttachment* LLVOAvatar::getWornAttachmentPoint(const LLUUID& idItem) const -{ - const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem); - for (attachment_map_t::const_iterator itAttachPt = mAttachmentPoints.begin(); itAttachPt != mAttachmentPoints.end(); ++itAttachPt) - { - LLViewerJointAttachment* pAttachPt = itAttachPt->second; - if (pAttachPt->getAttachedObject(idItemBase)) - return pAttachPt; - } - return NULL; -} -// [/RLVa:KB] - -const std::string LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id) -{ - const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); ) - { - attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getAttachedObject(base_inv_item_id)) - { - return attachment->getName(); - } - } - - return LLStringUtil::null; -} - - - - - - - - - - - - - - - - -//----------------------------------------------------------------------------- -// static -// onLocalTextureLoaded() -//----------------------------------------------------------------------------- - -void LLVOAvatar::onLocalTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) -{ - //llinfos << "onLocalTextureLoaded: " << src_vi->getID() << llendl; - - const LLUUID& src_id = src_vi->getID(); - LLAvatarTexData *data = (LLAvatarTexData *)userdata; - if (success) - { - LLVOAvatar *self = gObjectList.findAvatar(data->mAvatarID); - if (self) - { - ETextureIndex index = data->mIndex; - if (!self->isIndexLocalTexture(index)) return; - LocalTextureData &local_tex_data = self->mLocalTextureData[index]; - if(!local_tex_data.mIsBakedReady && - local_tex_data.mImage.notNull() && - (local_tex_data.mImage->getID() == src_id) && - discard_level < local_tex_data.mDiscard) - { - local_tex_data.mDiscard = discard_level; - if ( self->isSelf() && !gAgentCamera.cameraCustomizeAvatar() ) - { - self->requestLayerSetUpdate( index ); - } - else if( self->isSelf() && gAgentCamera.cameraCustomizeAvatar() ) - { - LLVisualParamHint::requestHintUpdates(); - } - self->updateMeshTextures(); - } - } - } - else if (final) - { - LLVOAvatar *self = gObjectList.findAvatar(data->mAvatarID); - if (self) - { - ETextureIndex index = data->mIndex; - if (!self->isIndexLocalTexture(index)) return; - LocalTextureData &local_tex_data = self->mLocalTextureData[index]; - // Failed: asset is missing - if(!local_tex_data.mIsBakedReady && - local_tex_data.mImage.notNull() && - local_tex_data.mImage->getID() == src_id) - { - local_tex_data.mDiscard = 0; - self->requestLayerSetUpdate( index ); - self->updateMeshTextures(); - } - } - } - - if( final || !success ) - { - delete data; - } -} - -void LLVOAvatar::updateComposites() -{ - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if ( mBakedTextureDatas[i].mTexLayerSet - && ((i != BAKED_SKIRT) || isWearingWearableType( LLWearableType::WT_SKIRT )) ) - { - mBakedTextureDatas[i].mTexLayerSet->updateComposite(); - } - } + S32 count = mAttachmentPoints.size(); + return count; } LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const @@ -7550,63 +7076,10 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result ) { - if( !layerset || !layerset->getUpdatesEnabled() ) - { - return; - } - - /* Debug spam. JC - const char* layer_name = ""; - if (layerset == mHeadLayerSet) - { - layer_name = "head"; - } - else if (layerset == mUpperBodyLayerSet) - { - layer_name = "upperbody"; - } - else if (layerset == mLowerBodyLayerSet) - { - layer_name = "lowerbody"; - } - else if (layerset == mEyesLayerSet) - { - layer_name = "eyes"; - } - else if (layerset == mHairLayerSet) - { - layer_name = "hair"; - } - else if (layerset == mSkirtLayerSet) - { - layer_name = "skirt"; - } - else - { - layer_name = "unknown"; - } - llinfos << "LLVOAvatar::invalidComposite() " << layer_name << llendl; - */ - - layerset->requestUpdate(); - - if( upload_result ) - { - llassert( isSelf() ); - - ETextureIndex baked_te = getBakedTE( layerset ); - setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR,0)); - layerset->requestUpload(); - } } void LLVOAvatar::invalidateAll() { - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE); - } - updateMeshTextures(); } void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake ) @@ -7647,89 +7120,6 @@ BOOL LLVOAvatar::isVisible() const && (mDrawable->isVisible() || mIsDummy); } -void LLVOAvatar::forceBakeAllTextures(bool slam_for_debug) -{ - llinfos << "TAT: forced full rebake. " << llendl; - - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex; - LLTexLayerSet* layer_set = getLayerSet(baked_index); - if (layer_set) - { - if (slam_for_debug) - { - layer_set->setUpdatesEnabled(TRUE); - layer_set->cancelUpload(); - } - - BOOL set_by_user = TRUE; - invalidateComposite(layer_set, set_by_user); - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); - } - else - { - llwarns << "TAT: NO LAYER SET FOR " << (S32)baked_index << llendl; - } - } - - // Don't know if this is needed - updateMeshTextures(); -} - - -// static -void LLVOAvatar::processRebakeAvatarTextures(LLMessageSystem* msg, void**) -{ - LLUUID texture_id; - msg->getUUID("TextureData", "TextureID", texture_id); - - LLVOAvatar* self = gAgentAvatarp; - if (!self) return; - - // If this is a texture corresponding to one of our baked entries, - // just rebake that layer set. - BOOL found = FALSE; - - /* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] = - TEX_HEAD_BAKED, - TEX_UPPER_BAKED, */ - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); - iter++) - { - const ETextureIndex index = iter->first; - const LLVOAvatarDictionary::TextureEntry *text_dict = iter->second; - if (text_dict->mIsBakedTexture) - { - if (texture_id == self->getTEImage(index)->getID()) - { - LLTexLayerSet* layer_set = self->getLayerSet(index); - if (layer_set) - { - llinfos << "TAT: rebake - matched entry " << (S32)index << llendl; - // Apparently set_by_user == force upload - BOOL set_by_user = TRUE; - self->invalidateComposite(layer_set, set_by_user); - found = TRUE; - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); - } - } - } - } - - // If texture not found, rebake all entries. - if (!found) - { - self->forceBakeAllTextures(); - } - else - { - // Not sure if this is necessary, but forceBakeAllTextures() does it. - self->updateMeshTextures(); - } -} - /*BOOL LLVOAvatar::getLocalTextureRaw(ETextureIndex index, LLImageRaw* image_raw) { @@ -7757,117 +7147,57 @@ void LLVOAvatar::processRebakeAvatarTextures(LLMessageSystem* msg, void**) return success; }*/ -BOOL LLVOAvatar::getLocalTextureGL(ETextureIndex index, LLViewerTexture** image_gl_pp) + + + +// Determine if we have enough avatar data to render +BOOL LLVOAvatar::getIsCloud() { - if (!isIndexLocalTexture(index)) return FALSE; - - BOOL success = FALSE; - *image_gl_pp = NULL; - - if (getLocalTextureID(index) == IMG_DEFAULT_AVATAR) + // Do we have a shape? + if (visualParamWeightsAreDefault()) { - success = TRUE; - } - else - { - LocalTextureData &local_tex_data = mLocalTextureData[index]; - *image_gl_pp = local_tex_data.mImage; - success = TRUE; + return TRUE; } - if( !success ) + if (!isTextureDefined(TEX_LOWER_BAKED) || + !isTextureDefined(TEX_UPPER_BAKED) || + !isTextureDefined(TEX_HEAD_BAKED)) { -// llinfos << "getLocalTextureGL(" << index << ") had no data" << llendl; + return TRUE; } - return success; + + return FALSE; } -const LLUUID& LLVOAvatar::getLocalTextureID(ETextureIndex index) -{ - if (!isIndexLocalTexture(index)) return IMG_DEFAULT_AVATAR; - - if (mLocalTextureData[index].mImage.notNull()) - { - return mLocalTextureData[index].mImage->getID(); - } - else - { - return IMG_DEFAULT_AVATAR; - } -} - -// static -void LLVOAvatar::dumpTotalLocalTextureByteCount() -{ - S32 total_gl_bytes = 0; - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* cur = (LLVOAvatar*) *iter; - S32 gl_bytes = 0; - cur->getLocalTextureByteCount(&gl_bytes ); - total_gl_bytes += gl_bytes; - } - llinfos << "Total Avatar LocTex GL:" << (total_gl_bytes/1024) << "KB" << llendl; -} - - // call periodically to keep isFullyLoaded up to date. // returns true if the value has changed. BOOL LLVOAvatar::updateIsFullyLoaded() { - // a "heuristic" to determine if we have enough avatar data to render - // (to avoid rendering a "Ruth" - DEV-3168) + const BOOL loading = getIsCloud(); + updateRuthTimer(loading); + return processFullyLoadedChange(loading); +} - BOOL loading = FALSE; - - // do we have a shape? - if (visualParamWeightsAreDefault()) +void LLVOAvatar::updateRuthTimer(bool loading) +{ + if (isSelf() || !loading) { - loading = TRUE; + return; } - // - if (isSelf()) + if (!mPreviousFullyLoaded && sendAvatarTexturesRequest()) { - if (!isTextureDefined(TEX_HAIR)) - { - loading = TRUE; - } + llinfos << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " + << "( Params loaded : " << !visualParamWeightsAreDefault() << " ) " + << "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) " + << "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) " + << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )." + << llendl; } - else if (!isTextureDefined(TEX_LOWER_BAKED) || !isTextureDefined(TEX_UPPER_BAKED) || !isTextureDefined(TEX_HEAD_BAKED)) - { - loading = TRUE; - } - - // special case to keep nudity off orientation island - - // this is fragilely dependent on the compositing system, - // which gets available textures in the following order: - // - // 1) use the baked texture - // 2) use the layerset - // 3) use the previously baked texture - // - // on orientation island case (3) can show naked skin. - // so we test for that here: - // - // if we were previously unloaded, and we don't have enough - // texture info for our shirt/pants, stay unloaded: - if (!mPreviousFullyLoaded) - { - if ((!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet)) && - (!isTextureDefined(TEX_LOWER_BAKED))) - { - loading = TRUE; - } +} - if ((!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet)) && - (!isTextureDefined(TEX_UPPER_BAKED))) - { - loading = TRUE; - } - } - +BOOL LLVOAvatar::processFullyLoadedChange(bool loading) +{ // we wait a little bit before giving the all clear, // to let textures settle down const F32 PAUSE = 1.f; @@ -7876,8 +7206,6 @@ BOOL LLVOAvatar::updateIsFullyLoaded() mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); - updateRuthTimer(loading); - // did our loading state "change" from last call? const S32 UPDATE_RATE = 30; BOOL changed = @@ -7919,24 +7247,6 @@ bool LLVOAvatar::sendAvatarTexturesRequest() return sent; } -void LLVOAvatar::updateRuthTimer(bool loading) -{ - if (isSelf() || !loading) - { - return; - } - - if (!mPreviousFullyLoaded && sendAvatarTexturesRequest()) - { - llinfos << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' " - << "( Params loaded : " << !visualParamWeightsAreDefault() << " ) " - << "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) " - << "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) " - << "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )." - << llendl; - } -} - //----------------------------------------------------------------------------- // findMotion() //----------------------------------------------------------------------------- @@ -7945,179 +7255,6 @@ LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const return mMotionController.findMotion(id); } -// Counts the memory footprint of local textures. -void LLVOAvatar::getLocalTextureByteCount( S32* gl_bytes ) -{ - *gl_bytes = 0; - for( S32 i = 0; i < TEX_NUM_INDICES; i++ ) - { - if (!isIndexLocalTexture((ETextureIndex)i)) continue; - LLViewerTexture* image_gl = mLocalTextureData[(ETextureIndex)i].mImage; - if( image_gl ) - { - S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); - - if( image_gl->hasGLTexture() ) - { - *gl_bytes += bytes; - } - } - } -} - - -BOOL LLVOAvatar::bindScratchTexture( LLGLenum format ) -{ - U32 texture_bytes = 0; - GLuint gl_name = getScratchTexName( format, &texture_bytes ); - if( gl_name ) - { - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name); - stop_glerror(); - - F32* last_bind_time = LLVOAvatar::sScratchTexLastBindTime.getIfThere( format ); - if( last_bind_time ) - { - if( *last_bind_time != LLImageGL::sLastFrameTime ) - { - *last_bind_time = LLImageGL::sLastFrameTime; - LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - } - } - else - { - LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) ); - } - - - return TRUE; - } - else - { - return FALSE; - } -} - - -LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes ) -{ - S32 components; - GLenum internal_format; - switch( format ) - { - case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break; - case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break; -// Support for GL_EXT_paletted_texture is deprecated -// case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; - case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break; - case GL_RGB: components = 3; internal_format = GL_RGB8; break; - case GL_RGBA: components = 4; internal_format = GL_RGBA8; break; - default: llassert(0); components = 4; internal_format = GL_RGBA8; break; - } - - *texture_bytes = components * SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT; - - if( LLVOAvatar::sScratchTexNames.checkData( format ) ) - { - return *( LLVOAvatar::sScratchTexNames.getData( format ) ); - } - else - { - - LLGLSUIDefault gls_ui; - - U32 name = 0; - LLImageGL::generateTextures(1, &name ); - stop_glerror(); - - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name); - stop_glerror(); - - LLImageGL::setManualImage( - GL_TEXTURE_2D, 0, internal_format, - SCRATCH_TEX_WIDTH, SCRATCH_TEX_HEIGHT, - format, GL_UNSIGNED_BYTE, NULL ); - stop_glerror(); - - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - stop_glerror(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - stop_glerror(); - - LLVOAvatar::sScratchTexNames.addData( format, new LLGLuint( name ) ); - - LLVOAvatar::sScratchTexBytes += *texture_bytes; - LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes; - - if(gAuditTexture) - { - LLImageGL::incTextureCounter(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ; - } - - return name; - } -} - - - -//----------------------------------------------------------------------------- -// setLocalTextureTE() -//----------------------------------------------------------------------------- -void LLVOAvatar::setLocTexTE( U8 te, LLViewerTexture* image, BOOL set_by_user ) -{ - if( !isSelf() ) - { - llassert( 0 ); - return; - } - - if( te >= TEX_NUM_INDICES ) - { - llassert(0); - return; - } - - if( getTEImage( te )->getID() == image->getID() ) - { - return; - } - - if (isIndexBakedTexture((ETextureIndex)te)) - { - llassert(0); - return; - } - - LLTexLayerSet* layer_set = getLayerSet((ETextureIndex)te); - if (layer_set) - { - invalidateComposite(layer_set, set_by_user); - } - - setTEImage( te, image ); - updateMeshTextures(); - - if( gAgentCamera.cameraCustomizeAvatar() ) - { - LLVisualParamHint::requestHintUpdates(); - } -} - -void LLVOAvatar::setupComposites() -{ - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - bool layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); - if (mBakedTextureDatas[i].mTexLayerSet) - { - mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( !layer_baked ); - } - } -} - //----------------------------------------------------------------------------- // updateMeshTextures() // Uses the current TE values to set the meshes' and layersets' textures. @@ -8155,10 +7292,11 @@ void LLVOAvatar::updateMeshTextures() // When an avatar is changing clothes and not in Appearance mode, // use the last-known good baked texture until it finish the first // render of the new layerset. + const BOOL layerset_invalid = mBakedTextureDatas[i].mTexLayerSet + && ( !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized()); use_lkg_baked_layer[i] = (!is_layer_baked[i] - && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) - && mBakedTextureDatas[i].mTexLayerSet - && !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized()); + && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) + && layerset_invalid); if (use_lkg_baked_layer[i]) { mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE); @@ -8270,83 +7408,14 @@ void LLVOAvatar::updateMeshTextures() removeMissingBakedTextures(); } +// virtual //----------------------------------------------------------------------------- // setLocalTexture() //----------------------------------------------------------------------------- -void LLVOAvatar::setLocalTexture( ETextureIndex index, LLViewerFetchedTexture* tex, BOOL baked_version_ready ) +void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, BOOL baked_version_ready ) { - if (!isIndexLocalTexture(index)) return; - - S32 desired_discard = isSelf() ? 0 : 2; - LocalTextureData &local_tex_data = mLocalTextureData[index]; - if (!baked_version_ready) - { - if (tex != local_tex_data.mImage || local_tex_data.mIsBakedReady) - { - local_tex_data.mDiscard = MAX_DISCARD_LEVEL+1; - } - if (tex->getID() != IMG_DEFAULT_AVATAR) - { - if (local_tex_data.mDiscard > desired_discard) - { - S32 tex_discard = tex->getDiscardLevel(); - if (tex_discard >= 0 && tex_discard <= desired_discard) - { - local_tex_data.mDiscard = tex_discard; - if( isSelf() && !gAgentCamera.cameraCustomizeAvatar() ) - { - requestLayerSetUpdate( index ); - } - else if( isSelf() && gAgentCamera.cameraCustomizeAvatar() ) - { - LLVisualParamHint::requestHintUpdates(); - } - } - else - { - tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), index), NULL ); - } - } - tex->setMinDiscardLevel(desired_discard); - } - } - local_tex_data.mIsBakedReady = baked_version_ready; - local_tex_data.mImage = tex; -} - -//----------------------------------------------------------------------------- -// requestLayerSetUploads() -//----------------------------------------------------------------------------- -void LLVOAvatar::requestLayerSetUploads() -{ - llassert_always(isSelf()); - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - requestLayerSetUpload((EBakedTextureIndex)i); - } -} - -void LLVOAvatar::requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i) -{ - bool layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex); - if ( !layer_baked && mBakedTextureDatas[i].mTexLayerSet ) - { - mBakedTextureDatas[i].mTexLayerSet->requestUpload(); - } -} - -//----------------------------------------------------------------------------- -// setCompositeUpdatesEnabled() -//----------------------------------------------------------------------------- -void LLVOAvatar::setCompositeUpdatesEnabled( BOOL b ) -{ - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if (mBakedTextureDatas[i].mTexLayerSet ) - { - mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( b ); - } - } + // invalid for anyone but self + llassert(0); } void LLVOAvatar::setNameFromChat(const std::string &text) { @@ -8394,181 +7463,6 @@ void LLVOAvatar::clearChat() mChats.clear(); } -S32 LLVOAvatar::getLocalDiscardLevel( ETextureIndex index ) -{ - // If the texture is not local, we don't care and treat it as fully loaded - if (!isIndexLocalTexture(index)) return FALSE; - - LocalTextureData &local_tex_data = mLocalTextureData[index]; - if (index >= 0 - && getLocalTextureID(index) != IMG_DEFAULT_AVATAR - && !local_tex_data.mImage->isMissingAsset()) - { - return local_tex_data.mImage->getDiscardLevel(); - } - else - { - // We don't care about this (no image associated with the layer) treat as fully loaded. - return 0; - } -} - -//----------------------------------------------------------------------------- -// isLocalTextureDataFinal() -// Returns true if the highest quality discard level exists for every texture -// in the layerset. -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::isLocalTextureDataFinal( const LLTexLayerSet* layerset ) -{ - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if (layerset == mBakedTextureDatas[i].mTexLayerSet) - { - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - local_tex_iter++) - { - if (getLocalDiscardLevel(*local_tex_iter) != 0) - { - return FALSE; - } - } - return TRUE; - } - } - - llassert(0); - return FALSE; -} - -//----------------------------------------------------------------------------- -// isLocalTextureDataAvailable() -// Returns true if at least the lowest quality discard level exists for every texture -// in the layerset. -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::isLocalTextureDataAvailable( const LLTexLayerSet* layerset ) -{ - /* if( layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet ) - return getLocalDiscardLevel( TEX_HEAD_BODYPAINT ) >= 0; */ - for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); - baked_iter++) - { - const EBakedTextureIndex baked_index = baked_iter->first; - if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) - { - bool ret = true; - const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; - for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); - local_tex_iter != baked_dict->mLocalTextures.end(); - local_tex_iter++) - { - ret &= (getLocalDiscardLevel(*local_tex_iter) >= 0); - } - return ret; - } - } - llassert(0); - return FALSE; -} - - -//----------------------------------------------------------------------------- -// getBakedTE() -// Used by the LayerSet. (Layer sets don't in general know what textures depend on them.) -//----------------------------------------------------------------------------- -ETextureIndex LLVOAvatar::getBakedTE( LLTexLayerSet* layerset ) -{ - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if (layerset == mBakedTextureDatas[i].mTexLayerSet ) - { - return mBakedTextureDatas[i].mTextureIndex; - } - } - - llassert(0); - return TEX_HEAD_BAKED; -} - -//----------------------------------------------------------------------------- -// setNewBakedTexture() -// A new baked texture has been successfully uploaded and we can start using it now. -//----------------------------------------------------------------------------- -void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) -{ - // Baked textures live on other sims. - LLHost target_host = getObjectHost(); - setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) ); - if (uuid != IMG_INVISIBLE) - { - // Do not update textures when setting a new invisible baked texture as - // it would result in destroying the calling object (setNewBakedTexture() - // is called by LLTexLayerSetBuffer::render()) ! - updateMeshTextures(); - } - dirtyMesh(); - - - LLVOAvatar::cullAvatarsByPixelArea(); - - /* switch(te) - case TEX_HEAD_BAKED: - llinfos << "New baked texture: HEAD" << llendl; */ - const LLVOAvatarDictionary::TextureEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(te); - if (text_dict->mIsBakedTexture) - { - llinfos << "New baked texture: " << text_dict->mName << " UUID: " << uuid <mBakedTextureIndex].mTexLayerSet->requestUpdate(); - } - else - { - llwarns << "New baked texture: unknown te " << te << llendl; - } - - // dumpAvatarTEs( "setNewBakedTexture() send" ); - // RN: throttle uploads - if (!hasPendingBakedUploads()) - { - gAgent.sendAgentSetAppearance(); - } -} - -bool LLVOAvatar::hasPendingBakedUploads() -{ - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - bool upload_pending = (mBakedTextureDatas[i].mTexLayerSet && mBakedTextureDatas[i].mTexLayerSet->getComposite()->uploadPending()); - if (upload_pending) - { - return true; - } - } - return false; -} - -//----------------------------------------------------------------------------- -// setCachedBakedTexture() -// A baked texture id was received from a cache query, make it active -//----------------------------------------------------------------------------- -void LLVOAvatar::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid ) -{ - setTETexture( te, uuid ); - - /* switch(te) - case TEX_HEAD_BAKED: - if( mHeadLayerSet ) - mHeadLayerSet->cancelUpload(); */ - for (U32 i = 0; i < mBakedTextureDatas.size(); i++) - { - if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet) - { - mBakedTextureDatas[i].mTexLayerSet->cancelUpload(); - } - } -} - //----------------------------------------------------------------------------- // releaseComponentTextures() // release any component texture UUIDs for which we have a baked texture @@ -8607,52 +7501,6 @@ void LLVOAvatar::releaseComponentTextures() } } - - - - -//----------------------------------------------------------------------------- -// static -// onCustomizeStart() -//----------------------------------------------------------------------------- -void LLVOAvatar::onCustomizeStart() -{ - // We're no longer doing any baking or invalidating on entering - // appearance editing mode. Leaving function in place in case - // further changes require us to do something at this point - Nyx -} - -//----------------------------------------------------------------------------- -// static -// onCustomizeEnd() -//----------------------------------------------------------------------------- -void LLVOAvatar::onCustomizeEnd() -{ - LLVOAvatar *avatarp = gAgentAvatarp; - if (avatarp) - { - avatarp->invalidateAll(); - avatarp->requestLayerSetUploads(); - } -} - -void LLVOAvatar::onChangeSelfInvisible(BOOL newvalue) -{ - LLVOAvatar *avatarp = gAgentAvatarp; - if (avatarp) - { - if (newvalue) - { - // we have just requested to set the avatar's baked textures to invisible - avatarp->setInvisible(TRUE); - } - else - { - avatarp->setInvisible(FALSE); - } - } -} - //static BOOL LLVOAvatar::teToColorParams( ETextureIndex te, const char* param_name[3] ) { @@ -8798,64 +7646,8 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const } } -//----------------------------------------------------------------------------- -// updateAttachmentVisibility() -//----------------------------------------------------------------------------- -void LLVOAvatar::updateAttachmentVisibility(U32 camera_mode) -{ - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); ) - { - attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getIsHUDAttachment()) - { - attachment->setAttachmentVisibility(TRUE); - } - else - { - switch (camera_mode) - { - case CAMERA_MODE_MOUSELOOK: - if (LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson()) - { - attachment->setAttachmentVisibility(TRUE); - } - else - { - attachment->setAttachmentVisibility(FALSE); - } - break; - default: - attachment->setAttachmentVisibility(TRUE); - break; - } - } - } -} - -void LLVOAvatar::setInvisible(BOOL newvalue) -{ - if (newvalue) - { - setCompositeUpdatesEnabled(FALSE); - for (U32 i = 0; i < mBakedTextureDatas.size(); i++ ) - { - setNewBakedTexture(mBakedTextureDatas[i].mTextureIndex, IMG_INVISIBLE); - } - gAgent.sendAgentSetAppearance(); - } - else - { - setCompositeUpdatesEnabled(TRUE); - invalidateAll(); - requestLayerSetUploads(); - gAgent.sendAgentSetAppearance(); - } -} - // Unlike most wearable functions, this works for both self and other. -BOOL LLVOAvatar::isWearingWearableType( LLWearableType::EType type ) const +/*virtual*/ BOOL LLVOAvatar::isWearingWearableType( LLWearableType::EType type ) const { if (mIsDummy) return TRUE; @@ -8877,45 +7669,18 @@ BOOL LLVOAvatar::isWearingWearableType( LLWearableType::EType type ) const tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); ++tex_iter) { - const LLVOAvatarDefines::ETextureIndex index = tex_iter->first; - const LLVOAvatarDictionary::TextureEntry *text_dict = tex_iter->second; - if (text_dict->mWearableType == type) + const LLVOAvatarDictionary::TextureEntry *texture_dict = tex_iter->second; + if (texture_dict->mWearableType == type) { - // If you're checking your own clothing, check the component texture - if (isSelf()) - { - if (isTextureDefined(index)) - { - return TRUE; - } - else - { - return FALSE; - } - } - // If you're checking another avatar's clothing, you don't have component textures. // Thus, you must check to see if the corresponding baked texture is defined. // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that // gets baked into a texture that always exists (upper or lower). - const std::string name = text_dict->mName; - for (LLVOAvatarDictionary::BakedTextures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); - iter++) + if (texture_dict->mIsUsedByBakedTexture) { - const LLVOAvatarDictionary::BakedEntry *baked_dict = iter->second; - if (baked_dict->mName == name) - { - if (isTextureDefined(baked_dict->mTextureIndex)) - { - return TRUE; - } - else - { - return FALSE; - } - } + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + return isTextureDefined(LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex); } return FALSE; } @@ -8923,49 +7688,6 @@ BOOL LLVOAvatar::isWearingWearableType( LLWearableType::EType type ) const return FALSE; } -//----------------------------------------------------------------------------- -// wearableUpdated(EWearableType type, BOOL upload_result) -// forces an update to any baked textures relevant to type. -// will force an upload of the resulting bake if the second parameter is TRUE -//----------------------------------------------------------------------------- -void LLVOAvatar::wearableUpdated(LLWearableType::EType type, BOOL upload_result) -{ - for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); - baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); - ++baked_iter) - { - const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; - const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first; - - if (baked_dict) - { - for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin(); - type_iter != baked_dict->mWearables.end(); - ++type_iter) - { - const LLWearableType::EType comp_type = *type_iter; - if (comp_type == type) - { - if (mBakedTextureDatas[index].mTexLayerSet) - { - invalidateComposite(mBakedTextureDatas[index].mTexLayerSet, upload_result); - updateMeshTextures(); - } - break; - } - } - } - } - - // Physics type has no associated baked textures, but change of params needs to be sent to - // other avatars. - if (isSelf() && type == LLWearableType::WT_PHYSICS) - { - gAgent.sendAgentSetAppearance(); - } -} - - //----------------------------------------------------------------------------- // clampAttachmentPositions() //----------------------------------------------------------------------------- @@ -9078,6 +7800,41 @@ void LLVOAvatar::onFirstTEMessageReceived() } } +//----------------------------------------------------------------------------- +// bool visualParamWeightsAreDefault() +//----------------------------------------------------------------------------- +bool LLVOAvatar::visualParamWeightsAreDefault() +{ + bool rtn = true; + + bool is_wearing_skirt = isWearingWearableType(LLWearableType::WT_SKIRT); + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + if (param->isTweakable()) + { + LLViewerVisualParam* vparam = dynamic_cast(param); + llassert(vparam); + bool is_skirt_param = vparam && + LLWearableType::WT_SKIRT == vparam->getWearableType(); + if (param->getWeight() != param->getDefaultWeight() && + // we have to not care whether skirt weights are default, if we're not actually wearing a skirt + (is_wearing_skirt || !is_skirt_param)) + { + //llinfos << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << llendl; + rtn = false; + break; + } + } + } + + //llinfos << "params are default ? " << int(rtn) << llendl; + + return rtn; +} + + //----------------------------------------------------------------------------- // processAvatarAppearance() //----------------------------------------------------------------------------- @@ -9153,7 +7910,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // (isTextureDefined(TEX_HAIR_BAKED) ? "HAIR" : "hair " ) << (getTEImage(TEX_HAIR_BAKED)->getID()) << std::endl << // (isTextureDefined(TEX_EYES_BAKED) ? "EYES" : "eyes" ) << (getTEImage(TEX_EYES_BAKED)->getID()) << llendl ; - if( !mFirstTEMessageReceived ) + if( !is_first_appearance_message ) { onFirstTEMessageReceived(); } @@ -9657,144 +8414,6 @@ void LLVOAvatar::cullAvatarsByPixelArea() } } -const LLUUID& LLVOAvatar::grabLocalTexture(ETextureIndex index) -{ - if (canGrabLocalTexture(index)) - { - return getTEImage( index )->getID(); - } - return LLUUID::null; -} - -BOOL LLVOAvatar::canGrabLocalTexture(ETextureIndex index) -{ - // Check if the texture hasn't been baked yet. - if (!isTextureDefined(index)) - { - lldebugs << "getTEImage( " << (U32) index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl; - return FALSE; - } - - if (gAgent.isGodlike() && !gAgent.getAdminOverride()) - return TRUE; - - // Check permissions of textures that show up in the - // baked texture. We don't want people copying people's - // work via baked textures. - /* switch(index) - case TEX_EYES_BAKED: - textures.push_back(TEX_EYES_IRIS); */ - const LLVOAvatarDictionary::TextureEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); - if (!text_dict->mIsUsedByBakedTexture) return FALSE; - - const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; - const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index); - for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin(); - iter != baked_dict->mLocalTextures.end(); - iter++) - { - const ETextureIndex t_index = (*iter); - lldebugs << "Checking index " << (U32) t_index << llendl; - const LLUUID& texture_id = getTEImage( t_index )->getID(); - if (texture_id != IMG_DEFAULT_AVATAR) - { - // Search inventory for this texture. - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(texture_id); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); - - BOOL can_grab = FALSE; - lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl; - if (items.count()) - { - // search for full permissions version - for (S32 i = 0; i < items.count(); i++) - { - LLInventoryItem* itemp = items[i]; - LLPermissions item_permissions = itemp->getPermissions(); - if ( item_permissions.allowOperationBy( - PERM_MODIFY, gAgent.getID(), gAgent.getGroupID()) && - item_permissions.allowOperationBy( - PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && - item_permissions.allowOperationBy( - PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID()) ) - { - can_grab = TRUE; - break; - } - } - } - if (!can_grab) return FALSE; - } - } - - return TRUE; -} - -void LLVOAvatar::dumpLocalTextures() -{ - llinfos << "Local Textures:" << llendl; - - /* ETextureIndex baked_equiv[] = { - TEX_UPPER_BAKED, - if (isTextureDefined(baked_equiv[i])) */ - for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); - iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); - iter++) - { - const LLVOAvatarDictionary::TextureEntry *text_dict = iter->second; - if (!text_dict->mIsLocalTexture || !text_dict->mIsUsedByBakedTexture) - continue; - - const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; - const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex; - - const std::string &name = text_dict->mName; - const LocalTextureData &local_tex_data = mLocalTextureData[iter->first]; - if (isTextureDefined(baked_equiv)) - { -#if LL_RELEASE_FOR_DOWNLOAD - // End users don't get to trivially see avatar texture IDs, makes textures - // easier to steal. JC - llinfos << "LocTex " << name << ": Baked " << llendl; -#else - llinfos << "LocTex " << name << ": Baked " << getTEImage( baked_equiv )->getID() << llendl; -#endif - } - else if (local_tex_data.mImage.notNull()) - { - if( local_tex_data.mImage->getID() == IMG_DEFAULT_AVATAR ) - { - llinfos << "LocTex " << name << ": None" << llendl; - } - else - { - const LLViewerFetchedTexture* image = local_tex_data.mImage; - - llinfos << "LocTex " << name << ": " - << "Discard " << image->getDiscardLevel() << ", " - << "(" << image->getWidth() << ", " << image->getHeight() << ") " -#if !LL_RELEASE_FOR_DOWNLOAD - // End users don't get to trivially see avatar texture IDs, - // makes textures easier to steal - << image->getID() << " " -#endif - << "Priority: " << image->getDecodePriority() - << llendl; - } - } - else - { - llinfos << "LocTex " << name << ": No LLViewerTexture" << llendl; - } - } -} - void LLVOAvatar::startAppearanceAnimation(BOOL set_by_user, BOOL play_sound) { if(!mAppearanceAnimating) @@ -10251,13 +8870,6 @@ BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root) return TRUE; } -// warning: order(N) not order(1) -S32 LLVOAvatar::getAttachmentCount() -{ - S32 count = mAttachmentPoints.size(); - return count; -} - //virtual void LLVOAvatar::updateRegion(LLViewerRegion *regionp) @@ -10279,21 +8891,6 @@ std::string LLVOAvatar::getFullname() const return name; } -LLTexLayerSet* LLVOAvatar::getLayerSet(ETextureIndex index) const -{ - /* switch(index) - case TEX_HEAD_BAKED: - case TEX_HEAD_BODYPAINT: - return mHeadLayerSet; */ - const LLVOAvatarDictionary::TextureEntry *text_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); - if (text_dict->mIsUsedByBakedTexture) - { - const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; - return mBakedTextureDatas[baked_index].mTexLayerSet; - } - return NULL; -} - LLHost LLVOAvatar::getObjectHost() const { LLViewerRegion* region = getRegion(); @@ -10495,8 +9092,6 @@ void LLVOAvatar::idleUpdateRenderCost() mText->setColor(LLColor4(red,green,0,1)); } - - // static BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index) { @@ -10535,6 +9130,22 @@ const std::string LLVOAvatar::getBakedStatusForPrintout() const } + +//virtual +S32 LLVOAvatar::getTexImageSize() const +{ + return TEX_IMAGE_SIZE_OTHER; +} + +//----------------------------------------------------------------------------- +// Utility functions +//----------------------------------------------------------------------------- + +F32 calc_bouncy_animation(F32 x) +{ + return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f; +} + U32 calc_shame(LLVOVolume* volume, std::set &textures) { if (!volume) @@ -10638,12 +9249,3 @@ U32 calc_shame(LLVOVolume* volume, std::set &textures) return shame; } - -//----------------------------------------------------------------------------- -// Utility functions -//----------------------------------------------------------------------------- - -F32 calc_bouncy_animation(F32 x) -{ - return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f; -} diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 07a2da690..6dafdcac1 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -237,6 +237,7 @@ public: void idleUpdateLoadingEffect(); void idleUpdateWindEffect(); void idleUpdateNameTag(const LLVector3& root_pos_last); + LLVector3 idleUpdateNameTagPosition(const LLVector3& root_pos_last); void clearNameTag(); static void invalidateNameTag(const LLUUID& agent_id); // force all name tags to rebuild, useful when display names turned on/off @@ -244,8 +245,6 @@ public: void idleUpdateRenderCost(); void idleUpdateBelowWater(); void idleUpdateBoobEffect(); //Emerald - - void updateAttachmentVisibility(U32 camera_mode); //Agent only LLFrameTimer mIdleTimer; std::string getIdleTime(); @@ -282,8 +281,12 @@ public: //-------------------------------------------------------------------- public: BOOL isFullyLoaded() const; + bool visualParamWeightsAreDefault(); +protected: + virtual BOOL getIsCloud(); //BOOL isReallyFullyLoaded(); BOOL updateIsFullyLoaded(); + BOOL processFullyLoadedChange(bool loading); protected: bool sendAvatarTexturesRequest(); void updateRuthTimer(bool loading); @@ -484,6 +487,15 @@ public: private: static S32 sFreezeCounter; + //-------------------------------------------------------------------- + // Constants + //-------------------------------------------------------------------- +public: + virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; } + virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; } + virtual S32 getTexImageSize() const; + virtual S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); } + /** Rendering ** ** *******************************************************************************/ @@ -497,8 +509,8 @@ private: // Loading status //-------------------------------------------------------------------- public: - BOOL isTextureDefined(U8 te) const; - BOOL isTextureVisible(U8 te) const; + BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type) const; + BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type) const; protected: BOOL isFullyBaked(); @@ -533,8 +545,9 @@ protected: // Local Textures //-------------------------------------------------------------------- protected: - void setLocalTexture(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* tex, BOOL baked_version_exits); - void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked); + virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits); + virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked); + //-------------------------------------------------------------------- // Layers //-------------------------------------------------------------------- @@ -548,6 +561,9 @@ protected: public: virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result); virtual void invalidateAll(); + virtual void setCompositeUpdatesEnabled(bool b) {} + virtual void setCompositeUpdatesEnabled(U32 index, bool b) {} + virtual bool isCompositeUpdateEnabled(U32 index) { return false; } //-------------------------------------------------------------------- // Static texture/mesh/baked dictionary @@ -572,71 +588,14 @@ private: //Most this stuff is Agent only - - //-------------------------------------------------------------------- - // Textures and Layers - //-------------------------------------------------------------------- -protected: - void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i); - - - LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const; - S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex index); - //-------------------------------------------------------------------- // Other public functions //-------------------------------------------------------------------- -public: - static void dumpTotalLocalTextureByteCount(); -protected: - void getLocalTextureByteCount( S32* gl_byte_count ); public: - void dumpLocalTextures(); - const LLUUID& grabLocalTexture(LLVOAvatarDefines::ETextureIndex index); - BOOL canGrabLocalTexture(LLVOAvatarDefines::ETextureIndex index); - - void setCompositeUpdatesEnabled(BOOL b); - void setNameFromChat(const std::string &text); void clearNameFromChat(); -public: - - - //-------------------------------------------------------------------- - // texture compositing (used only by the LLTexLayer series of classes) - //-------------------------------------------------------------------- -public: - BOOL isLocalTextureDataAvailable( const LLTexLayerSet* layerset ); - BOOL isLocalTextureDataFinal( const LLTexLayerSet* layerset ); - LLVOAvatarDefines::ETextureIndex getBakedTE( LLTexLayerSet* layerset ); - void updateComposites(); - //BOOL getLocalTextureRaw( LLVOAvatarDefines::ETextureIndex index, LLImageRaw* image_raw_pp ); - BOOL getLocalTextureGL( LLVOAvatarDefines::ETextureIndex index, LLViewerTexture** image_gl_pp ); - const LLUUID& getLocalTextureID( LLVOAvatarDefines::ETextureIndex index ); - LLGLuint getScratchTexName( LLGLenum format, U32* texture_bytes ); - BOOL bindScratchTexture( LLGLenum format ); - void forceBakeAllTextures(bool slam_for_debug = false); - static void processRebakeAvatarTextures(LLMessageSystem* msg, void**); - void setNewBakedTexture( LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid ); - void setCachedBakedTexture( LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid ); - void requestLayerSetUploads(); - void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i); - bool hasPendingBakedUploads(); - static void onLocalTextureLoaded( BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ); - static void onChangeSelfInvisible(BOOL newvalue); - void setInvisible(BOOL newvalue); - - void wearableUpdated(LLWearableType::EType type, BOOL upload_result = TRUE); - - //-------------------------------------------------------------------- - // texture compositing - //-------------------------------------------------------------------- -public: - void setLocTexTE( U8 te, LLViewerTexture* image, BOOL set_by_user ); - void setupComposites(); - /** Textures ** ** *******************************************************************************/ @@ -683,7 +642,6 @@ public: void processAvatarAppearance(LLMessageSystem* mesgsys); void hideSkirt(); void startAppearanceAnimation(BOOL set_by_user, BOOL play_sound); - LLPolyMesh* getMesh(LLPolyMeshSharedData* shared_data); //-------------------------------------------------------------------- // Appearance morphing @@ -701,12 +659,12 @@ public: typedef std::map mesh_info_t; static void getMeshInfo(mesh_info_t* mesh_info); - + LLPolyMesh* getMesh( LLPolyMeshSharedData *shared_data ); //-------------------------------------------------------------------- // Clothing colors (convenience functions to access visual parameters) //-------------------------------------------------------------------- public: - void setClothesColor( LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL set_by_user ); + void setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake); LLColor4 getClothesColor(LLVOAvatarDefines::ETextureIndex te); static BOOL teToColorParams( LLVOAvatarDefines::ETextureIndex te, const char* param_name[3] ); @@ -715,7 +673,7 @@ public: //-------------------------------------------------------------------- public: LLColor4 getGlobalColor(const std::string& color_name ) const; - void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL set_by_user ); + void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake); private: LLTexGlobalColor* mTexSkinColor; LLTexGlobalColor* mTexHairColor; @@ -730,13 +688,6 @@ public: U32 getVisibilityRank() const { return mVisibilityRank; } // unused static S32 sNumVisibleAvatars; // Number of instances of this class static LLColor4 getDummyColor(); - - //-------------------------------------------------------------------- - // Customize - //-------------------------------------------------------------------- -public: - static void onCustomizeStart(); - static void onCustomizeEnd(); /** Appearance ** ** *******************************************************************************/ @@ -747,19 +698,19 @@ public: **/ public: - BOOL isWearingWearableType( LLWearableType::EType type ) const; + virtual BOOL isWearingWearableType(LLWearableType::EType type ) const; //-------------------------------------------------------------------- // Attachments //-------------------------------------------------------------------- public: void clampAttachmentPositions(); - BOOL attachObject(LLViewerObject *viewer_object); - BOOL detachObject(LLViewerObject *viewer_object); + virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object); + virtual BOOL detachObject(LLViewerObject *viewer_object); #if MESH_ENABLED void cleanupAttachedMesh( LLViewerObject* pVO ); #endif //MESH_ENABLED - static LLVOAvatar* findAvatarFromAttachment( LLViewerObject* obj ); + static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); protected: // [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i LLViewerJointAttachment* getTargetAttachmentPoint(const LLViewerObject* viewer_object) const; @@ -776,7 +727,8 @@ public: S32 getAttachmentCount(); // Warning: order(N) not order(1) // currently used only by -self typedef std::map attachment_map_t; attachment_map_t mAttachmentPoints; - std::vector > mPendingAttachment; + std::vector > mPendingAttachment; + //-------------------------------------------------------------------- // HUD functions //-------------------------------------------------------------------- @@ -789,25 +741,6 @@ public: protected: U32 getNumAttachments() const; // O(N), not O(1) - //-------------------------------------------------------------------- - // Old/nonstandard/Agent-only functions - //-------------------------------------------------------------------- -public: - static BOOL detachAttachmentIntoInventory(const LLUUID& item_id); - BOOL isWearingAttachment( const LLUUID& inv_item_id ); - // testzone attachpt - BOOL isWearingUnsupportedAttachment( const LLUUID& inv_item_id ); - // - LLViewerObject* getWornAttachment( const LLUUID& inv_item_id ); -// [RLVa:KB] - Checked: 2010-03-14 (RLVa-1.2.0a) | Added: RLVa-1.1.0i - LLViewerJointAttachment* getWornAttachmentPoint(const LLUUID& inv_item_id) const; -// [/RLVa:KB] - const std::string getAttachedPointName(const LLUUID& inv_item_id); - - // - std::map > mUnsupportedAttachmentPoints; - // - /** Wearables ** ** *******************************************************************************/ @@ -1073,7 +1006,6 @@ private: //-------------------------------------------------------------------- public: static void dumpArchetypeXML(void*); - static void dumpScratchTextureByteCount(); //Agent only static void dumpBakedStatus(); const std::string getBakedStatusForPrintout() const; void dumpAvatarTEs(const std::string& context) const; @@ -1086,7 +1018,6 @@ protected: S32 getUnbakedPixelAreaRank(); BOOL mHasGrey; private: - LLUUID mSavedTE[ LLVOAvatarDefines::TEX_NUM_INDICES ]; BOOL mHasBakedHair; F32 mMinPixelArea; F32 mMaxPixelArea; @@ -1248,15 +1179,15 @@ private: //----------------------------------------------------------------------------------------------- // Inlines //----------------------------------------------------------------------------------------------- -inline BOOL LLVOAvatar::isTextureDefined(U8 te) const +inline BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex type) const { - return (getTEImage(te)->getID() != IMG_DEFAULT_AVATAR && getTEImage(te)->getID() != IMG_DEFAULT); + return (getTEImage(type)->getID() != IMG_DEFAULT_AVATAR && getTEImage(type)->getID() != IMG_DEFAULT); } -inline BOOL LLVOAvatar::isTextureVisible(U8 te) const +inline BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type) const { - return ((isTextureDefined(te) || isSelf()) - && (getTEImage(te)->getID() != IMG_INVISIBLE + return ((isTextureDefined(type) || isSelf()) + && (getTEImage(type)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)); } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index ce1077c9c..441bea7f9 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -37,6 +37,7 @@ #include "llhudmanager.h" #include "llnotificationsutil.h" #include "llselectmgr.h" +#include "lltexlayer.h" #include "lltoolgrab.h" // for needsRenderBeam #include "lltoolmgr.h" // for needsRenderBeam #include "lltoolmorph.h" @@ -49,6 +50,10 @@ #include "llviewerregion.h" #include "llmeshrepository.h" #include "llvovolume.h" + +#include "cofmgr.h" +#include "rlvhandler.h" + LLVOAvatarSelf *gAgentAvatarp = NULL; BOOL isAgentAvatarValid() { @@ -57,6 +62,15 @@ BOOL isAgentAvatarValid() (!gAgentAvatarp->isDead())); } +using namespace LLVOAvatarDefines; +//----------------------------------------------------------------------------- +// Static Data +//----------------------------------------------------------------------------- +S32 LLVOAvatarSelf::sScratchTexBytes = 0; +LLMap< LLGLenum, LLGLuint*> LLVOAvatarSelf::sScratchTexNames; +LLMap< LLGLenum, F32*> LLVOAvatarSelf::sScratchTexLastBindTime; + + /********************************************************************************* ** ** ** Begin LLVOAvatarSelf Constructor routines @@ -445,6 +459,12 @@ void LLVOAvatarSelf::resetJointPositions( void ) { return LLVOAvatar::resetJointPositions(); } + +/*virtual*/ +void LLVOAvatarSelf::updateVisualParams() +{ + LLVOAvatar::updateVisualParams(); +} // virtual void LLVOAvatarSelf::requestStopMotion(LLMotion* motion) { @@ -469,6 +489,43 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id) object->mFlags &= ~FLAGS_ANIM_SOURCE; } } + +//----------------------------------------------------------------------------- +// setLocalTextureTE() +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::setLocalTextureTE( U8 te, LLViewerTexture* image, BOOL set_by_user ) +{ + if( te >= TEX_NUM_INDICES ) + { + llassert(0); + return; + } + + if( getTEImage( te )->getID() == image->getID() ) + { + return; + } + + if (isIndexBakedTexture((ETextureIndex)te)) + { + llassert(0); + return; + } + + LLTexLayerSet* layer_set = getLayerSet((ETextureIndex)te); + if (layer_set) + { + invalidateComposite(layer_set, set_by_user); + } + + setTEImage( te, image ); + updateMeshTextures(); + + if( gAgentCamera.cameraCustomizeAvatar() ) + { + LLVisualParamHint::requestHintUpdates(); + } +} //virtual void LLVOAvatarSelf::removeMissingBakedTextures() { @@ -496,6 +553,7 @@ void LLVOAvatarSelf::removeMissingBakedTextures() { for(U32 i = 0; i < mBakedTextureDatas.size(); i++) { + mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE); invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, FALSE); } updateMeshTextures(); @@ -652,6 +710,1171 @@ void LLVOAvatarSelf::restoreMeshData() // force mesh update as LOD might not have changed to trigger this gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE); } + +//----------------------------------------------------------------------------- +// updateAttachmentVisibility() +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode) +{ + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment->getIsHUDAttachment()) + { + attachment->setAttachmentVisibility(TRUE); + } + else + { + switch (camera_mode) + { + case CAMERA_MODE_MOUSELOOK: + if (LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson()) + { + attachment->setAttachmentVisibility(TRUE); + } + else + { + attachment->setAttachmentVisibility(FALSE); + } + break; + default: + attachment->setAttachmentVisibility(TRUE); + break; + } + } + } +} + +/*virtual*/ BOOL LLVOAvatarSelf::isWearingWearableType(LLWearableType::EType type ) const +{ + return gAgentWearables.getWearableCount(type) > 0; +} + +//----------------------------------------------------------------------------- +// wearableUpdated(EWearableType type, BOOL upload_result) +// forces an update to any baked textures relevant to type. +// will force an upload of the resulting bake if the second parameter is TRUE +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::wearableUpdated(LLWearableType::EType type, BOOL upload_result) +{ + for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + ++baked_iter) + { + const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; + const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first; + + if (baked_dict) + { + for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin(); + type_iter != baked_dict->mWearables.end(); + ++type_iter) + { + const LLWearableType::EType comp_type = *type_iter; + if (comp_type == type) + { + if (mBakedTextureDatas[index].mTexLayerSet) + { + mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled(true); + invalidateComposite(mBakedTextureDatas[index].mTexLayerSet, upload_result); + } + break; + } + } + } + } + + // Physics type has no associated baked textures, but change of params needs to be sent to + // other avatars. + if (type == LLWearableType::WT_PHYSICS) + { + gAgent.sendAgentSetAppearance(); + } +} + +//----------------------------------------------------------------------------- +// isWearingAttachment() +//----------------------------------------------------------------------------- +BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id ) const +{ + const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment* attachment = iter->second; + if(attachment->getAttachedObject(base_inv_item_id)) + { + return TRUE; + } + } + return FALSE; +} + +// testzone attachpt +BOOL LLVOAvatarSelf::isWearingUnsupportedAttachment( const LLUUID& inv_item_id ) +{ + std::map >::iterator end = mUnsupportedAttachmentPoints.end(); + for(std::map >::iterator iter = mUnsupportedAttachmentPoints.begin(); iter != end; ++iter) + { + if((*iter).second.first == inv_item_id) + { + return TRUE; + } + } + return FALSE; +} +//----------------------------------------------------------------------------- +// getWornAttachment() +//----------------------------------------------------------------------------- +LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id) +{ + const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (LLViewerObject *attached_object = attachment->getAttachedObject(base_inv_item_id)) + { + return attached_object; + } + } + return NULL; +} + +// [RLVa:KB] - Checked: 2010-03-14 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a +LLViewerJointAttachment* LLVOAvatarSelf::getWornAttachmentPoint(const LLUUID& idItem) const +{ + const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem); + for (attachment_map_t::const_iterator itAttachPt = mAttachmentPoints.begin(); itAttachPt != mAttachmentPoints.end(); ++itAttachPt) + { + LLViewerJointAttachment* pAttachPt = itAttachPt->second; + if (pAttachPt->getAttachedObject(idItemBase)) + return pAttachPt; + } + return NULL; +} +// [/RLVa:KB] + +const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id) const +{ + const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); + for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + const LLViewerJointAttachment* attachment = iter->second; + if (attachment->getAttachedObject(base_inv_item_id)) + { + return attachment->getName(); + } + } + + return LLStringUtil::null; +} + +//virtual +const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_object) +{ + const LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object); + if(!attachment) + { + // testzone attachpt + S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState()); + LLUUID item_id; + LLNameValue* item_id_nv = viewer_object->getNVPair("AttachItemID"); + if( item_id_nv ) + { + const char* s = item_id_nv->getString(); + if(s) + item_id.set(s); + } + if(!item_id.isNull()) + { + mUnsupportedAttachmentPoints[attachmentID] = std::pair(item_id,viewer_object->getID()); + if (viewer_object->isSelected()) + { + LLSelectMgr::getInstance()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updatePointAt(); + } + + updateAttachmentVisibility(gAgentCamera.getCameraMode()); + + // Then make sure the inventory is in sync with the avatar. + gInventory.addChangedMask( LLInventoryObserver::LABEL, item_id ); + gInventory.notifyObservers(); + } + else + llwarns << "No item ID" << llendl; + // + return 0; + } + + updateAttachmentVisibility(gAgentCamera.getCameraMode()); + +// [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a + // NOTE: RLVa event handlers should be invoked *after* LLVOAvatar::attachObject() calls LLViewerJointAttachment::addObject() + if (rlv_handler_t::isEnabled()) + { + RlvAttachmentLockWatchdog::instance().onAttach(viewer_object, attachment); + gRlvHandler.onAttach(viewer_object, attachment); + + if ( (attachment->getIsHUDAttachment()) && (!gRlvAttachmentLocks.hasLockedHUD()) ) + gRlvAttachmentLocks.updateLockedHUD(); + } +// [/RLVa:KB] + + // Then make sure the inventory is in sync with the avatar. + gInventory.addChangedMask(LLInventoryObserver::LABEL, viewer_object->getAttachmentItemID()); + gInventory.notifyObservers(); + + // Should just be the last object added + if (attachment->isObjectAttached(viewer_object)) + { + LLCOFMgr::instance().addAttachment(viewer_object->getAttachmentItemID()); + updateLODRiggedAttachments(); + } + + return attachment; +} + +//virtual +BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) +{ + const LLUUID attachment_id = viewer_object->getAttachmentItemID(); + const std::string point_name = getAttachedPointName(attachment_id); + if(LLVOAvatar::detachObject(viewer_object)) + { + LLVOAvatar::cleanupAttachedMesh( viewer_object ); + + // the simulator should automatically handle permission revocation + + stopMotionFromSource(attachment_id); + LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE); + + 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* child_objectp = *iter; + // the simulator should automatically handle + // permissions revocation + + stopMotionFromSource(child_objectp->getID()); + LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE); + } + +// [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Added: RLVa-1.2.1a + if ( (rlv_handler_t::isEnabled()) && (viewer_object->isHUDAttachment()) && (gRlvAttachmentLocks.hasLockedHUD()) ) + gRlvAttachmentLocks.updateLockedHUD(); +// [/RLVa:KB] + + lldebugs << "Detaching object " << viewer_object->mID << " from " << point_name << llendl; + + // Then make sure the inventory is in sync with the avatar. + gInventory.addChangedMask(LLInventoryObserver::LABEL, attachment_id); + gInventory.notifyObservers(); + + // Update COF contents (unless the avatar is being destroyed) + if (!isAgentAvatarValid()) + { + llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl; + } + else + { + LLCOFMgr::instance().removeAttachment(attachment_id); + } + return TRUE; + } + // testzone attachpt + LLUUID item_id; + LLNameValue* item_id_nv = viewer_object->getNVPair("AttachItemID"); + if( item_id_nv ) + { + const char* s = item_id_nv->getString(); + if(s) + item_id.set(s); + } + if(!item_id.isNull()) + { + std::map >::iterator iter = mUnsupportedAttachmentPoints.begin(); + std::map >::iterator end = mUnsupportedAttachmentPoints.end(); + for( ; iter != end; ++iter) + { + if((*iter).second.first == item_id) + { + mUnsupportedAttachmentPoints.erase((*iter).first); + // the simulator should automatically handle + // permission revocation + + stopMotionFromSource(viewer_object->getID()); + LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE); + + 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* child_objectp = *iter; + // the simulator should automatically handle + // permissions revocation + + stopMotionFromSource(child_objectp->getID()); + LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE); + } + // Then make sure the inventory is in sync with the avatar. + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + gInventory.notifyObservers(); + } + return TRUE; + } + llwarns << "Not found" << llendl; + } + else + { + llwarns << "No item ID" << llendl; + } + // + return FALSE; +} +BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id) +{ + LLInventoryItem* item = gInventory.getLinkedItem(item_id); + if ( (item) && (gAgentAvatarp) && (!gAgentAvatarp->isWearingAttachment(item->getUUID())) ) + { + LLCOFMgr::instance().removeAttachment(item->getUUID()); + return FALSE; + } +// if (item) +// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1c) | Added: RLVa-1.2.1c + if ( (item) && ((!rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(item))) ) +// [/RLVa:KB] + { + gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); + gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); + + // This object might have been selected, so let the selection manager know it's gone now + LLViewerObject *found_obj = gObjectList.findObject(item_id); + if (found_obj) + { + LLSelectMgr::getInstance()->remove(found_obj); + } + + return TRUE; + } + return FALSE; +} + +U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const +{ + LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i); + return gAgentWearables.getWearableCount(type); +} + +// virtual +void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) +{ + + const LLUUID& src_id = src_vi->getID(); + LLAvatarTexData *data = (LLAvatarTexData *)userdata; + ETextureIndex index = data->mIndex; + if (!isIndexLocalTexture(index)) return; + + LocalTextureData &local_tex_data = mLocalTextureData[index]; + if (success) + { + if(!local_tex_data.mIsBakedReady && + local_tex_data.mImage.notNull() && + (local_tex_data.mImage->getID() == src_id) && + discard_level < local_tex_data.mDiscard) + { + local_tex_data.mDiscard = discard_level; + if ( isUsingBakedTextures() ) + { + requestLayerSetUpdate( index ); + } + else + { + LLVisualParamHint::requestHintUpdates(); + } + updateMeshTextures(); + } + } + else if (final) + { + // Failed: asset is missing + if(!local_tex_data.mIsBakedReady && + local_tex_data.mImage.notNull() && + local_tex_data.mImage->getID() == src_id) + { + local_tex_data.mDiscard = 0; + requestLayerSetUpdate( index ); + updateMeshTextures(); + } + } +} + +// virtual +BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex_pp) const +{ + *tex_pp = NULL; + + if (!isIndexLocalTexture(type)) return FALSE; + if (getLocalTextureID(type) == IMG_DEFAULT_AVATAR) return TRUE; + + localtexture_map_t::const_iterator it = mLocalTextureData.find(type); + if(it == mLocalTextureData.end()) + return FALSE; + *tex_pp = it->second.mImage; + return TRUE; +} +const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type) const +{ + if (!isIndexLocalTexture(type)) return IMG_DEFAULT_AVATAR; + localtexture_map_t::const_iterator it = mLocalTextureData.find(type); + if(it != mLocalTextureData.end() && it->second.mImage.notNull()) + { + return it->second.mImage->getID(); + } + return IMG_DEFAULT_AVATAR; +} + +//----------------------------------------------------------------------------- +// isLocalTextureDataAvailable() +// Returns true if at least the lowest quality discard level exists for every texture +// in the layerset. +//----------------------------------------------------------------------------- +BOOL LLVOAvatarSelf::isLocalTextureDataAvailable( const LLTexLayerSet* layerset ) const +{ + /* if( layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet ) + return getLocalDiscardLevel( TEX_HEAD_BODYPAINT ) >= 0; */ + for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin(); + baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end(); + ++baked_iter) + { + const EBakedTextureIndex baked_index = baked_iter->first; + if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet) + { + BOOL ret = true; + const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second; + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + ret &= (getLocalDiscardLevel(*local_tex_iter) >= 0); + } + return ret; + } + } + llassert(0); + return FALSE; +} + +//----------------------------------------------------------------------------- +// isLocalTextureDataFinal() +// Returns true if the highest quality discard level exists for every texture +// in the layerset. +//----------------------------------------------------------------------------- +BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) const +{ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if (layerset == mBakedTextureDatas[i].mTexLayerSet) + { + const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i); + for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin(); + local_tex_iter != baked_dict->mLocalTextures.end(); + ++local_tex_iter) + { + if (getLocalDiscardLevel(*local_tex_iter) != 0) + { + return FALSE; + } + } + return TRUE; + } + } + + llassert(0); + return FALSE; +} +//----------------------------------------------------------------------------- +// requestLayerSetUploads() +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::requestLayerSetUploads() +{ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + requestLayerSetUpload((EBakedTextureIndex)i); + } +} + +void LLVOAvatarSelf::requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i) +{ + ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex; + const BOOL layer_baked = isTextureDefined(tex_index); + if ( !layer_baked && mBakedTextureDatas[i].mTexLayerSet ) + { + mBakedTextureDatas[i].mTexLayerSet->requestUpload(); + } +} + +bool LLVOAvatarSelf::areTexturesCurrent() const +{ + return !hasPendingBakedUploads() && gAgentWearables.areWearablesLoaded(); +} + +// virtual +bool LLVOAvatarSelf::hasPendingBakedUploads() const +{ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + LLTexLayerSet* layerset = mBakedTextureDatas[i].mTexLayerSet; + if (layerset && layerset->getComposite() && layerset->getComposite()->uploadPending()) + { + return true; + } + } + return false; +} + +void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result ) +{ + if( !layerset || !layerset->getUpdatesEnabled() ) + { + return; + } + + layerset->requestUpdate(); + + if( upload_result ) + { + llassert( isSelf() ); + + ETextureIndex baked_te = getBakedTE( layerset ); + setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR,0)); + layerset->requestUpload(); + updateMeshTextures(); + } +} + +void LLVOAvatarSelf::invalidateAll() +{ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE); + } +} + +//----------------------------------------------------------------------------- +// setCompositeUpdatesEnabled() +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::setCompositeUpdatesEnabled( bool b ) +{ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + setCompositeUpdatesEnabled(i, b); + } +} + +void LLVOAvatarSelf::setCompositeUpdatesEnabled(U32 index, bool b) +{ + if (mBakedTextureDatas[index].mTexLayerSet ) + { + mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled( b ); + } +} + +bool LLVOAvatarSelf::isCompositeUpdateEnabled(U32 index) +{ + if (mBakedTextureDatas[index].mTexLayerSet) + { + return mBakedTextureDatas[index].mTexLayerSet->getUpdatesEnabled(); + } + return false; +} + +void LLVOAvatarSelf::setupComposites() +{ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex; + BOOL layer_baked = isTextureDefined(tex_index); + if (mBakedTextureDatas[i].mTexLayerSet) + { + mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( !layer_baked ); + } + } +} + +void LLVOAvatarSelf::updateComposites() +{ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if ( mBakedTextureDatas[i].mTexLayerSet + && ((i != BAKED_SKIRT) || isWearingWearableType( LLWearableType::WT_SKIRT )) ) + { + mBakedTextureDatas[i].mTexLayerSet->updateComposite(); + } + } +} + +// virtual +S32 LLVOAvatarSelf::getLocalDiscardLevel( ETextureIndex type ) const +{ + // If the texture is not local, we don't care and treat it as fully loaded + if (!isIndexLocalTexture(type)) return FALSE; + + localtexture_map_t::const_iterator it = mLocalTextureData.find(type); + if (type >= 0 + && it != mLocalTextureData.end() + && getLocalTextureID(type) != IMG_DEFAULT_AVATAR + && !it->second.mImage->isMissingAsset()) + { + return it->second.mImage->getDiscardLevel(); + } + else + { + // We don't care about this (no image associated with the layer) treat as fully loaded. + return 0; + } +} +// Counts the memory footprint of local textures. +void LLVOAvatarSelf::getLocalTextureByteCount( S32* gl_bytes ) const +{ + *gl_bytes = 0; + for( S32 type = 0; type < TEX_NUM_INDICES; type++ ) + { + if (!isIndexLocalTexture((ETextureIndex)type)) continue; + localtexture_map_t::const_iterator it = mLocalTextureData.find((ETextureIndex)type); + if(it == mLocalTextureData.end())continue; + LLViewerTexture* image_gl = it->second.mImage; + if( image_gl ) + { + S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); + + if( image_gl->hasGLTexture() ) + { + *gl_bytes += bytes; + } + } + } +} +// virtual +void LLVOAvatarSelf::setLocalTexture( ETextureIndex type, LLViewerTexture* src_tex, BOOL baked_version_ready ) +{ + if (!isIndexLocalTexture(type)) return; + + LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(src_tex, TRUE) ; + if(!tex) + { + return ; + } + + S32 desired_discard = isSelf() ? 0 : 2; + LocalTextureData &local_tex_data = mLocalTextureData[type]; + if (!baked_version_ready) + { + if (tex != local_tex_data.mImage || local_tex_data.mIsBakedReady) + { + local_tex_data.mDiscard = MAX_DISCARD_LEVEL+1; + } + if (tex->getID() != IMG_DEFAULT_AVATAR) + { + if (local_tex_data.mDiscard > desired_discard) + { + S32 tex_discard = tex->getDiscardLevel(); + if (tex_discard >= 0 && tex_discard <= desired_discard) + { + local_tex_data.mDiscard = tex_discard; + if (gAgentAvatarp->isUsingBakedTextures()) + { + requestLayerSetUpdate( type ); + } + else + { + LLVisualParamHint::requestHintUpdates(); + } + } + else + { + tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(),type), NULL ); + } + } + tex->setMinDiscardLevel(desired_discard); + } + } + local_tex_data.mIsBakedReady = baked_version_ready; + local_tex_data.mImage = tex; +} + +//virtual +void LLVOAvatarSelf::dumpLocalTextures() const +{ + llinfos << "Local Textures:" << llendl; + + /* ETextureIndex baked_equiv[] = { + TEX_UPPER_BAKED, + if (isTextureDefined(baked_equiv[i])) */ + for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); + iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + iter++) + { + const LLVOAvatarDictionary::TextureEntry *text_dict = iter->second; + if (!text_dict->mIsLocalTexture || !text_dict->mIsUsedByBakedTexture) + continue; + + const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex; + const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex; + + const std::string &name = text_dict->mName; + localtexture_map_t::const_iterator it = mLocalTextureData.find(iter->first); + if (isTextureDefined(baked_equiv)) + { +#if LL_RELEASE_FOR_DOWNLOAD + // End users don't get to trivially see avatar texture IDs, makes textures + // easier to steal. JC + llinfos << "LocTex " << name << ": Baked " << llendl; +#else + llinfos << "LocTex " << name << ": Baked " << getTEImage( baked_equiv )->getID() << llendl; +#endif + } + else if (it != mLocalTextureData.end() && it->second.mImage.notNull()) + { + if( it->second.mImage->getID() == IMG_DEFAULT_AVATAR ) + { + llinfos << "LocTex " << name << ": None" << llendl; + } + else + { + const LLViewerFetchedTexture* image = it->second.mImage; + + llinfos << "LocTex " << name << ": " + << "Discard " << image->getDiscardLevel() << ", " + << "(" << image->getWidth() << ", " << image->getHeight() << ") " +#if !LL_RELEASE_FOR_DOWNLOAD + // End users don't get to trivially see avatar texture IDs, + // makes textures easier to steal + << image->getID() << " " +#endif + << "Priority: " << image->getDecodePriority() + << llendl; + } + } + else + { + llinfos << "LocTex " << name << ": No LLViewerTexture" << llendl; + } + } +} + +//----------------------------------------------------------------------------- +// static +// onLocalTextureLoaded() +//----------------------------------------------------------------------------- + +void LLVOAvatarSelf::onLocalTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) +{ + LLAvatarTexData *data = (LLAvatarTexData *)userdata; + LLVOAvatarSelf *self = (LLVOAvatarSelf *)gObjectList.findAvatar(data->mAvatarID); + if (self) + { + // We should only be handling local textures for ourself + self->localTextureLoaded(success, src_vi, src_raw, aux_src, discard_level, final, userdata); + } + // ensure data is cleaned up + if (final || !success) + { + delete data; + } +} + +// static +void LLVOAvatarSelf::dumpTotalLocalTextureByteCount() +{ + S32 gl_bytes = 0; + gAgentAvatarp->getLocalTextureByteCount(&gl_bytes); + llinfos << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << llendl; +} + +BOOL LLVOAvatarSelf::getIsCloud() +{ + // do we have a shape? + if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 || + gAgentWearables.getWearableCount(LLWearableType::WT_HAIR) == 0 || + gAgentWearables.getWearableCount(LLWearableType::WT_EYES) == 0 || + gAgentWearables.getWearableCount(LLWearableType::WT_SKIN) == 0) + { + return TRUE; + } + + if (!isTextureDefined(TEX_HAIR)) + { + return TRUE; + } + + if (!mPreviousFullyLoaded) + { + if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) && + (!isTextureDefined(TEX_LOWER_BAKED))) + { + return TRUE; + } + + if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) && + (!isTextureDefined(TEX_UPPER_BAKED))) + { + return TRUE; + } + } + return FALSE; +} + +const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const +{ + if (canGrabBakedTexture(baked_index)) + { + ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index); + if (tex_index == TEX_NUM_INDICES) + { + return LLUUID::null; + } + return getTEImage( tex_index )->getID(); + } + return LLUUID::null; +} + +BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const +{ + ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index); + if (tex_index == TEX_NUM_INDICES) + { + return FALSE; + } + // Check if the texture hasn't been baked yet. + if (!isTextureDefined(tex_index)) + { + lldebugs << "getTEImage( " << (U32) tex_index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl; + return FALSE; + } + + if (gAgent.isGodlikeWithoutAdminMenuFakery()) + return TRUE; + + // Check permissions of textures that show up in the + // baked texture. We don't want people copying people's + // work via baked textures. + + + const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index); + for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin(); + iter != baked_dict->mLocalTextures.end(); + ++iter) + { + const ETextureIndex t_index = (*iter); + lldebugs << "Checking index " << (U32) t_index << llendl; + const LLUUID& texture_id = getTEImage( t_index )->getID(); + if (texture_id != IMG_DEFAULT_AVATAR) + { + // Search inventory for this texture. + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(texture_id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + BOOL can_grab = FALSE; + lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl; + if (items.count()) + { + // search for full permissions version + for (S32 i = 0; i < items.count(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp->getIsFullPerm()) + { + can_grab = TRUE; + break; + } + } + } + if (!can_grab) return FALSE; + } + } + + return TRUE; +} +void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep, + F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked ) +{ + if (!isIndexLocalTexture(type)) return; + + if (!covered_by_baked) // render_avatar is always true if isSelf() + { + if (getLocalTextureID(type) != IMG_DEFAULT_AVATAR && imagep->getDiscardLevel() != 0) + { + F32 desired_pixels; + desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); + imagep->setBoostLevel(getAvatarBoostLevel()); + // SNOW-8 : temporary snowglobe1.0 fix for baked textures + if (!gGLManager.mIsDisabled ) + { + // bind the texture so that its boost level won't be slammed + gGL.getTexUnit(0)->bind(imagep); + } + imagep->addTextureStats( desired_pixels / texel_area_ratio ); + if (imagep->getDiscardLevel() < 0) + { + mHasGrey = TRUE; // for statistics gathering + } + } + else + { + // texture asset is missing + mHasGrey = TRUE; // for statistics gathering + } + } +} + +//----------------------------------------------------------------------------- +// getBakedTE() +// Used by the LayerSet. (Layer sets don't in general know what textures depend on them.) +//----------------------------------------------------------------------------- +ETextureIndex LLVOAvatarSelf::getBakedTE(const LLTexLayerSet* layerset ) const +{ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if (layerset == mBakedTextureDatas[i].mTexLayerSet ) + { + return mBakedTextureDatas[i].mTextureIndex; + } + } + llassert(0); + return TEX_HEAD_BAKED; +} + + +void LLVOAvatarSelf::setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid) +{ + ETextureIndex index = LLVOAvatarDictionary::bakedToLocalTextureIndex(i); + setNewBakedTexture(index, uuid); +} + +//----------------------------------------------------------------------------- +// setNewBakedTexture() +// A new baked texture has been successfully uploaded and we can start using it now. +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) +{ + // Baked textures live on other sims. + LLHost target_host = getObjectHost(); + setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) ); + if (uuid != IMG_INVISIBLE) + { + // Do not update textures when setting a new invisible baked texture as + // it would result in destroying the calling object (setNewBakedTexture() + // is called by LLTexLayerSetBuffer::render()) ! + updateMeshTextures(); + } + dirtyMesh(); + + + LLVOAvatar::cullAvatarsByPixelArea(); + + /* switch(te) + case TEX_HEAD_BAKED: + llinfos << "New baked texture: HEAD" << llendl; */ + const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(te); + if (texture_dict->mIsBakedTexture) + { + llinfos << "New baked texture: " << texture_dict->mName << " UUID: " << uuid <mBakedTextureIndex].mTexLayerSet->requestUpdate(); + } + else + { + llwarns << "New baked texture: unknown te " << te << llendl; + } + + // dumpAvatarTEs( "setNewBakedTexture() send" ); + // RN: throttle uploads + if (!hasPendingBakedUploads()) + { + gAgent.sendAgentSetAppearance(); + } +} +//----------------------------------------------------------------------------- +// setCachedBakedTexture() +// A baked texture id was received from a cache query, make it active +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid ) +{ + setTETexture( te, uuid ); + + /* switch(te) + case TEX_HEAD_BAKED: + if( mHeadLayerSet ) + mHeadLayerSet->cancelUpload(); */ + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet) + { + mBakedTextureDatas[i].mTexLayerSet->cancelUpload(); + } + } +} +// static +void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**) +{ + LLUUID texture_id; + msg->getUUID("TextureData", "TextureID", texture_id); + if (!isAgentAvatarValid()) return; + + // If this is a texture corresponding to one of our baked entries, + // just rebake that layer set. + BOOL found = FALSE; + + /* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] = + TEX_HEAD_BAKED, + TEX_UPPER_BAKED, */ + for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); + iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + ++iter) + { + const ETextureIndex index = iter->first; + const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + if (texture_dict->mIsBakedTexture) + { + if (texture_id == gAgentAvatarp->getTEImage(index)->getID()) + { + LLTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index); + if (layer_set) + { + llinfos << "TAT: rebake - matched entry " << (S32)index << llendl; + gAgentAvatarp->invalidateComposite(layer_set, TRUE); + found = TRUE; + LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); + } + } + } + } + + // If texture not found, rebake all entries. + if (!found) + { + gAgentAvatarp->forceBakeAllTextures(); + } + else + { + // Not sure if this is necessary, but forceBakeAllTextures() does it. + gAgentAvatarp->updateMeshTextures(); + } +} +BOOL LLVOAvatarSelf::isUsingBakedTextures() const +{ + // Composite textures are used during appearance mode. + if (gAgentCamera.cameraCustomizeAvatar()) + return FALSE; + + return TRUE; +} + + +void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) +{ + llinfos << "TAT: forced full rebake. " << llendl; + + for (U32 i = 0; i < mBakedTextureDatas.size(); i++) + { + ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex; + LLTexLayerSet* layer_set = getLayerSet(baked_index); + if (layer_set) + { + if (slam_for_debug) + { + layer_set->setUpdatesEnabled(TRUE); + layer_set->cancelUpload(); + } + + invalidateComposite(layer_set, TRUE); + LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); + } + else + { + llwarns << "TAT: NO LAYER SET FOR " << (S32)baked_index << llendl; + } + } + + // Don't know if this is needed + updateMeshTextures(); +} + +//----------------------------------------------------------------------------- +// requestLayerSetUpdate() +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index ) +{ + /* switch(index) + case LOCTEX_UPPER_BODYPAINT: + case LOCTEX_UPPER_SHIRT: + if( mUpperBodyLayerSet ) + mUpperBodyLayerSet->requestUpdate(); */ + const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); + if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture) + return; + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + if (mBakedTextureDatas[baked_index].mTexLayerSet) + { + mBakedTextureDatas[baked_index].mTexLayerSet->requestUpdate(); + } +} + +LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const +{ + /* switch(index) + case TEX_HEAD_BAKED: + case TEX_HEAD_BODYPAINT: + return mHeadLayerSet; */ + const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index); + if (texture_dict->mIsUsedByBakedTexture) + { + const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex; + return mBakedTextureDatas[baked_index].mTexLayerSet; + } + return NULL; +} + +//----------------------------------------------------------------------------- +// static +// onCustomizeStart() +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::onCustomizeStart() +{ + // We're no longer doing any baking or invalidating on entering + // appearance editing mode. Leaving function in place in case + // further changes require us to do something at this point - Nyx +} + +//----------------------------------------------------------------------------- +// static +// onCustomizeEnd() +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::onCustomizeEnd() +{ + if (isAgentAvatarValid()) + { + gAgentAvatarp->invalidateAll(); + gAgentAvatarp->requestLayerSetUploads(); + } +} //------------------------------------------------------------------------ // needsRenderBeam() //------------------------------------------------------------------------ @@ -661,6 +1884,7 @@ BOOL LLVOAvatarSelf::needsRenderBeam() { return FALSE; } + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); BOOL is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing()); @@ -671,4 +1895,196 @@ BOOL LLVOAvatarSelf::needsRenderBeam() is_touching_or_grabbing = FALSE; } return is_touching_or_grabbing || (mState & AGENT_STATE_EDITING && LLSelectMgr::getInstance()->shouldShowSelection()); +} + +// static +void LLVOAvatarSelf::deleteScratchTextures() +{ +if(gAuditTexture) + { + S32 total_tex_size = sScratchTexBytes ; + S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; + + if( sScratchTexNames.checkData( GL_LUMINANCE ) ) + { + LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + total_tex_size -= tex_size ; + } + if( sScratchTexNames.checkData( GL_ALPHA ) ) + { + LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + total_tex_size -= tex_size ; + } + if( sScratchTexNames.checkData( GL_COLOR_INDEX ) ) + { + LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + total_tex_size -= tex_size ; + } + if( sScratchTexNames.checkData( GL_LUMINANCE_ALPHA ) ) + { + LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + total_tex_size -= 2 * tex_size ; + } + if( sScratchTexNames.checkData( GL_RGB ) ) + { + LLImageGL::decTextureCounter(tex_size, 3, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + total_tex_size -= 3 * tex_size ; + } + if( sScratchTexNames.checkData( GL_RGBA ) ) + { + LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + total_tex_size -= 4 * tex_size ; + } + //others + while(total_tex_size > 0) + { + LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + total_tex_size -= 4 * tex_size ; + } + } + + for( LLGLuint* namep = sScratchTexNames.getFirstData(); + namep; + namep = sScratchTexNames.getNextData() ) + { + LLImageGL::deleteTextures(1, (U32 *)namep ); + stop_glerror(); + } + + if( sScratchTexBytes ) + { + lldebugs << "Clearing Scratch Textures " << (sScratchTexBytes/1024) << "KB" << llendl; + + sScratchTexNames.deleteAllData(); + sScratchTexLastBindTime.deleteAllData(); + LLImageGL::sGlobalTextureMemoryInBytes -= sScratchTexBytes; + sScratchTexBytes = 0; + } +} + +BOOL LLVOAvatarSelf::bindScratchTexture( LLGLenum format ) +{ + U32 texture_bytes = 0; + S32 components = 0; + GLuint gl_name = getScratchTexName( format, components, &texture_bytes ); + if( gl_name ) + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name); + stop_glerror(); + + F32* last_bind_time = sScratchTexLastBindTime.getIfThere( format ); + if( last_bind_time ) + { + if( *last_bind_time != LLImageGL::sLastFrameTime ) + { + *last_bind_time = LLImageGL::sLastFrameTime; + LLImageGL::updateBoundTexMem(texture_bytes, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + } + } + else + { + LLImageGL::updateBoundTexMem(texture_bytes, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) ); + } + return TRUE; + } + return FALSE; +} + +LLGLuint LLVOAvatarSelf::getScratchTexName( LLGLenum format, S32& components, U32* texture_bytes ) +{ + GLenum internal_format; + switch( format ) + { + case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break; + case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break; + case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break; + case GL_RGB: components = 3; internal_format = GL_RGB8; break; + case GL_RGBA: components = 4; internal_format = GL_RGBA8; break; + default: llassert(0); components = 4; internal_format = GL_RGBA8; break; + } + + *texture_bytes = components * SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT; + + if( sScratchTexNames.checkData( format ) ) + { + return *( sScratchTexNames.getData( format ) ); + } + + LLGLSUIDefault gls_ui; + + U32 name = 0; + LLImageGL::generateTextures(1, &name ); + stop_glerror(); + + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name); + stop_glerror(); + + LLImageGL::setManualImage( + GL_TEXTURE_2D, 0, internal_format, + SCRATCH_TEX_WIDTH, SCRATCH_TEX_HEIGHT, + format, GL_UNSIGNED_BYTE, NULL ); + stop_glerror(); + + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + stop_glerror(); + + sScratchTexNames.addData( format, new LLGLuint( name ) ); + + sScratchTexBytes += *texture_bytes; + LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes; + + if(gAuditTexture) + { + LLImageGL::incTextureCounter(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ; + } + return name; +} + +// static +void LLVOAvatarSelf::dumpScratchTextureByteCount() +{ + llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl; +} + +//static +void LLVOAvatarSelf::onChangeSelfInvisible(BOOL newvalue) +{ + if (isAgentAvatarValid()) + { + if (newvalue) + { + // we have just requested to set the avatar's baked textures to invisible + gAgentAvatarp->setInvisible(TRUE); + } + else + { + gAgentAvatarp->setInvisible(FALSE); + } + } +} + + +void LLVOAvatarSelf::setInvisible(BOOL newvalue) +{ + if (newvalue) + { + setCompositeUpdatesEnabled(FALSE); + for (U32 i = 0; i < mBakedTextureDatas.size(); i++ ) + { + setNewBakedTexture(mBakedTextureDatas[i].mTextureIndex, IMG_INVISIBLE); + } + gAgent.sendAgentSetAppearance(); + } + else + { + setCompositeUpdatesEnabled(TRUE); + invalidateAll(); + requestLayerSetUploads(); + gAgent.sendAgentSetAppearance(); + } } \ No newline at end of file diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 24ee48517..fb0003553 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -83,6 +83,7 @@ public: void resetJointPositions( void ); + /*virtual*/ void updateVisualParams(); /** Initialization @@ -104,6 +105,11 @@ public: /*virtual*/ BOOL updateCharacter(LLAgent &agent); /*virtual*/ void idleUpdateTractorBeam(); + //-------------------------------------------------------------------- + // Loading state + //-------------------------------------------------------------------- +public: + /*virtual*/ BOOL getIsCloud(); private: @@ -129,12 +135,102 @@ private: LLPointer mBeam; LLFrameTimer mBeamTimer; + //-------------------------------------------------------------------- + // LLVOAvatar Constants + //-------------------------------------------------------------------- +public: + /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; } + /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; } + /*virtual*/ S32 getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; } /** Rendering ** ** *******************************************************************************/ + +/******************************************************************************** + ** ** + ** TEXTURES + **/ + + //-------------------------------------------------------------------- + // Loading status + //-------------------------------------------------------------------- +public: + /*virtual*/ bool hasPendingBakedUploads() const; + S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type) const; + bool areTexturesCurrent() const; + BOOL isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const; + BOOL isLocalTextureDataFinal(const LLTexLayerSet* layerset) const; + //-------------------------------------------------------------------- + // Local Textures + //-------------------------------------------------------------------- +public: + BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp) const; + const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type) const; + void setLocalTextureTE( U8 te, LLViewerTexture* image, BOOL set_by_user ); + void setLocalTexture( LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits ); +protected: + void localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + void getLocalTextureByteCount(S32* gl_byte_count) const; + /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked); +private: + static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); + //-------------------------------------------------------------------- + // Baked textures + //-------------------------------------------------------------------- +public: + LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const; + void setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid); + void setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid); + void setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid); + void forceBakeAllTextures(bool slam_for_debug = false); + static void processRebakeAvatarTextures(LLMessageSystem* msg, void**); + BOOL isUsingBakedTextures() const; // e.g. false if in appearance edit mode protected: /*virtual*/ void removeMissingBakedTextures(); + + //-------------------------------------------------------------------- + // Layers + //-------------------------------------------------------------------- +public: + void requestLayerSetUploads(); + void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i); + void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i); + LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const; + + //-------------------------------------------------------------------- + // Composites + //-------------------------------------------------------------------- +public: + /* virtual */ void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result); + /* virtual */ void invalidateAll(); + /* virtual */ void setCompositeUpdatesEnabled(bool b); // only works for self + /* virtual */ void setCompositeUpdatesEnabled(U32 index, bool b); + /* virtual */ bool isCompositeUpdateEnabled(U32 index); + void setupComposites(); + void updateComposites(); + + const LLUUID& grabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; + BOOL canGrabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const; + + + //-------------------------------------------------------------------- + // Scratch textures (used for compositing) + //-------------------------------------------------------------------- +public: + BOOL bindScratchTexture(LLGLenum format); + static void deleteScratchTextures(); +protected: + LLGLuint getScratchTexName(LLGLenum format, S32& components, U32* texture_bytes); +private: + static S32 sScratchTexBytes; + static LLMap< LLGLenum, LLGLuint*> sScratchTexNames; + static LLMap< LLGLenum, F32*> sScratchTexLastBindTime; + +/** Textures + ** ** + *******************************************************************************/ + /******************************************************************************** ** ** ** MESHES @@ -146,15 +242,74 @@ protected: ** ** *******************************************************************************/ +/******************************************************************************** + ** ** + ** WEARABLES + **/ + +public: + /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type) const; + void wearableUpdated(LLWearableType::EType type, BOOL upload_result); +protected: + U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const; + //-------------------------------------------------------------------- - // HUDs + // Attachments //-------------------------------------------------------------------- +public: + void updateAttachmentVisibility(U32 camera_mode); + BOOL isWearingAttachment(const LLUUID& inv_item_id) const; + LLViewerObject* getWornAttachment(const LLUUID& inv_item_id); + const std::string getAttachedPointName(const LLUUID& inv_item_id) const; + /*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object); + /*virtual*/ BOOL detachObject(LLViewerObject *viewer_object); + static BOOL detachAttachmentIntoInventory(const LLUUID& item_id); + // testzone attachpt + BOOL isWearingUnsupportedAttachment( const LLUUID& inv_item_id ); + std::map > mUnsupportedAttachmentPoints; +// [RLVa:KB] - Checked: 2010-03-14 (RLVa-1.2.0a) | Added: RLVa-1.1.0i + LLViewerJointAttachment* getWornAttachmentPoint(const LLUUID& inv_item_id) const; +// [/RLVa:KB] private: + LLViewerJoint* mScreenp; // special purpose joint for HUD attachments /** Attachments ** ** *******************************************************************************/ + +/******************************************************************************** + ** ** + ** APPEARANCE + **/ + +public: + static void onCustomizeStart(); + static void onCustomizeEnd(); + + +/** Appearance + ** ** + *******************************************************************************/ + // General + //-------------------------------------------------------------------- +public: + static void dumpTotalLocalTextureByteCount(); + void dumpLocalTextures() const; + static void dumpScratchTextureByteCount(); +public: + struct LLAvatarTexData + { + LLAvatarTexData(const LLUUID& id, LLVOAvatarDefines::ETextureIndex index) : + mAvatarID(id), + mIndex(index) + {} + LLUUID mAvatarID; + LLVOAvatarDefines::ETextureIndex mIndex; + }; +//Spechul schtuff. + static void onChangeSelfInvisible(BOOL newvalue); + void setInvisible(BOOL newvalue); }; extern LLVOAvatarSelf *gAgentAvatarp; diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 1c18245b1..5b943d06c 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -650,7 +650,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) { const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te ) ); LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id ); - gAgentAvatarp->setLocTexTE( te, image, set_by_user ); + gAgentAvatarp->setLocalTextureTE( te, image, set_by_user ); } } @@ -720,7 +720,7 @@ void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake { if( LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te ) == type ) { - gAgentAvatarp->setLocTexTE( te, image, upload_bake ); + gAgentAvatarp->setLocalTextureTE( te, image, upload_bake ); } } diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index aa61e3640..e079acc9f 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1502,7 +1502,7 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const const LLViewerObject* pAttachObj = gObjectList.findObject(rlvCmd.getObjectID()); if ( (pAttachObj) && (pAttachObj->isAttachment()) ) { - LLVOAvatar::detachAttachmentIntoInventory(pAttachObj->getAttachmentItemID()); + LLVOAvatarSelf::detachAttachmentIntoInventory(pAttachObj->getAttachmentItemID()); } } break; diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 6f5a00e11..0e9b8381b 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -355,8 +355,7 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); return; } - LLVOAvatar* pAvatar = gAgentAvatarp; - if (!pAvatar) + if (!isAgentAvatarValid()) return; // Grab a list of all the items we'll be wearing/attaching @@ -439,7 +438,7 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc } else { - const LLViewerObject* pAttachObj = pAvatar->getWornAttachment(pItem->getUUID()); + const LLViewerObject* pAttachObj = gAgentAvatarp->getWornAttachment(pItem->getUUID()); if ( (pAttachObj) && (isForceDetachable(pAttachObj, false)) ) remAttachment(pAttachObj); } diff --git a/indra/newview/rlvinventory.cpp b/indra/newview/rlvinventory.cpp index 54fb89f76..debf93f51 100644 --- a/indra/newview/rlvinventory.cpp +++ b/indra/newview/rlvinventory.cpp @@ -364,9 +364,14 @@ void RlvRenameOnWearObserver::done() // Checked: 2010-03-14 (RLVa-1.1.3a) | Added: RLVa-1.2.0a void RlvRenameOnWearObserver::doneIdle() { - const LLViewerInventoryCategory* pRlvRoot = NULL; LLVOAvatar* pAvatar = gAgentAvatarp; + const LLViewerInventoryCategory* pRlvRoot = NULL; + if(!isAgentAvatarValid()) + { + delete this; + return; + } if ( (RlvSettings::getEnableSharedWear()) || (!RlvSettings::getSharedInvAutoRename()) || (LLStartUp::getStartupState() < STATE_STARTED) || - (!pAvatar) || ((pRlvRoot = RlvInventory::instance().getSharedRoot()) == NULL) ) + ((pRlvRoot = RlvInventory::instance().getSharedRoot()) == NULL) ) { delete this; return; @@ -387,7 +392,7 @@ void RlvRenameOnWearObserver::doneIdle() if (items.empty()) continue; - if ( ((pAttachPt = pAvatar->getWornAttachmentPoint(idAttachItem)) == NULL) || + if ( ((pAttachPt = gAgentAvatarp->getWornAttachmentPoint(idAttachItem)) == NULL) || ((idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(pAttachPt)) == 0) ) { // RLV_ASSERT(false); From 4d68dc7c575fb74021f3872eb71a08e93eb6a019 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 25 Oct 2011 16:50:39 -0500 Subject: [PATCH 2/7] LLTexLayer refactored. Tried to keep behavior changes as minimal as possible. Consider as base slate for changes required for multi-wearables. --- indra/newview/CMakeLists.txt | 4 + indra/newview/llassetuploadresponders.h | 2 +- indra/newview/lltexglobalcolor.cpp | 145 ++ indra/newview/lltexglobalcolor.h | 83 + indra/newview/lltexlayer.cpp | 1936 ++++++++--------------- indra/newview/lltexlayer.h | 686 +++----- indra/newview/lltexlayerparams.cpp | 20 +- indra/newview/lltexlayerparams.h | 187 +++ indra/newview/llviewerstats.cpp | 3 +- indra/newview/llviewervisualparam.cpp | 8 +- indra/newview/llviewervisualparam.h | 2 +- indra/newview/llvoavatar.cpp | 2 +- indra/newview/llvoavatar.h | 1 + 13 files changed, 1324 insertions(+), 1755 deletions(-) create mode 100644 indra/newview/lltexglobalcolor.cpp create mode 100644 indra/newview/lltexglobalcolor.h create mode 100644 indra/newview/lltexlayerparams.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ce601470f..b9816f240 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -386,7 +386,9 @@ set(viewer_SOURCE_FILES llstylemap.cpp llsurface.cpp llsurfacepatch.cpp + lltexglobalcolor.cpp lltexlayer.cpp + lltexlayerparams.cpp lltexturecache.cpp lltexturectrl.cpp lltexturefetch.cpp @@ -873,7 +875,9 @@ set(viewer_HEADER_FILES llsurface.h llsurfacepatch.h lltable.h + lltexglobalcolor.h lltexlayer.h + lltexlayerparams.h lltexturecache.h lltexturectrl.h lltexturefetch.h diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index c08f2999f..17d8f1a13 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -71,7 +71,7 @@ public: virtual void uploadComplete(const LLSD& content); }; -class LLBakedUploadData; +struct LLBakedUploadData; class LLSendTexLayerResponder : public LLAssetUploadResponder { public: diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/newview/lltexglobalcolor.cpp new file mode 100644 index 000000000..5704aa6ec --- /dev/null +++ b/indra/newview/lltexglobalcolor.cpp @@ -0,0 +1,145 @@ +/** + * @file lltexlayerglobalcolor.cpp + * @brief Color for texture layers. + * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llagent.h" +#include "lltexlayer.h" +#include "llvoavatar.h" +#include "llwearable.h" +#include "lltexglobalcolor.h" + +//----------------------------------------------------------------------------- +// LLTexGlobalColor +//----------------------------------------------------------------------------- + +LLTexGlobalColor::LLTexGlobalColor(LLVOAvatar* avatar) + : + mAvatar(avatar), + mInfo(NULL) +{ +} + +LLTexGlobalColor::~LLTexGlobalColor() +{ + // mParamColorList are LLViewerVisualParam's and get deleted with ~LLCharacter() + //std::for_each(mParamColorList.begin(), mParamColorList.end(), DeletePointer()); +} + +BOOL LLTexGlobalColor::setInfo(LLTexGlobalColorInfo *info) +{ + llassert(mInfo == NULL); + mInfo = info; + //mID = info->mID; // No ID + + mParamGlobalColorList.reserve(mInfo->mParamColorInfoList.size()); + for (param_color_info_list_t::iterator iter = mInfo->mParamColorInfoList.begin(); + iter != mInfo->mParamColorInfoList.end(); + iter++) + { + LLTexParamGlobalColor* param_color = new LLTexParamGlobalColor(this); + if (!param_color->setInfo(*iter, TRUE)) + { + mInfo = NULL; + return FALSE; + } + mParamGlobalColorList.push_back(param_color); + } + + return TRUE; +} + +LLColor4 LLTexGlobalColor::getColor() const +{ + // Sum of color params + if (mParamGlobalColorList.empty()) + return LLColor4(1.f, 1.f, 1.f, 1.f); + + LLColor4 net_color(0.f, 0.f, 0.f, 0.f); + LLTexLayer::calculateTexLayerColor(mParamGlobalColorList, net_color); + return net_color; +} + +const std::string& LLTexGlobalColor::getName() const +{ + return mInfo->mName; +} + +//----------------------------------------------------------------------------- +// LLTexParamGlobalColor +//----------------------------------------------------------------------------- +LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) : + LLTexLayerParamColor(tex_global_color->getAvatar()), + mTexGlobalColor(tex_global_color) +{ +} + +void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake) +{ + mAvatar->onGlobalColorChanged(mTexGlobalColor, upload_bake); +} + +//----------------------------------------------------------------------------- +// LLTexGlobalColorInfo +//----------------------------------------------------------------------------- + +LLTexGlobalColorInfo::LLTexGlobalColorInfo() +{ +} + + +LLTexGlobalColorInfo::~LLTexGlobalColorInfo() +{ + for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer()); +} + +BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node) +{ + // name attribute + static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); + if (!node->getFastAttributeString(name_string, mName)) + { + llwarns << " element is missing name attribute." << llendl; + return FALSE; + } + // sub-element + for (LLXmlTreeNode* child = node->getChildByName("param"); + child; + child = node->getNextNamedChild()) + { + if (child->getChildByName("param_color")) + { + // + LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo(); + if (!info->parseXml(child)) + { + delete info; + return FALSE; + } + mParamColorInfoList.push_back(info); + } + } + return TRUE; +} diff --git a/indra/newview/lltexglobalcolor.h b/indra/newview/lltexglobalcolor.h new file mode 100644 index 000000000..c01187a89 --- /dev/null +++ b/indra/newview/lltexglobalcolor.h @@ -0,0 +1,83 @@ +/** + * @file lltexglobalcolor.h + * @brief This is global texture color info used by llvoavatar. + * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLTEXGLOBALCOLOR_H +#define LL_LLTEXGLOBALCOLOR_H + +#include "lltexlayer.h" +#include "lltexlayerparams.h" + +class LLVOAvatar; +class LLWearable; +class LLTexGlobalColorInfo; + +class LLTexGlobalColor +{ +public: + LLTexGlobalColor( LLVOAvatar* avatar ); + ~LLTexGlobalColor(); + + LLTexGlobalColorInfo* getInfo() const { return mInfo; } + // This sets mInfo and calls initialization functions + BOOL setInfo(LLTexGlobalColorInfo *info); + + LLVOAvatar* getAvatar() const { return mAvatar; } + LLColor4 getColor() const; + const std::string& getName() const; + +private: + param_color_list_t mParamGlobalColorList; + LLVOAvatar* mAvatar; // just backlink, don't LLPointer + LLTexGlobalColorInfo *mInfo; +}; + +// Used by llvoavatar to determine skin/eye/hair color. +class LLTexGlobalColorInfo +{ + friend class LLTexGlobalColor; +public: + LLTexGlobalColorInfo(); + ~LLTexGlobalColorInfo(); + + BOOL parseXml(LLXmlTreeNode* node); + +private: + param_color_info_list_t mParamColorInfoList; + std::string mName; +}; + +class LLTexParamGlobalColor : public LLTexLayerParamColor +{ +public: + LLTexParamGlobalColor(LLTexGlobalColor *tex_color); + /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const; +protected: + /*virtual*/ void onGlobalColorChanged(bool upload_bake); +private: + LLTexGlobalColor* mTexGlobalColor; +}; + +#endif diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 0dd7614ba..0dfda5110 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -32,6 +32,8 @@ #include "llviewerprecompiledheaders.h" +#include "lltexlayer.h" + #include "imageids.h" #include "llagent.h" #include "llagentcamera.h" @@ -44,7 +46,6 @@ #include "llimagetga.h" #include "llpolymorph.h" #include "llquantize.h" -#include "lltexlayer.h" #include "llui.h" #include "llvfile.h" #include "llviewertexturelist.h" @@ -58,6 +59,7 @@ #include "v4coloru.h" #include "llrender.h" #include "llassetuploadresponders.h" +#include "lltexlayerparams.h" //#include "../tools/imdebug/imdebug.h" @@ -65,46 +67,73 @@ using namespace LLVOAvatarDefines; const S32 MAX_BAKE_UPLOAD_ATTEMPTS = 4; -// static -S32 LLTexLayerSetBuffer::sGLByteCount = 0; +class LLTexLayerInfo +{ + friend class LLTexLayer; + friend class LLTexLayerInterface; +public: + LLTexLayerInfo(); + ~LLTexLayerInfo(); + + BOOL parseXml(LLXmlTreeNode* node); + BOOL isUserSettable() { return mLocalTexture != -1; } + S32 getLocalTexture() const { return mLocalTexture; } + BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; } + std::string getName() const { return mName; } + +private: + std::string mName; + + BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer, + LLTexLayerInterface::ERenderPass mRenderPass; + + std::string mGlobalColor; + LLColor4 mFixedColor; + + S32 mLocalTexture; + std::string mStaticImageFileName; + BOOL mStaticImageIsMask; + BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask + BOOL mIsVisibilityMask; + + typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t; + morph_name_list_t mMorphNameList; + param_color_info_list_t mParamColorInfoList; + param_alpha_info_list_t mParamAlphaInfoList; +}; //----------------------------------------------------------------------------- // LLBakedUploadData() //----------------------------------------------------------------------------- -LLBakedUploadData::LLBakedUploadData( LLVOAvatarSelf* avatar, - LLTexLayerSet* layerset, - LLTexLayerSetBuffer* layerset_buffer, +LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar, + LLTexLayerSet* layerset, const LLUUID & id ) : - mAvatar( avatar ), - mTexLayerSet( layerset ), - mLayerSetBuffer( layerset_buffer ), - mID(id) -{ - mStartTime = LLFrameTimer::getTotalTime(); // Record starting time - for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ ) - { - LLWearable* wearable = gAgentWearables.getWearable( (LLWearableType::EType)i); - if( wearable ) - { - mWearableAssets[i] = wearable->getAssetID(); - } - } + mAvatar(avatar), + mTexLayerSet(layerset), + mID(id), + mStartTime(LLFrameTimer::getTotalTime()) // Record starting time +{ } //----------------------------------------------------------------------------- // LLTexLayerSetBuffer + // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. //----------------------------------------------------------------------------- -LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 height) - : + +// static +S32 LLTexLayerSetBuffer::sGLByteCount = 0; + +LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner, + S32 width, S32 height) : // ORDER_LAST => must render these after the hints are created. LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), - mNeedsUpdate( TRUE ), - mNeedsUpload( FALSE ), - mUploadPending( FALSE ), // Not used for any logic here, just to sync sending of updates - mUploadFailCount( 0 ), + mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates + mNeedsUpload(FALSE), + mUploadFailCount(0), + mNeedsUpdate(TRUE), mUploadAfter( 0 ), - mTexLayerSet( owner ) + mTexLayerSet(owner) { LLTexLayerSetBuffer::sGLByteCount += getSize(); } @@ -113,7 +142,7 @@ LLTexLayerSetBuffer::~LLTexLayerSetBuffer() { LLTexLayerSetBuffer::sGLByteCount -= getSize(); destroyGLTexture(); - for (S32 order = 0; order < ORDER_COUNT; order++) + for( S32 order = 0; order < ORDER_COUNT; order++ ) { LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. } @@ -180,10 +209,7 @@ void LLTexLayerSetBuffer::requestDelayedUpload(U64 delay_usec) void LLTexLayerSetBuffer::cancelUpload() { - if (mNeedsUpload) - { - mNeedsUpload = FALSE; - } + mNeedsUpload = FALSE; mUploadPending = FALSE; mUploadAfter = 0; } @@ -195,7 +221,7 @@ BOOL LLTexLayerSetBuffer::needsUploadNow() const return (upload && (LLFrameTimer::getTotalTime() > mUploadAfter)); } -void LLTexLayerSetBuffer::pushProjection() +void LLTexLayerSetBuffer::pushProjection() const { glMatrixMode(GL_PROJECTION); gGL.pushMatrix(); @@ -207,7 +233,7 @@ void LLTexLayerSetBuffer::pushProjection() glLoadIdentity(); } -void LLTexLayerSetBuffer::popProjection() +void LLTexLayerSetBuffer::popProjection() const { glMatrixMode(GL_PROJECTION); gGL.popMatrix(); @@ -285,21 +311,21 @@ BOOL LLTexLayerSetBuffer::render() { if (!success) { - llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegion() << llendl; + llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl; mUploadPending = FALSE; } else { if (mTexLayerSet->isVisible()) { - readBackAndUpload(); + doUpload(); } else { mUploadPending = FALSE; mNeedsUpload = FALSE; - mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getAvatar()->getBakedTE(mTexLayerSet), IMG_INVISIBLE); - llinfos << "Invisible baked texture set for " << mTexLayerSet->getBodyRegion() << llendl; + mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(), IMG_INVISIBLE); + llinfos << "Invisible baked texture set for " << mTexLayerSet->getBodyRegionName() << llendl; } } } @@ -315,12 +341,16 @@ BOOL LLTexLayerSetBuffer::render() return success; } -bool LLTexLayerSetBuffer::isInitialized(void) const +BOOL LLTexLayerSetBuffer::isInitialized(void) const { return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated(); } +BOOL LLTexLayerSetBuffer::uploadPending() const +{ + return mUploadPending; +} -BOOL LLTexLayerSetBuffer::updateImmediate() +BOOL LLTexLayerSetBuffer::requestUpdateImmediate() { mNeedsUpdate = TRUE; BOOL result = FALSE; @@ -335,9 +365,11 @@ BOOL LLTexLayerSetBuffer::updateImmediate() return result; } -void LLTexLayerSetBuffer::readBackAndUpload() +// Create the baked texture, send it out to the server, then wait for it to come +// back so we can switch to using it. +void LLTexLayerSetBuffer::doUpload() { - llinfos << "Baked " << mTexLayerSet->getBodyRegion() << llendl; + llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl; LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); // Don't need caches since we're baked now. (note: we won't *really* be baked @@ -351,15 +383,13 @@ void LLTexLayerSetBuffer::readBackAndUpload() // Get the MASK information from our texture LLGLSUIDefault gls_ui; - LLPointer baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 ); U8* baked_mask_data = baked_mask_image->getData(); - - mTexLayerSet->gatherAlphaMasks(baked_mask_data, mFullWidth, mFullHeight); -// imdebug("lum b=8 w=%d h=%d %p", mWidth, mHeight, baked_mask_data); + mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight); - S32 baked_image_components = 5; // red green blue bump clothing + // Create the baked image from our color and mask information + const S32 baked_image_components = 5; // red green blue [bump] clothing LLPointer baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components ); U8* baked_image_data = baked_image->getData(); S32 i = 0; @@ -367,11 +397,11 @@ void LLTexLayerSetBuffer::readBackAndUpload() { for (S32 v=0; v < mFullHeight; v++) { - baked_image_data[5 * i + 0] = baked_color_data[4 * i + 0]; - baked_image_data[5 * i + 1] = baked_color_data[4 * i + 1]; - baked_image_data[5 * i + 2] = baked_color_data[4 * i + 2]; - baked_image_data[5 * i + 3] = baked_color_data[4 * i + 3]; // alpha should be correct for eyelashes. - baked_image_data[5 * i + 4] = baked_mask_data[i]; + baked_image_data[5*i + 0] = baked_color_data[4*i + 0]; + baked_image_data[5*i + 1] = baked_color_data[4*i + 1]; + baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; + baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes. + baked_image_data[5*i + 4] = baked_mask_data[i]; i++; } } @@ -405,7 +435,7 @@ void LLTexLayerSetBuffer::readBackAndUpload() { // baked_upload_data is owned by the responder and deleted after the request completes LLBakedUploadData* baked_upload_data = - new LLBakedUploadData( gAgentAvatarp, this->mTexLayerSet, this, asset_id ); + new LLBakedUploadData( gAgentAvatarp, this->mTexLayerSet, asset_id ); mUploadID = asset_id; // Upload the image @@ -520,16 +550,17 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, gAgentAvatarp->dirtyMesh(); } - else - { + else + { + // Baked texture failed to upload (in which case since we // didn't set the new baked texture, it means that they'll try // and rebake it at some point in the future (after login?)), // or this response to upload is out of date, in which case a // current response should be on the way or already processed. - llwarns << "Baked upload failed" << llendl; - } - - delete baked_upload_data; + llwarns << "Baked upload failed" << llendl; + } + + delete baked_upload_data; } //----------------------------------------------------------------------------- @@ -610,13 +641,12 @@ BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node) BOOL LLTexLayerSet::sHasCaches = FALSE; -LLTexLayerSet::LLTexLayerSet( LLVOAvatarSelf* avatar ) - : +LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) : mComposite( NULL ), mAvatar( avatar ), mUpdatesEnabled( FALSE ), - mIsVisible(TRUE), - mBakedTexIndex(BAKED_HEAD), + mIsVisible( TRUE ), + mBakedTexIndex(LLVOAvatarDefines::BAKED_HEAD), mInfo( NULL ) { } @@ -633,17 +663,19 @@ LLTexLayerSet::~LLTexLayerSet() // setInfo //----------------------------------------------------------------------------- -BOOL LLTexLayerSet::setInfo(LLTexLayerSetInfo *info) +BOOL LLTexLayerSet::setInfo(const LLTexLayerSetInfo *info) { llassert(mInfo == NULL); mInfo = info; //mID = info->mID; // No ID - LLTexLayerSetInfo::layer_info_list_t::iterator iter; mLayerList.reserve(info->mLayerInfoList.size()); - for (iter = info->mLayerInfoList.begin(); iter != info->mLayerInfoList.end(); iter++) + for (LLTexLayerSetInfo::layer_info_list_t::const_iterator iter = info->mLayerInfoList.begin(); + iter != info->mLayerInfoList.end(); + iter++) { - LLTexLayer* layer = new LLTexLayer( this ); + LLTexLayerInterface* layer = new LLTexLayer( this ); + // this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar if (!layer->setInfo(*iter)) { mInfo = NULL; @@ -651,7 +683,7 @@ BOOL LLTexLayerSet::setInfo(LLTexLayerSetInfo *info) } if (!layer->isVisibilityMask()) { - mLayerList.push_back(layer); + mLayerList.push_back( layer ); } else { @@ -693,30 +725,197 @@ void LLTexLayerSet::deleteCaches() { for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { - LLTexLayer* layer = *iter; + LLTexLayerInterface* layer = *iter; layer->deleteCaches(); } for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) { - LLTexLayer* layer = *iter; + LLTexLayerInterface* layer = *iter; layer->deleteCaches(); } } // Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on. -BOOL LLTexLayerSet::isLocalTextureDataAvailable() +BOOL LLTexLayerSet::isLocalTextureDataAvailable() const { - return mAvatar->isLocalTextureDataAvailable( this ); + if (!mAvatar->isSelf()) return FALSE; + return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataAvailable(this); } // Returns TRUE if all of the data for the textures that this layerset depends on have arrived. -BOOL LLTexLayerSet::isLocalTextureDataFinal() +BOOL LLTexLayerSet::isLocalTextureDataFinal() const { - return mAvatar->isLocalTextureDataFinal( this ); + if (!mAvatar->isSelf()) return FALSE; + return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataFinal(this); } +BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) +{ + BOOL success = TRUE; + mIsVisible = TRUE; + + if (mMaskLayerList.size() > 0) + { + for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) + { + LLTexLayerInterface* layer = *iter; + if (layer->isInvisibleAlphaMask()) + { + mIsVisible = FALSE; + } + } + } + + LLGLSUIDefault gls_ui; + LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); + gGL.setColorMask(true, true); + + // clear buffer area to ensure we don't pick up UI elements + { + gGL.flush(); + LLGLDisable no_alpha(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.color4f( 0.f, 0.f, 0.f, 1.f ); + + gl_rect_2d_simple( width, height ); + + gGL.flush(); + } + + if (mIsVisible) + { + // composite color layers + for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + { + LLTexLayerInterface* layer = *iter; + if (layer->getRenderPass() == LLTexLayer::RP_COLOR || layer->getRenderPass() == LLTexLayer::RP_BUMP) + { + gGL.flush(); + success &= layer->render(x, y, width, height); + gGL.flush(); + } + } + + renderAlphaMaskTextures(x, y, width, height, false); + + stop_glerror(); + } + else + { + gGL.flush(); + + gGL.setSceneBlendType(LLRender::BT_REPLACE); + LLGLDisable no_alpha(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.color4f( 0.f, 0.f, 0.f, 0.f ); + + gl_rect_2d_simple( width, height ); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + gGL.flush(); + } + + return success; +} +BOOL LLTexLayerSet::isBodyRegion(const std::string& region) const +{ + return mInfo->mBodyRegion == region; +} + +const std::string LLTexLayerSet::getBodyRegionName() const +{ + return mInfo->mBodyRegion; +} + +void LLTexLayerSet::requestUpdate() +{ + if( mUpdatesEnabled ) + { + createComposite(); + mComposite->requestUpdate(); + } +} + +void LLTexLayerSet::requestUpload() +{ + createComposite(); + mComposite->requestUpload(); +} + +void LLTexLayerSet::cancelUpload() +{ + if(mComposite) + { + mComposite->cancelUpload(); + } +} + +void LLTexLayerSet::createComposite() +{ + if(!mComposite) + { + S32 width = mInfo->mWidth; + S32 height = mInfo->mHeight; + // Composite other avatars at reduced resolution + if( !mAvatar->isSelf() ) + { + width /= 2; + height /= 2; + } + mComposite = new LLTexLayerSetBuffer( this, width, height ); + } +} + +void LLTexLayerSet::destroyComposite() +{ + if( mComposite ) + { + mComposite = NULL; + } +} + +void LLTexLayerSet::setUpdatesEnabled( BOOL b ) +{ + mUpdatesEnabled = b; +} + + +void LLTexLayerSet::updateComposite() +{ + createComposite(); + mComposite->requestUpdateImmediate(); +} + +LLTexLayerSetBuffer* LLTexLayerSet::getComposite() +{ + if (!mComposite) + { + createComposite(); + } + return mComposite; +} + +const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const +{ + return mComposite; +} + +void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height) +{ + memset(data, 255, width * height); + + for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + { + LLTexLayerInterface* layer = *iter; + layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height); + } + + // Set alpha back to that of our alpha masks. + renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true); +} + void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear) { const LLTexLayerSetInfo *info = getInfo(); @@ -730,7 +929,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLGLSNoAlphaTest gls_no_alpha_test; gGL.flush(); { - LLViewerTexture* tex = gTexStaticImageList.getTexture(info->mStaticAlphaFileName, TRUE); + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE); if (tex) { LLGLSUIDefault gls_ui; @@ -762,7 +961,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_REPLACE); for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) { - LLTexLayer* layer = *iter; + LLTexLayerInterface* layer = *iter; gGL.flush(); layer->blendAlphaTexture(x, y, width, height); gGL.flush(); @@ -776,191 +975,48 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, gGL.setSceneBlendType(LLRender::BT_ALPHA); } -BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) -{ - BOOL success = TRUE; - mIsVisible = TRUE; - - if (mMaskLayerList.size() > 0) - { - for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) - { - LLTexLayer* layer = *iter; - if (layer->isInvisibleAlphaMask()) - { - mIsVisible = FALSE; - } - } - } - - LLGLSUIDefault gls_ui; - LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); - gGL.setColorMask(true, true); - - // clear buffer area to ensure we don't pick up UI elements - { - gGL.flush(); - LLGLDisable no_alpha(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4f( 0.f, 0.f, 0.f, 1.f ); - - gl_rect_2d_simple( width, height ); - - gGL.flush(); - } - - if (mIsVisible) - { - // composite color layers - for (layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++) - { - LLTexLayer* layer = *iter; - if (layer->getRenderPass() == RP_COLOR || layer->getRenderPass() == RP_BUMP) - { - gGL.flush(); - success &= layer->render(x, y, width, height); - gGL.flush(); - } - } - - renderAlphaMaskTextures(x, y, width, height, false); - - stop_glerror(); - } - else - { - gGL.flush(); - - gGL.setSceneBlendType(LLRender::BT_REPLACE); - LLGLDisable no_alpha(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4f( 0.f, 0.f, 0.f, 0.f ); - - gl_rect_2d_simple( width, height ); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - - gGL.flush(); - } - - return success; - } - -void LLTexLayerSet::requestUpdate() -{ - if( mUpdatesEnabled ) - { - createComposite(); - mComposite->requestUpdate(); - } -} - -void LLTexLayerSet::requestUpload() -{ - createComposite(); - mComposite->requestUpload(); -} - -void LLTexLayerSet::cancelUpload() -{ - if(mComposite) - { - mComposite->cancelUpload(); - } -} - -void LLTexLayerSet::createComposite() -{ - if( !mComposite ) - { - S32 width = mInfo->mWidth; - S32 height = mInfo->mHeight; - // Composite other avatars at reduced resolution - if( !mAvatar->isSelf() ) - { - width /= 2; - height /= 2; - } - mComposite = new LLTexLayerSetBuffer(this, width, height); - } -} - -void LLTexLayerSet::destroyComposite() -{ - if( mComposite ) - { - mComposite = NULL; - } -} - -void LLTexLayerSet::setUpdatesEnabled( BOOL b ) -{ - mUpdatesEnabled = b; -} - - -void LLTexLayerSet::updateComposite() -{ - createComposite(); - mComposite->updateImmediate(); -} - -LLTexLayerSetBuffer* LLTexLayerSet::getComposite() -{ - createComposite(); - return mComposite; -} - -void LLTexLayerSet::gatherAlphaMasks(U8 *data, S32 width, S32 height) -{ - S32 size = width * height; - - memset(data, 255, width * height); - - for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) - { - LLTexLayer* layer = *iter; - U8* alphaData = layer->getAlphaData(); - if (!alphaData && layer->hasAlphaParams()) - { - LLColor4 net_color; - layer->findNetColor( &net_color ); - layer->invalidateMorphMasks(); - layer->renderAlphaMasks(mComposite->getOriginX(), mComposite->getOriginY(), width, height, &net_color); - alphaData = layer->getAlphaData(); - } - if (alphaData) - { - for( S32 i = 0; i < size; i++ ) - { - U8 curAlpha = data[i]; - U16 resultAlpha = curAlpha; - resultAlpha *= (alphaData[i] + 1); - resultAlpha = resultAlpha >> 8; - data[i] = (U8)resultAlpha; - } - } - } - - // Set alpha back to that of our alpha masks. - renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true); -} - void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components) { for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { - LLTexLayer* layer = *iter; + LLTexLayerInterface* layer = *iter; layer->applyMorphMask(tex_data, width, height, num_components); } } +BOOL LLTexLayerSet::isMorphValid() const +{ + for(layer_list_t::const_iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + { + const LLTexLayerInterface* layer = *iter; + if (layer && !layer->isMorphValid()) + { + return FALSE; + } + } + return TRUE; +} + +void LLTexLayerSet::invalidateMorphMasks() +{ + for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) + { + LLTexLayerInterface* layer = *iter; + if (layer) + { + layer->invalidateMorphMasks(); + } + } +} + + + //----------------------------------------------------------------------------- // LLTexLayerInfo //----------------------------------------------------------------------------- -LLTexLayerInfo::LLTexLayerInfo( ) - : +LLTexLayerInfo::LLTexLayerInfo() : mWriteAllChannels( FALSE ), - mRenderPass( RP_COLOR ), + mRenderPass(LLTexLayer::RP_COLOR), mFixedColor( 0.f, 0.f, 0.f, 0.f ), mLocalTexture( -1 ), mStaticImageIsMask( FALSE ), @@ -971,8 +1027,8 @@ LLTexLayerInfo::LLTexLayerInfo( ) LLTexLayerInfo::~LLTexLayerInfo( ) { - std::for_each(mColorInfoList.begin(), mColorInfoList.end(), DeletePointer()); - std::for_each(mAlphaInfoList.begin(), mAlphaInfoList.end(), DeletePointer()); + std::for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer()); + std::for_each(mParamAlphaInfoList.begin(), mParamAlphaInfoList.end(), DeletePointer()); } BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) @@ -995,7 +1051,7 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) { if( render_pass_name == "bump" ) { - mRenderPass = RP_BUMP; + mRenderPass = LLTexLayer::RP_BUMP; } } @@ -1025,7 +1081,7 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) texture_node; texture_node = node->getNextNamedChild()) { - std::string local_texture; + std::string local_texture_name; static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file"); static LLStdStringHandle local_texture_string = LLXmlTree::addAttributeString("local_texture"); static LLStdStringHandle file_is_mask_string = LLXmlTree::addAttributeString("file_is_mask"); @@ -1034,105 +1090,27 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) { texture_node->getFastAttributeBOOL( file_is_mask_string, mStaticImageIsMask ); } - else if( texture_node->getFastAttributeString( local_texture_string, local_texture ) ) + else if (texture_node->getFastAttributeString(local_texture_string, local_texture_name)) { texture_node->getFastAttributeBOOL( local_texture_alpha_only_string, mUseLocalTextureAlphaOnly ); - if( "upper_shirt" == local_texture ) + /* if ("upper_shirt" == local_texture_name) + mLocalTexture = TEX_UPPER_SHIRT; */ + mLocalTexture = TEX_NUM_INDICES; + for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); + iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); + iter++) { - mLocalTexture = TEX_UPPER_SHIRT; + const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; + if (local_texture_name == texture_dict->mName) + { + mLocalTexture = iter->first; + break; } - else if( "upper_bodypaint" == local_texture ) - { - mLocalTexture = TEX_UPPER_BODYPAINT; } - else if( "lower_pants" == local_texture ) + if (mLocalTexture == TEX_NUM_INDICES) { - mLocalTexture = TEX_LOWER_PANTS; - } - else if( "lower_bodypaint" == local_texture ) - { - mLocalTexture = TEX_LOWER_BODYPAINT; - } - else if( "lower_shoes" == local_texture ) - { - mLocalTexture = TEX_LOWER_SHOES; - } - else if( "head_bodypaint" == local_texture ) - { - mLocalTexture = TEX_HEAD_BODYPAINT; - } - else if( "lower_socks" == local_texture ) - { - mLocalTexture = TEX_LOWER_SOCKS; - } - else if( "upper_jacket" == local_texture ) - { - mLocalTexture = TEX_UPPER_JACKET; - } - else if( "lower_jacket" == local_texture ) - { - mLocalTexture = TEX_LOWER_JACKET; - } - else if( "upper_gloves" == local_texture ) - { - mLocalTexture = TEX_UPPER_GLOVES; - } - else if( "upper_undershirt" == local_texture ) - { - mLocalTexture = TEX_UPPER_UNDERSHIRT; - } - else if( "lower_underpants" == local_texture ) - { - mLocalTexture = TEX_LOWER_UNDERPANTS; - } - else if( "eyes_iris" == local_texture ) - { - mLocalTexture = TEX_EYES_IRIS; - } - else if( "skirt" == local_texture ) - { - mLocalTexture = TEX_SKIRT; - } - else if( "hair_grain" == local_texture ) - { - mLocalTexture = TEX_HAIR; - } - else if ("hair_alpha" == local_texture) - { - mLocalTexture = TEX_HAIR_ALPHA; - } - else if ("head_alpha" == local_texture) - { - mLocalTexture = TEX_HEAD_ALPHA; - } - else if ("upper_alpha" == local_texture) - { - mLocalTexture = TEX_UPPER_ALPHA; - } - else if ("lower_alpha" == local_texture) - { - mLocalTexture = TEX_LOWER_ALPHA; - } - else if ("eyes_alpha" == local_texture) - { - mLocalTexture = TEX_EYES_ALPHA; - } - else if ("head_tattoo" == local_texture) - { - mLocalTexture = TEX_HEAD_TATTOO; - } - else if ("upper_tattoo" == local_texture) - { - mLocalTexture = TEX_UPPER_TATTOO; - } - else if ("lower_tattoo" == local_texture) - { - mLocalTexture = TEX_LOWER_TATTOO; - } - else - { - llwarns << " element has invalid local_texture attribute: " << mName << " " << local_texture << llendl; + llwarns << " element has invalid local_texture attribute: " << mName << " " << local_texture_name << llendl; return FALSE; } } @@ -1166,13 +1144,13 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) if( child->getChildByName( "param_color" ) ) { // - LLTexParamColorInfo* info = new LLTexParamColorInfo( ); + LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo(); if (!info->parseXml(child)) { delete info; return FALSE; } - mColorInfoList.push_back( info ); + mParamColorInfoList.push_back(info); } else if( child->getChildByName( "param_alpha" ) ) { @@ -1183,13 +1161,171 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) delete info; return FALSE; } - mAlphaInfoList.push_back( info ); + mParamAlphaInfoList.push_back(info); } } return TRUE; } + +LLTexLayerInterface::LLTexLayerInterface(LLTexLayerSet* const layer_set): + mTexLayerSet( layer_set ), + mMorphMasksValid( FALSE ), + mInfo(NULL), + mHasMorph(FALSE) +{ +} +BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info ) // This sets mInfo and calls initialization functions +{ + // setInfo should only be called once. Code is not robust enough to handle redefinition of a texlayer. + // Not a critical warning, but could be useful for debugging later issues. -Nyx + if (mInfo != NULL) + { + llwarns << "mInfo != NULL" << llendl; + } + mInfo = info; + //mID = info->mID; // No ID + + mParamColorList.reserve(mInfo->mParamColorInfoList.size()); + for (param_color_info_list_t::const_iterator iter = mInfo->mParamColorInfoList.begin(); + iter != mInfo->mParamColorInfoList.end(); + iter++) + { + LLTexLayerParamColor* param_color; + //if (!wearable) + { + param_color = new LLTexLayerParamColor(this); + if (!param_color->setInfo(*iter, TRUE)) + { + mInfo = NULL; + return FALSE; + } + } + /*else + { + param_color = (LLTexLayerParamColor*)wearable->getVisualParam((*iter)->getID()); + if (!param_color) + { + mInfo = NULL; + return FALSE; + } + }*/ + mParamColorList.push_back( param_color ); + } + + mParamAlphaList.reserve(mInfo->mParamAlphaInfoList.size()); + for (param_alpha_info_list_t::const_iterator iter = mInfo->mParamAlphaInfoList.begin(); + iter != mInfo->mParamAlphaInfoList.end(); + iter++) + { + LLTexLayerParamAlpha* param_alpha; + //if (!wearable) + { + param_alpha = new LLTexLayerParamAlpha( this ); + if (!param_alpha->setInfo(*iter, TRUE)) + { + mInfo = NULL; + return FALSE; + } + } + /*else + { + param_alpha = (LLTexLayerParamAlpha*) wearable->getVisualParam((*iter)->getID()); + if (!param_alpha) + { + mInfo = NULL; + return FALSE; + } + }*/ + mParamAlphaList.push_back( param_alpha ); + } + + LLTexLayerInfo::morph_name_list_t::const_iterator iter = getInfo()->mMorphNameList.begin(); + for (; iter != getInfo()->mMorphNameList.end(); iter++) + { + // *FIX: we assume that the referenced visual param is a + // morph target, need a better way of actually looking + // this up. + LLPolyMorphTarget *morph_param; + const std::string &name = (iter->first); + morph_param = (LLPolyMorphTarget *)(getTexLayerSet()->getAvatar()->getVisualParam(name.c_str())); + if (morph_param) + { + BOOL invert = iter->second; + addMaskedMorph(morph_param, invert); + } + } + return TRUE; +} + +void LLTexLayerInterface::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components) +{ + for( morph_list_t::iterator iter = mMaskedMorphs.begin(); + iter != mMaskedMorphs.end(); iter++ ) + { + LLVOAvatar::LLMaskedMorph* maskedMorph = (LLVOAvatar::LLMaskedMorph*)(*iter); + maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); + } +} + +void LLTexLayerInterface::addMaskedMorph(LLPolyMorphTarget* morph_target, BOOL invert) +{ + mMaskedMorphs.push_front((char*)new LLVOAvatar::LLMaskedMorph(morph_target, invert)); + setHasMorph(!mMaskedMorphs.empty()); +} + +/*virtual*/ void LLTexLayerInterface::requestUpdate() +{ + mTexLayerSet->requestUpdate(); +} + +const std::string& LLTexLayerInterface::getName() const +{ + return mInfo->mName; +} + +LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const +{ + return mInfo->mRenderPass; +} + +const std::string& LLTexLayerInterface::getGlobalColor() const +{ + return mInfo->mGlobalColor; +} + +BOOL LLTexLayerInterface::isVisibilityMask() const +{ + return mInfo->mIsVisibilityMask; +} + +void LLTexLayerInterface::invalidateMorphMasks() +{ + mMorphMasksValid = FALSE; +} + +LLViewerVisualParam* LLTexLayerInterface::getVisualParamPtr(S32 index) const +{ + LLViewerVisualParam *result = NULL; + for (param_color_list_t::const_iterator color_iter = mParamColorList.begin(); color_iter != mParamColorList.end() && !result; ++color_iter) + { + if ((*color_iter)->getID() == index) + { + result = *color_iter; + } + } + for (param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin(); alpha_iter != mParamAlphaList.end() && !result; ++alpha_iter) + { + if ((*alpha_iter)->getID() == index) + { + result = *alpha_iter; + } + } + + return result; +} + //----------------------------------------------------------------------------- // LLTexLayer // A single texture layer, consisting of: @@ -1203,12 +1339,10 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) // * a texture entry index (TE) // * (optional) one or more alpha parameters (weighted alpha textures) //----------------------------------------------------------------------------- -LLTexLayer::LLTexLayer( LLTexLayerSet* layer_set ) - : - mTexLayerSet( layer_set ), - mMorphMasksValid( FALSE ), - mStaticImageInvalid( FALSE ), - mInfo( NULL ) +LLTexLayer::LLTexLayer(LLTexLayerSet* const layer_set) : + LLTexLayerInterface( layer_set ), + + mStaticImageInvalid( FALSE ) { } @@ -1225,100 +1359,50 @@ LLTexLayer::~LLTexLayer() U8* alpha_data = iter->second; delete [] alpha_data; } + } //----------------------------------------------------------------------------- // setInfo //----------------------------------------------------------------------------- -BOOL LLTexLayer::setInfo(LLTexLayerInfo* info) +BOOL LLTexLayer::setInfo(const LLTexLayerInfo* info) { - //llassert(mInfo == NULL); // nyx says this is probably bogus but needs investigating - if (mInfo != NULL) // above llassert(), but softened into a warning - { - llwarns << "BAD STUFF! mInfo != NULL" << llendl; - } - mInfo = info; - //mID = info->mID; // No ID - - { - LLTexLayerInfo::morph_name_list_t::iterator iter; - for (iter = mInfo->mMorphNameList.begin(); iter != mInfo->mMorphNameList.end(); iter++) - { - // *FIX: we assume that the referenced visual param is a - // morph target, need a better way of actually looking - // this up. - LLPolyMorphTarget *morph_param; - std::string *name = &(iter->first); - morph_param = (LLPolyMorphTarget *)(getTexLayerSet()->getAvatar()->getVisualParam(name->c_str())); - if (morph_param) - { - BOOL invert = iter->second; - addMaskedMorph(morph_param, invert); - } - } - } - - { - LLTexLayerInfo::color_info_list_t::iterator iter; - mParamColorList.reserve(mInfo->mColorInfoList.size()); - for (iter = mInfo->mColorInfoList.begin(); iter != mInfo->mColorInfoList.end(); iter++) - { - LLTexParamColor* param_color = new LLTexParamColor( this ); - if (!param_color->setInfo(*iter)) - { - mInfo = NULL; - return FALSE; - } - mParamColorList.push_back( param_color ); - } - } - { - LLTexLayerInfo::alpha_info_list_t::iterator iter; - mParamAlphaList.reserve(mInfo->mAlphaInfoList.size()); - for (iter = mInfo->mAlphaInfoList.begin(); iter != mInfo->mAlphaInfoList.end(); iter++) - { - LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha( this ); - if (!param_alpha->setInfo(*iter)) - { - mInfo = NULL; - return FALSE; - } - mParamAlphaList.push_back( param_alpha ); - } - } - - return TRUE; + return LLTexLayerInterface::setInfo(info); } -#if 0 // obsolete -//----------------------------------------------------------------------------- -// parseData -//----------------------------------------------------------------------------- -BOOL LLTexLayer::parseData( LLXmlTreeNode* node ) +//static +void LLTexLayer::calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color) { - LLTexLayerInfo *info = new LLTexLayerInfo; - - if (!info->parseXml(node)) + for (param_color_list_t::const_iterator iter = param_list.begin(); + iter != param_list.end(); iter++) { - delete info; - return FALSE; + const LLTexLayerParamColor* param = *iter; + LLColor4 param_net = param->getNetColor(); + const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)param->getInfo(); + switch(info->getOperation()) + { + case LLTexLayerParamColor::OP_ADD: + net_color += param_net; + break; + case LLTexLayerParamColor::OP_MULTIPLY: + net_color = net_color * param_net; + break; + case LLTexLayerParamColor::OP_BLEND: + net_color = lerp(net_color, param_net, param->getWeight()); + break; + default: + llassert(0); + break; + } } - if (!setInfo(info)) - { - delete info; - return FALSE; - } - return TRUE; + net_color.clamp(); } -#endif -//----------------------------------------------------------------------------- - - -void LLTexLayer::deleteCaches() +/*virtual*/ void LLTexLayer::deleteCaches() { - for( alpha_list_t::iterator iter = mParamAlphaList.begin(); + // Only need to delete caches for alpha params. Color params don't hold extra memory + for (param_alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ ) { LLTexLayerParamAlpha* param = *iter; @@ -1327,14 +1411,14 @@ void LLTexLayer::deleteCaches() mStaticImageRaw = NULL; } -BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) +BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) { LLGLEnable color_mat(GL_COLOR_MATERIAL); gPipeline.disableLights(); LLColor4 net_color; BOOL color_specified = findNetColor(&net_color); - + if (mTexLayerSet->getAvatar()->mIsDummy) { color_specified = true; @@ -1350,18 +1434,18 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) } BOOL alpha_mask_specified = FALSE; - alpha_list_t::iterator iter = mParamAlphaList.begin(); + param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); if( iter != mParamAlphaList.end() ) { // If we have alpha masks, but we're skipping all of them, skip the whole layer. // However, we can't do this optimization if we have morph masks that need updating. -/* if( mMaskedMorphs.empty() ) +/* if (!mHasMorph) { BOOL skip_layer = TRUE; while( iter != mParamAlphaList.end() ) { - LLTexLayerParamAlpha* param = *iter; + const LLTexLayerParamAlpha* param = *iter; if( !param->getSkip() ) { @@ -1376,9 +1460,9 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) { return success; } - }*/ + }//*/ - renderAlphaMasks( x, y, width, height, &net_color ); + renderMorphMasks(x, y, width, height, net_color); alpha_mask_specified = TRUE; gGL.flush(); gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA); @@ -1428,7 +1512,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) if( !getInfo()->mStaticImageFileName.empty() ) { { - LLViewerTexture* tex = gTexStaticImageList.getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { gGL.getTexUnit(0)->bind(tex, TRUE); @@ -1474,20 +1558,85 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) return success; } +const U8* LLTexLayer::getAlphaData() const +{ + LLCRC alpha_mask_crc; + const LLUUID& uuid = getUUID(); + alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES); + + for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++) + { + const LLTexLayerParamAlpha* param = *iter; + // MULTI-WEARABLE: verify visual parameters used here + F32 param_weight = param->getWeight(); + alpha_mask_crc.update((U8*)¶m_weight, sizeof(F32)); + } + + U32 cache_index = alpha_mask_crc.getCRC(); + + alpha_cache_t::const_iterator iter2 = mAlphaCache.find(cache_index); + return (iter2 == mAlphaCache.end()) ? 0 : iter2->second; +} + +BOOL LLTexLayer::findNetColor(LLColor4* net_color) const +{ + // Color is either: + // * one or more color parameters (weighted colors) (which may make use of a global color or fixed color) + // * a reference to a global color + // * a fixed color with non-zero alpha + // * opaque white (the default) + + if( !mParamColorList.empty() ) + { + if( !getGlobalColor().empty() ) + { + net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getInfo()->mGlobalColor ) ); + } + else if (getInfo()->mFixedColor.mV[VW]) + { + net_color->setVec( getInfo()->mFixedColor ); + } + else + { + net_color->setVec( 0.f, 0.f, 0.f, 0.f ); + } + + calculateTexLayerColor(mParamColorList, *net_color); + return TRUE; + } + + if( !getGlobalColor().empty() ) + { + net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getGlobalColor() ) ); + return TRUE; + } + + if( getInfo()->mFixedColor.mV[VW] ) + { + net_color->setVec( getInfo()->mFixedColor ); + return TRUE; + } + + net_color->setToWhite(); + + return FALSE; // No need to draw a separate colored polygon +} + BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) { BOOL success = TRUE; gGL.flush(); - if (!getInfo()->mStaticImageFileName.empty()) + + if( !getInfo()->mStaticImageFileName.empty() ) { - LLViewerTexture* tex = gTexStaticImageList.getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); - if (tex) + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask ); + if( tex ) { LLGLSNoAlphaTest gls_no_alpha_test; gGL.getTexUnit(0)->bind(tex, TRUE); - gl_rect_2d_simple_tex(width, height); + gl_rect_2d_simple_tex( width, height ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } else @@ -1517,95 +1666,12 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) return success; } -U8* LLTexLayer::getAlphaData() +/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { - LLCRC alpha_mask_crc; - const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture); - alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES); - - for( alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ ) - { - LLTexLayerParamAlpha* param = *iter; - F32 param_weight = param->getWeight(); - alpha_mask_crc.update((U8*)¶m_weight, sizeof(F32)); - } - - U32 cache_index = alpha_mask_crc.getCRC(); - - alpha_cache_t::iterator iter2 = mAlphaCache.find(cache_index); - return (iter2 == mAlphaCache.end()) ? 0 : iter2->second; + addAlphaMask(data, originX, originY, width, height); } -BOOL LLTexLayer::findNetColor( LLColor4* net_color ) -{ - // Color is either: - // * one or more color parameters (weighted colors) (which may make use of a global color or fixed color) - // * a reference to a global color - // * a fixed color with non-zero alpha - // * opaque white (the default) - - if( !mParamColorList.empty() ) - { - if( !getGlobalColor().empty() ) - { - net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getInfo()->mGlobalColor ) ); - } - else - if( getInfo()->mFixedColor.mV[VW] ) - { - net_color->setVec( getInfo()->mFixedColor ); - } - else - { - net_color->setVec( 0.f, 0.f, 0.f, 0.f ); - } - - for( color_list_t::iterator iter = mParamColorList.begin(); - iter != mParamColorList.end(); iter++ ) - { - LLTexParamColor* param = *iter; - LLColor4 param_net = param->getNetColor(); - switch( param->getOperation() ) - { - case OP_ADD: - *net_color += param_net; - break; - case OP_MULTIPLY: - net_color->mV[VX] *= param_net.mV[VX]; - net_color->mV[VY] *= param_net.mV[VY]; - net_color->mV[VZ] *= param_net.mV[VZ]; - net_color->mV[VW] *= param_net.mV[VW]; - break; - case OP_BLEND: - net_color->setVec( lerp(*net_color, param_net, param->getWeight()) ); - break; - default: - llassert(0); - break; - } - } - return TRUE; - } - - if( !getGlobalColor().empty() ) - { - net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getGlobalColor() ) ); - return TRUE; - } - - if( getInfo()->mFixedColor.mV[VW] ) - { - net_color->setVec( getInfo()->mFixedColor ); - return TRUE; - } - - net_color->setToWhite(); - - return FALSE; // No need to draw a separate colored polygon -} - - -BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp ) +BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color) { BOOL success = TRUE; @@ -1613,9 +1679,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 gGL.setColorMask(false, true); - alpha_list_t::iterator iter = mParamAlphaList.begin(); - LLTexLayerParamAlpha* first_param = *iter; - + LLTexLayerParamAlpha* first_param = *mParamAlphaList.begin(); // Note: if the first param is a mulitply, multiply against the current buffer's alpha if( !first_param || !first_param->getMultiplyBlend() ) { @@ -1633,8 +1697,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 // Accumulate alphas LLGLSNoAlphaTest gls_no_alpha_test; gGL.color4f( 1.f, 1.f, 1.f, 1.f ); - - for( iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ ) + for (param_alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++) { LLTexLayerParamAlpha* param = *iter; success &= param->render( x, y, width, height ); @@ -1671,7 +1734,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 if( !getInfo()->mStaticImageFileName.empty() ) { - LLViewerTexture* tex = gTexStaticImageList.getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); + LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask); if( tex ) { if( (tex->getComponents() == 4) || @@ -1687,11 +1750,11 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 // Draw a rectangle with the layer color to multiply the alpha by that color's alpha. // Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO ); - if( colorp->mV[VW] != 1.f ) + if (layer_color.mV[VW] != 1.f) { LLGLDisable no_alpha(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4fv( colorp->mV ); + gGL.color4fv(layer_color.mV); gl_rect_2d_simple( width, height ); } @@ -1700,34 +1763,28 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 gGL.setColorMask(true, true); - if (success && !mMorphMasksValid && !mMaskedMorphs.empty()) + if (hasMorph() && success) { LLCRC alpha_mask_crc; - const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture); + const LLUUID& uuid = getUUID(); alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES); - for( alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ ) + for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++) { - LLTexLayerParamAlpha* param = *iter; + const LLTexLayerParamAlpha* param = *iter; F32 param_weight = param->getWeight(); alpha_mask_crc.update((U8*)¶m_weight, sizeof(F32)); } U32 cache_index = alpha_mask_crc.getCRC(); - - alpha_cache_t::iterator iter2 = mAlphaCache.find(cache_index); - U8* alpha_data; - if (iter2 != mAlphaCache.end()) - { - alpha_data = iter2->second; - } - else + U8* alpha_data = get_if_there(mAlphaCache,cache_index,(U8*)NULL); + if (!alpha_data) { // clear out a slot if we have filled our cache S32 max_cache_entries = getTexLayerSet()->getAvatar()->isSelf() ? 4 : 1; while ((S32)mAlphaCache.size() >= max_cache_entries) { - iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry + alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry alpha_data = iter2->second; delete [] alpha_data; mAlphaCache.erase(iter2); @@ -1740,120 +1797,39 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 getTexLayerSet()->getAvatar()->dirtyMesh(); mMorphMasksValid = TRUE; - - for( morph_list_t::iterator iter3 = mMaskedMorphs.begin(); - iter3 != mMaskedMorphs.end(); iter3++ ) - { - LLVOAvatar::LLMaskedMorph* maskedMorph = &(*iter3); - maskedMorph->mMorphTarget->applyMask(alpha_data, width, height, 1, maskedMorph->mInvert); - } + applyMorphMask(alpha_data, width, height, 1); } return success; } -void LLTexLayer::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components) +void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { - for( morph_list_t::iterator iter = mMaskedMorphs.begin(); - iter != mMaskedMorphs.end(); iter++ ) + S32 size = width * height; + const U8* alphaData = getAlphaData(); + if (!alphaData && hasAlphaParams()) { - LLVOAvatar::LLMaskedMorph* maskedMorph = &(*iter); - maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert); + LLColor4 net_color; + findNetColor( &net_color ); + // TODO: eliminate need for layer morph mask valid flag + invalidateMorphMasks(); + renderMorphMasks(originX, originY, width, height, net_color); + alphaData = getAlphaData(); } -} - -// Returns TRUE on success. -BOOL LLTexLayer::renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask ) -{ - if (!in_data) + if (alphaData) { - return FALSE; - } - GLenum format_options[4] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA }; - GLenum format = format_options[in_components-1]; - if( is_mask ) - { - llassert( 1 == in_components ); - format = GL_ALPHA; - } - - if( (in_width != SCRATCH_TEX_WIDTH) || (in_height != SCRATCH_TEX_HEIGHT) ) - { - LLGLSNoAlphaTest gls_no_alpha_test; - - GLenum internal_format_options[4] = { GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8 }; - GLenum internal_format = internal_format_options[in_components-1]; - if( is_mask ) + for( S32 i = 0; i < size; i++ ) { - llassert( 1 == in_components ); - internal_format = GL_ALPHA8; + U8 curAlpha = data[i]; + U16 resultAlpha = curAlpha; + resultAlpha *= (alphaData[i] + 1); + resultAlpha = resultAlpha >> 8; + data[i] = (U8)resultAlpha; } - - U32 name = 0; - LLImageGL::generateTextures(1, &name ); - stop_glerror(); - - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name); - stop_glerror(); - - LLImageGL::setManualImage( - GL_TEXTURE_2D, 0, internal_format, - in_width, in_height, - format, GL_UNSIGNED_BYTE, in_data ); - stop_glerror(); - - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - - gl_rect_2d_simple_tex( width, height ); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - LLImageGL::deleteTextures(1, &name ); - stop_glerror(); } - else - { - LLGLSNoAlphaTest gls_no_alpha_test; - - if( !mTexLayerSet->getAvatar()->bindScratchTexture(format) ) - { - return FALSE; - } - - glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, in_width, in_height, format, GL_UNSIGNED_BYTE, in_data ); - stop_glerror(); - - gl_rect_2d_simple_tex( width, height ); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - } - - return TRUE; } -void LLTexLayer::requestUpdate() -{ - mTexLayerSet->requestUpdate(); -} - -void LLTexLayer::addMaskedMorph(LLPolyMorphTarget* morph_target, BOOL invert) -{ - mMaskedMorphs.push_front(LLVOAvatar::LLMaskedMorph(morph_target, invert)); -} - -void LLTexLayer::invalidateMorphMasks() -{ - mMorphMasksValid = FALSE; -} - -BOOL LLTexLayer::isVisibilityMask() const -{ - return mInfo->mIsVisibilityMask; -} - -BOOL LLTexLayer::isInvisibleAlphaMask() +BOOL LLTexLayer::isInvisibleAlphaMask() const { const LLTexLayerInfo *info = getInfo(); @@ -1868,656 +1844,60 @@ BOOL LLTexLayer::isInvisibleAlphaMask() return FALSE; } -//----------------------------------------------------------------------------- -// LLTexLayerParamAlphaInfo -//----------------------------------------------------------------------------- -LLTexLayerParamAlphaInfo::LLTexLayerParamAlphaInfo( ) - : - mMultiplyBlend( FALSE ), - mSkipIfZeroWeight( FALSE ), - mDomain( 0.f ) +LLUUID LLTexLayer::getUUID() const { + return mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture); } -BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node) -{ - llassert( node->hasName( "param" ) && node->getChildByName( "param_alpha" ) ); - - if( !LLViewerVisualParamInfo::parseXml(node) ) - return FALSE; - - LLXmlTreeNode* param_alpha_node = node->getChildByName( "param_alpha" ); - if( !param_alpha_node ) - { - return FALSE; - } - - static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file"); - if( param_alpha_node->getFastAttributeString( tga_file_string, mStaticImageFileName ) ) - { - // Don't load the image file until it's actually needed. - } -// else -// { -// llwarns << " element is missing tga_file attribute." << llendl; -// } - - static LLStdStringHandle multiply_blend_string = LLXmlTree::addAttributeString("multiply_blend"); - param_alpha_node->getFastAttributeBOOL( multiply_blend_string, mMultiplyBlend ); - - static LLStdStringHandle skip_if_zero_string = LLXmlTree::addAttributeString("skip_if_zero"); - param_alpha_node->getFastAttributeBOOL( skip_if_zero_string, mSkipIfZeroWeight ); - - static LLStdStringHandle domain_string = LLXmlTree::addAttributeString("domain"); - param_alpha_node->getFastAttributeF32( domain_string, mDomain ); - - return TRUE; -} //----------------------------------------------------------------------------- -// LLTexLayerParamAlpha +// finds a specific layer based on a passed in name //----------------------------------------------------------------------------- - -// static -LLTexLayerParamAlpha::param_alpha_ptr_list_t LLTexLayerParamAlpha::sInstances; - -// static -void LLTexLayerParamAlpha::dumpCacheByteCount() +LLTexLayerInterface* LLTexLayerSet::findLayerByName(const std::string& name) { - S32 gl_bytes = 0; - getCacheByteCount( &gl_bytes ); - llinfos << "Processed Alpha Texture Cache GL:" << (gl_bytes/1024) << "KB" << llendl; -} - -// static -void LLTexLayerParamAlpha::getCacheByteCount( S32* gl_bytes ) -{ - *gl_bytes = 0; - - for( param_alpha_ptr_list_t::iterator iter = sInstances.begin(); - iter != sInstances.end(); iter++ ) + for (layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { - LLTexLayerParamAlpha* instance = *iter; - LLViewerTexture* tex = instance->mCachedProcessedTexture; - if( tex ) + LLTexLayerInterface* layer = *iter; + if (layer->getName() == name) { - S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents(); - - if( tex->hasGLTexture() ) - { - *gl_bytes += bytes; - } + return layer; } } -} - -LLTexLayerParamAlpha::LLTexLayerParamAlpha( LLTexLayer* layer ) - : - mCachedProcessedTexture( NULL ), - mTexLayer( layer ), - mNeedsCreateTexture( FALSE ), - mStaticImageInvalid( FALSE ), - mAvgDistortionVec(1.f, 1.f, 1.f), - mCachedEffectiveWeight(0.f) -{ - sInstances.push_front( this ); -} - -LLTexLayerParamAlpha::~LLTexLayerParamAlpha() -{ - deleteCaches(); - sInstances.remove( this ); -} - -//----------------------------------------------------------------------------- -// setInfo() -//----------------------------------------------------------------------------- -BOOL LLTexLayerParamAlpha::setInfo(LLTexLayerParamAlphaInfo *info) -{ - llassert(mInfo == NULL); - if (info->mID < 0) - return FALSE; - mInfo = info; - mID = info->mID; - - mTexLayer->getTexLayerSet()->getAvatar()->addVisualParam( this ); - setWeight(getDefaultWeight(), FALSE ); - - return TRUE; -} - -//----------------------------------------------------------------------------- - -void LLTexLayerParamAlpha::deleteCaches() -{ - mStaticImageTGA = NULL; // deletes image - mCachedProcessedTexture = NULL; - mStaticImageRaw = NULL; - mNeedsCreateTexture = FALSE; -} - -void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL set_by_user) -{ - if (mIsAnimating) + for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ ) { - return; - } - F32 min_weight = getMinWeight(); - F32 max_weight = getMaxWeight(); - F32 new_weight = llclamp(weight, min_weight, max_weight); - U8 cur_u8 = F32_to_U8( mCurWeight, min_weight, max_weight ); - U8 new_u8 = F32_to_U8( new_weight, min_weight, max_weight ); - if( cur_u8 != new_u8) - { - mCurWeight = new_weight; - - LLVOAvatar* avatar = mTexLayer->getTexLayerSet()->getAvatar(); - if( avatar->getSex() & getSex() ) + LLTexLayerInterface* layer = *iter; + if (layer->getName() == name) { - if ( gAgentCamera.cameraCustomizeAvatar() ) - { - set_by_user = FALSE; - } - avatar->invalidateComposite( mTexLayer->getTexLayerSet(), set_by_user ); - mTexLayer->invalidateMorphMasks(); - avatar->updateMeshTextures(); + return layer; } } -} - -void LLTexLayerParamAlpha::setAnimationTarget(F32 target_value, BOOL set_by_user) -{ - mTargetWeight = target_value; - setWeight(target_value, set_by_user); - mIsAnimating = TRUE; - if (mNext) - { - mNext->setAnimationTarget(target_value, set_by_user); - } -} - -void LLTexLayerParamAlpha::animate(F32 delta, BOOL set_by_user) -{ - if (mNext) - { - mNext->animate(delta, set_by_user); - } -} - -BOOL LLTexLayerParamAlpha::getSkip() -{ - LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar(); - - if( getInfo()->mSkipIfZeroWeight ) - { - F32 effective_weight = ( avatar->getSex() & getSex() ) ? mCurWeight : getDefaultWeight(); - if (is_approx_zero( effective_weight )) - { - return TRUE; - } - } - - LLWearableType::EType type = (LLWearableType::EType)getWearableType(); - if( (type != LLWearableType::WT_INVALID) && !avatar->isWearingWearableType( type ) ) - { - return TRUE; - } - - return FALSE; -} - - -BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height ) -{ - BOOL success = TRUE; - - F32 effective_weight = ( mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex() ) ? mCurWeight : getDefaultWeight(); - BOOL weight_changed = effective_weight != mCachedEffectiveWeight; - if( getSkip() ) - { - return success; - } - - gGL.flush(); - if( getInfo()->mMultiplyBlend ) - { - gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); // Multiplication: approximates a min() function - } - else - { - gGL.setSceneBlendType(LLRender::BT_ADD); // Addition: approximates a max() function - } - - if( !getInfo()->mStaticImageFileName.empty() && !mStaticImageInvalid) - { - if( mStaticImageTGA.isNull() ) - { - // Don't load the image file until we actually need it the first time. Like now. - mStaticImageTGA = gTexStaticImageList.getImageTGA( getInfo()->mStaticImageFileName ); - // We now have something in one of our caches - LLTexLayerSet::sHasCaches |= mStaticImageTGA.notNull() ? TRUE : FALSE; - - if( mStaticImageTGA.isNull() ) - { - llwarns << "Unable to load static file: " << getInfo()->mStaticImageFileName << llendl; - mStaticImageInvalid = TRUE; // don't try again. - return FALSE; - } - } - - const S32 image_tga_width = mStaticImageTGA->getWidth(); - const S32 image_tga_height = mStaticImageTGA->getHeight(); - if( !mCachedProcessedTexture || - (mCachedProcessedTexture->getWidth() != image_tga_width) || - (mCachedProcessedTexture->getHeight() != image_tga_height) || - (weight_changed) ) - { -// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl; - mCachedEffectiveWeight = effective_weight; - - if( !mCachedProcessedTexture ) - { - mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture( image_tga_width, image_tga_height, 1, FALSE ); - - // We now have something in one of our caches - LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE; - - mCachedProcessedTexture->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); - } - - // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed. - mStaticImageRaw = NULL; - mStaticImageRaw = new LLImageRaw; - mStaticImageTGA->decodeAndProcess( mStaticImageRaw, getInfo()->mDomain, effective_weight ); - mNeedsCreateTexture = TRUE; - } - - if( mCachedProcessedTexture ) - { - { - // Create the GL texture, and then hang onto it for future use. - if( mNeedsCreateTexture ) - { - mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw, 0, TRUE, LLViewerTexture::BOOST_AVATAR_SELF); - mNeedsCreateTexture = FALSE; - gGL.getTexUnit(0)->bind(mCachedProcessedTexture); - mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP); - } - - LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(mCachedProcessedTexture, TRUE); - gl_rect_2d_simple_tex( width, height ); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - stop_glerror(); - } - } - - // Don't keep the cache for other people's avatars - // (It's not really a "cache" in that case, but the logic is the same) - if( !mTexLayer->getTexLayerSet()->getAvatar()->isSelf() ) - { - mCachedProcessedTexture = NULL; - } - } - else - { - LLGLDisable no_alpha(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4f( 0.f, 0.f, 0.f, effective_weight ); - gl_rect_2d_simple( width, height ); - } - - return success; + return NULL; } //----------------------------------------------------------------------------- -// LLTexGlobalColorInfo +// LLTexLayerStaticImageList //----------------------------------------------------------------------------- -LLTexGlobalColorInfo::LLTexGlobalColorInfo() +LLTexLayerStaticImageList::LLTexLayerStaticImageList() : + mGLBytes(0), + mTGABytes(0), + mImageNames(16384) { } - -LLTexGlobalColorInfo::~LLTexGlobalColorInfo() -{ - for_each(mColorInfoList.begin(), mColorInfoList.end(), DeletePointer()); -} - -BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node) -{ - // name attribute - static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); - if( !node->getFastAttributeString( name_string, mName ) ) - { - llwarns << " element is missing name attribute." << llendl; - return FALSE; - } - // sub-element - for (LLXmlTreeNode* child = node->getChildByName( "param" ); - child; - child = node->getNextNamedChild()) - { - if( child->getChildByName( "param_color" ) ) - { - // - LLTexParamColorInfo* info = new LLTexParamColorInfo(); - if (!info->parseXml(child)) - { - delete info; - return FALSE; - } - mColorInfoList.push_back( info ); - } - } - return TRUE; -} - -//----------------------------------------------------------------------------- -// LLTexGlobalColor -//----------------------------------------------------------------------------- - -LLTexGlobalColor::LLTexGlobalColor( LLVOAvatar* avatar ) - : - mAvatar( avatar ), - mInfo( NULL ) -{ -} - - -LLTexGlobalColor::~LLTexGlobalColor() -{ - // mParamList are LLViewerVisualParam's and get deleted with ~LLCharacter() - //std::for_each(mParamList.begin(), mParamList.end(), DeletePointer()); -} - -BOOL LLTexGlobalColor::setInfo(LLTexGlobalColorInfo *info) -{ - llassert(mInfo == NULL); - mInfo = info; - //mID = info->mID; // No ID - - LLTexGlobalColorInfo::color_info_list_t::iterator iter; - mParamList.reserve(mInfo->mColorInfoList.size()); - for (iter = mInfo->mColorInfoList.begin(); iter != mInfo->mColorInfoList.end(); iter++) - { - LLTexParamColor* param_color = new LLTexParamColor( this ); - if (!param_color->setInfo(*iter)) - { - mInfo = NULL; - return FALSE; - } - mParamList.push_back( param_color ); - } - - return TRUE; -} - -//----------------------------------------------------------------------------- - -LLColor4 LLTexGlobalColor::getColor() -{ - // Sum of color params - if( !mParamList.empty() ) - { - LLColor4 net_color( 0.f, 0.f, 0.f, 0.f ); - - for( param_list_t::iterator iter = mParamList.begin(); - iter != mParamList.end(); iter++ ) - { - LLTexParamColor* param = *iter; - LLColor4 param_net = param->getNetColor(); - switch( param->getOperation() ) - { - case OP_ADD: - net_color += param_net; - break; - case OP_MULTIPLY: - net_color.mV[VX] *= param_net.mV[VX]; - net_color.mV[VY] *= param_net.mV[VY]; - net_color.mV[VZ] *= param_net.mV[VZ]; - net_color.mV[VW] *= param_net.mV[VW]; - break; - case OP_BLEND: - net_color = lerp(net_color, param_net, param->getWeight()); - break; - default: - llassert(0); - break; - } - } - - net_color.mV[VX] = llclampf( net_color.mV[VX] ); - net_color.mV[VY] = llclampf( net_color.mV[VY] ); - net_color.mV[VZ] = llclampf( net_color.mV[VZ] ); - net_color.mV[VW] = llclampf( net_color.mV[VW] ); - - return net_color; - } - return LLColor4( 1.f, 1.f, 1.f, 1.f ); -} - -//----------------------------------------------------------------------------- -// LLTexParamColorInfo -//----------------------------------------------------------------------------- -LLTexParamColorInfo::LLTexParamColorInfo() - : - mOperation( OP_ADD ), - mNumColors( 0 ) -{ -} - -BOOL LLTexParamColorInfo::parseXml(LLXmlTreeNode *node) -{ - llassert( node->hasName( "param" ) && node->getChildByName( "param_color" ) ); - - if (!LLViewerVisualParamInfo::parseXml(node)) - return FALSE; - - LLXmlTreeNode* param_color_node = node->getChildByName( "param_color" ); - if( !param_color_node ) - { - return FALSE; - } - - std::string op_string; - static LLStdStringHandle operation_string = LLXmlTree::addAttributeString("operation"); - if( param_color_node->getFastAttributeString( operation_string, op_string ) ) - { - LLStringUtil::toLower(op_string); - if ( op_string == "add" ) mOperation = OP_ADD; - else if ( op_string == "multiply" ) mOperation = OP_MULTIPLY; - else if ( op_string == "blend" ) mOperation = OP_BLEND; - } - - mNumColors = 0; - - LLColor4U color4u; - for (LLXmlTreeNode* child = param_color_node->getChildByName( "value" ); - child; - child = param_color_node->getNextNamedChild()) - { - if( (mNumColors < MAX_COLOR_VALUES) ) - { - static LLStdStringHandle color_string = LLXmlTree::addAttributeString("color"); - if( child->getFastAttributeColor4U( color_string, color4u ) ) - { - mColors[ mNumColors ].setVec(color4u); - mNumColors++; - } - } - } - if( !mNumColors ) - { - llwarns << " is missing sub-elements" << llendl; - return FALSE; - } - - if( (mOperation == OP_BLEND) && (mNumColors != 1) ) - { - llwarns << " with operation\"blend\" must have exactly one " << llendl; - return FALSE; - } - - return TRUE; -} - -//----------------------------------------------------------------------------- -// LLTexParamColor -//----------------------------------------------------------------------------- -LLTexParamColor::LLTexParamColor( LLTexGlobalColor* tex_global_color ) - : - mAvgDistortionVec(1.f, 1.f, 1.f), - mTexGlobalColor( tex_global_color ), - mTexLayer( NULL ), - mAvatar( tex_global_color->getAvatar() ) -{ -} - -LLTexParamColor::LLTexParamColor( LLTexLayer* layer ) - : - mAvgDistortionVec(1.f, 1.f, 1.f), - mTexGlobalColor( NULL ), - mTexLayer( layer ), - mAvatar( layer->getTexLayerSet()->getAvatar() ) -{ -} - - -LLTexParamColor::~LLTexParamColor() -{ -} - -//----------------------------------------------------------------------------- -// setInfo() -//----------------------------------------------------------------------------- - -BOOL LLTexParamColor::setInfo(LLTexParamColorInfo *info) -{ - llassert(mInfo == NULL); - if (info->mID < 0) - return FALSE; - mID = info->mID; - mInfo = info; - - mAvatar->addVisualParam( this ); - setWeight( getDefaultWeight(), FALSE ); - - return TRUE; -} - -LLColor4 LLTexParamColor::getNetColor() -{ - llassert( getInfo()->mNumColors >= 1 ); - - F32 effective_weight = ( mAvatar && (mAvatar->getSex() & getSex()) ) ? mCurWeight : getDefaultWeight(); - - S32 index_last = getInfo()->mNumColors - 1; - F32 scaled_weight = effective_weight * index_last; - S32 index_start = (S32) scaled_weight; - S32 index_end = index_start + 1; - if( index_start == index_last ) - { - return getInfo()->mColors[index_last]; - } - else - { - F32 weight = scaled_weight - index_start; - const LLColor4 *start = &getInfo()->mColors[ index_start ]; - const LLColor4 *end = &getInfo()->mColors[ index_end ]; - return LLColor4( - (1.f - weight) * start->mV[VX] + weight * end->mV[VX], - (1.f - weight) * start->mV[VY] + weight * end->mV[VY], - (1.f - weight) * start->mV[VZ] + weight * end->mV[VZ], - (1.f - weight) * start->mV[VW] + weight * end->mV[VW] ); - } -} - -void LLTexParamColor::setWeight(F32 weight, BOOL set_by_user) -{ - if (mIsAnimating) - { - return; - } - F32 min_weight = getMinWeight(); - F32 max_weight = getMaxWeight(); - F32 new_weight = llclamp(weight, min_weight, max_weight); - U8 cur_u8 = F32_to_U8( mCurWeight, min_weight, max_weight ); - U8 new_u8 = F32_to_U8( new_weight, min_weight, max_weight ); - if( cur_u8 != new_u8) - { - mCurWeight = new_weight; - - if( getInfo()->mNumColors <= 0 ) - { - // This will happen when we set the default weight the first time. - return; - } - - if( mAvatar->getSex() & getSex() ) - { - if( mTexGlobalColor ) - { - mAvatar->onGlobalColorChanged( mTexGlobalColor, set_by_user ); - } - else - if( mTexLayer ) - { - mAvatar->invalidateComposite( mTexLayer->getTexLayerSet(), set_by_user ); - } - } -// llinfos << "param " << mName << " = " << new_weight << llendl; - } -} - -void LLTexParamColor::setAnimationTarget(F32 target_value, BOOL set_by_user) -{ - // set value first then set interpolating flag to ignore further updates - mTargetWeight = target_value; - setWeight(target_value, set_by_user); - mIsAnimating = TRUE; - if (mNext) - { - mNext->setAnimationTarget(target_value, set_by_user); - } -} - -void LLTexParamColor::animate(F32 delta, BOOL set_by_user) -{ - if (mNext) - { - mNext->animate(delta, set_by_user); - } -} - - -//----------------------------------------------------------------------------- -// LLTexStaticImageList -//----------------------------------------------------------------------------- - -// static -LLTexStaticImageList gTexStaticImageList; -LLStringTable LLTexStaticImageList::sImageNames(16384); - -LLTexStaticImageList::LLTexStaticImageList() - : - mGLBytes( 0 ), - mTGABytes( 0 ) -{} - -LLTexStaticImageList::~LLTexStaticImageList() +LLTexLayerStaticImageList::~LLTexLayerStaticImageList() { deleteCachedImages(); } -void LLTexStaticImageList::dumpByteCount() const +void LLTexLayerStaticImageList::dumpByteCount() const { llinfos << "Avatar Static Textures " << "KB GL:" << (mGLBytes / 1024) << "KB TGA:" << (mTGABytes / 1024) << "KB" << llendl; } -void LLTexStaticImageList::deleteCachedImages() +void LLTexLayerStaticImageList::deleteCachedImages() { if( mGLBytes || mTGABytes ) { @@ -2535,16 +1915,16 @@ void LLTexStaticImageList::deleteCachedImages() } } -// Note: in general, for a given image image we'll call either getImageTga() or getImageGL(). +// Note: in general, for a given image image we'll call either getImageTga() or getTexture(). // We call getImageTga() if the image is used as an alpha gradient. -// Otherwise, we call getImageGL() +// Otherwise, we call getTexture() // Returns an LLImageTGA that contains the encoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. -LLImageTGA* LLTexStaticImageList::getImageTGA(const std::string& file_name) +LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name) { - const char *namekey = sImageNames.addString(file_name); - image_tga_map_t::iterator iter = mStaticImageListTGA.find(namekey); + const char *namekey = mImageNames.addString(file_name); + image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey); if( iter != mStaticImageListTGA.end() ) { return iter->second; @@ -2567,14 +1947,12 @@ LLImageTGA* LLTexStaticImageList::getImageTGA(const std::string& file_name) } } - - // Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name. // Caches the result to speed identical subsequent requests. -LLViewerTexture* LLTexStaticImageList::getTexture(const std::string& file_name, BOOL is_mask) +LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask) { LLPointer tex; - const char *namekey = sImageNames.addString(file_name); + const char *namekey = mImageNames.addString(file_name); texture_map_t::const_iterator iter = mStaticImageList.find(namekey); if( iter != mStaticImageList.end() ) @@ -2612,7 +1990,7 @@ LLViewerTexture* LLTexStaticImageList::getTexture(const std::string& file_name, // Reads a .tga file, decodes it, and puts the decoded data in image_raw. // Returns TRUE if successful. -BOOL LLTexStaticImageList::loadImageRaw( const std::string& file_name, LLImageRaw* image_raw ) +BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw) { BOOL success = FALSE; std::string path; diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index ae3633c39..eae4ab1e0 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -34,524 +34,312 @@ #define LL_LLTEXLAYER_H #include -#include "llassetstorage.h" #include "lldynamictexture.h" -#include "llrect.h" -#include "llstring.h" -#include "lluuid.h" -#include "llviewertexture.h" -#include "llviewervisualparam.h" #include "llvoavatardefines.h" -#include "llwearable.h" -#include "v4color.h" -#include "llfloater.h" -#include "llvoavatar.h" +#include "lltexlayerparams.h" -class LLTexLayerSetInfo; -class LLTexLayerSet; -class LLTexLayerInfo; -class LLTexLayer; -class LLViewerTexture; -class LLImageTGA; -class LLTexGlobalColorInfo; -class LLTexLayerParamAlphaInfo; -class LLTexLayerParamAlpha; -class LLTexParamColorInfo; -class LLTexParamColor; -class LLPolyMesh; -class LLXmlTreeNode; -class LLImageRaw; -class LLPolyMorphTarget; -class LLViewerTexture; - -class LLTextureCtrl; class LLVOAvatar; +class LLVOAvatarSelf; +class LLImageTGA; +class LLImageRaw; +class LLXmlTreeNode; +class LLTexLayerSet; +class LLTexLayerSetInfo; +class LLTexLayerInfo; +class LLTexLayerSetBuffer; +class LLWearable; +class LLViewerVisualParam; +class LLPolyMorphTarget; - -enum EColorOperation +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerInterface +// +// Interface class to generalize functionality shared by LLTexLayer +// and LLTexLayerTemplate. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLTexLayerInterface { - OP_ADD = 0, - OP_MULTIPLY = 1, - OP_BLEND = 2, - OP_COUNT = 3 // Number of operations -}; - - -//----------------------------------------------------------------------------- -// LLTexLayerParamAlphaInfo -//----------------------------------------------------------------------------- -class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo -{ - friend class LLTexLayerParamAlpha; public: - LLTexLayerParamAlphaInfo(); - /*virtual*/ ~LLTexLayerParamAlphaInfo() {}; + enum ERenderPass + { + RP_COLOR, + RP_BUMP, + RP_SHINE + }; - /*virtual*/ BOOL parseXml(LLXmlTreeNode* node); + LLTexLayerInterface(LLTexLayerSet* const layer_set); + virtual ~LLTexLayerInterface() {} + + virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0; + virtual void deleteCaches() = 0; + virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0; + virtual BOOL isInvisibleAlphaMask() const = 0; + + const LLTexLayerInfo* getInfo() const { return mInfo; } + virtual BOOL setInfo(const LLTexLayerInfo *info); // sets mInfo, calls initialization functions + + const std::string& getName() const; + const LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; } + LLTexLayerSet* const getTexLayerSet() { return mTexLayerSet; } + + void invalidateMorphMasks(); + virtual void setHasMorph(BOOL newval) { mHasMorph = newval; } + BOOL hasMorph() const { return mHasMorph; } + BOOL isMorphValid() const { return mMorphMasksValid; } + void addMaskedMorph(LLPolyMorphTarget* morph_target, BOOL invert); + void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); + + void requestUpdate(); + virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0; + BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); } + + ERenderPass getRenderPass() const; + BOOL isVisibilityMask() const; protected: - std::string mStaticImageFileName; - BOOL mMultiplyBlend; - BOOL mSkipIfZeroWeight; - F32 mDomain; -}; + const std::string& getGlobalColor() const; + LLViewerVisualParam* getVisualParamPtr(S32 index) const; -//----------------------------------------------------------------------------- -// LLTexParamColorInfo -//----------------------------------------------------------------------------- -class LLTexParamColorInfo : public LLViewerVisualParamInfo -{ - friend class LLTexParamColor; - -public: - LLTexParamColorInfo(); - virtual ~LLTexParamColorInfo() {}; - BOOL parseXml( LLXmlTreeNode* node ); - protected: - enum { MAX_COLOR_VALUES = 20 }; - EColorOperation mOperation; - LLColor4 mColors[MAX_COLOR_VALUES]; - S32 mNumColors; -}; + LLTexLayerSet* const mTexLayerSet; + const LLTexLayerInfo* mInfo; + BOOL mMorphMasksValid; + BOOL mHasMorph; -//----------------------------------------------------------------------------- -// LLTexGlobalColorInfo -//----------------------------------------------------------------------------- -class LLTexGlobalColorInfo -{ - friend class LLTexGlobalColor; -public: - LLTexGlobalColorInfo(); - ~LLTexGlobalColorInfo(); - - BOOL parseXml(LLXmlTreeNode* node); + // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order. + param_color_list_t mParamColorList; + param_alpha_list_t mParamAlphaList; + // mGlobalColor name stored in mInfo + // mFixedColor value stored in mInfo -protected: - typedef std::vector color_info_list_t; - color_info_list_t mColorInfoList; - std::string mName; + typedef std::deque morph_list_t; //Hack. + morph_list_t mMaskedMorphs; }; -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayer +// +// A single texture layer. Only exists for llvoavatarself. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLTexLayer : public LLTexLayerInterface +{ +public: + LLTexLayer(LLTexLayerSet* const layer_set); + /*virtual*/ ~LLTexLayer(); + + /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info); // This sets mInfo and calls initialization functions + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); + + /*virtual*/ void deleteCaches(); + const U8* getAlphaData() const; + + BOOL findNetColor(LLColor4* color) const; + /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); + BOOL renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color); + void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height); + /*virtual*/ BOOL isInvisibleAlphaMask() const; + + + static void calculateTexLayerColor(const param_color_list_t ¶m_list, LLColor4 &net_color); +protected: + LLUUID getUUID() const; + LLPointer mStaticImageRaw; +private: + typedef std::map alpha_cache_t; + alpha_cache_t mAlphaCache; + BOOL mStaticImageInvalid; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerSet +// +// An ordered set of texture layers that gets composited into a single texture. +// Only exists for llvoavatarself. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLTexLayerSet +{ + friend class LLTexLayerSetBuffer; +public: + LLTexLayerSet(LLVOAvatarSelf* const avatar); + ~LLTexLayerSet(); + + const LLTexLayerSetInfo* getInfo() const { return mInfo; } + BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions + + BOOL render(S32 x, S32 y, S32 width, S32 height); + void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); + + BOOL isBodyRegion(const std::string& region) const; + LLTexLayerSetBuffer* getComposite(); + const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist. + void requestUpdate(); + void requestUpload(); + void cancelUpload(); + void updateComposite(); + BOOL isLocalTextureDataAvailable() const; + BOOL isLocalTextureDataFinal() const; + void createComposite(); + void destroyComposite(); + void setUpdatesEnabled(BOOL b); + BOOL getUpdatesEnabled() const { return mUpdatesEnabled; } + void deleteCaches(); + void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height); + void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); + BOOL isMorphValid() const; + void invalidateMorphMasks(); + LLTexLayerInterface* findLayerByName(const std::string& name); + + LLVOAvatarSelf* getAvatar() const { return mAvatar; } + const std::string getBodyRegionName() const; + BOOL hasComposite() const { return (mComposite.notNull()); } + LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } + void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } + BOOL isVisible() const { return mIsVisible; } + + static BOOL sHasCaches; + +private: + typedef std::vector layer_list_t; + layer_list_t mLayerList; + layer_list_t mMaskLayerList; + LLPointer mComposite; + LLVOAvatarSelf* const mAvatar; // note: backlink only; don't make this an LLPointer. + BOOL mUpdatesEnabled; + BOOL mIsVisible; + + LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex; + const LLTexLayerSetInfo* mInfo; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayerSetInfo -// Containes shared layer set data -//----------------------------------------------------------------------------- +// +// Contains shared layer set data. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerSetInfo { friend class LLTexLayerSet; public: LLTexLayerSetInfo(); ~LLTexLayerSetInfo(); - BOOL parseXml(LLXmlTreeNode* node); - -protected: +private: std::string mBodyRegion; S32 mWidth; S32 mHeight; std::string mStaticAlphaFileName; - BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName) - + BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName) typedef std::vector layer_info_list_t; layer_info_list_t mLayerInfoList; }; -//----------------------------------------------------------------------------- -// LLTexLayerInfo -//----------------------------------------------------------------------------- -enum ERenderPass -{ - RP_COLOR, - RP_BUMP, - RP_SHINE -}; - -class LLTexLayerInfo -{ - friend class LLTexLayer; -public: - LLTexLayerInfo(); - ~LLTexLayerInfo(); - - BOOL parseXml(LLXmlTreeNode* node); - -protected: - std::string mName; - - BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer, - ERenderPass mRenderPass; - - std::string mGlobalColor; - LLColor4 mFixedColor; - - S32 mLocalTexture; - std::string mStaticImageFileName; - BOOL mStaticImageIsMask; - BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask - BOOL mIsVisibilityMask; - - typedef std::vector > morph_name_list_t; - morph_name_list_t mMorphNameList; - - typedef std::vector color_info_list_t; - color_info_list_t mColorInfoList; - - typedef std::vector alpha_info_list_t; - alpha_info_list_t mAlphaInfoList; - -}; - -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLTexLayerSetBuffer +// // The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one. -//----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerSetBuffer : public LLViewerDynamicTexture { public: - LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 height); + LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height); virtual ~LLTexLayerSetBuffer(); +public: + /*virtual*/ S8 getType() const; + BOOL isInitialized(void) const; + static void dumpTotalByteCount(); + virtual void restoreGLTexture(); + virtual void destroyGLTexture(); +protected: + void pushProjection() const; + void popProjection() const; +private: + LLTexLayerSet* const mTexLayerSet; + static S32 sGLByteCount; + + //-------------------------------------------------------------------- + // Render + //-------------------------------------------------------------------- +public: + /*virtual*/ BOOL needsRender(); +protected: + BOOL render(S32 x, S32 y, S32 width, S32 height); virtual void preRender(BOOL clear_depth); virtual void postRender(BOOL success); - virtual BOOL render(); - BOOL updateImmediate(); - bool isInitialized(void) const; - BOOL needsRender(); - void requestUpdate(); + virtual BOOL render(); + + //-------------------------------------------------------------------- + // Uploads + //-------------------------------------------------------------------- +public: void requestUpload(); void requestDelayedUpload(U64 delay_usec); - void cancelUpload(); - BOOL uploadPending() { return mUploadPending; } - BOOL render( S32 x, S32 y, S32 width, S32 height ); - void readBackAndUpload(); - - static void onTextureUploadComplete( const LLUUID& uuid, - void* userdata, - S32 result, LLExtStat ext_status); - static void dumpTotalByteCount(); - - virtual S8 getType() const ; - virtual void restoreGLTexture() ; - virtual void destroyGLTexture() ; - -private: - void pushProjection(); - void popProjection(); BOOL needsUploadNow() const; - -private: - BOOL mNeedsUpdate; - BOOL mNeedsUpload; - BOOL mUploadPending; - LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit) - S32 mUploadFailCount; - U64 mUploadAfter; // delay upload until after this time (in microseconds) - LLTexLayerSet* mTexLayerSet; - - static S32 sGLByteCount; -}; - -//----------------------------------------------------------------------------- -// LLTexLayerSet -// An ordered set of texture layers that get composited into a single texture. -//----------------------------------------------------------------------------- -class LLTexLayerSet -{ - friend class LLTexLayerSetBuffer; -public: - LLTexLayerSet( LLVOAvatarSelf* avatar ); - ~LLTexLayerSet(); - - //BOOL parseData(LLXmlTreeNode* node); - LLTexLayerSetInfo* getInfo() const { return mInfo; } - // This sets mInfo and calls initialization functions - BOOL setInfo(LLTexLayerSetInfo *info); - - BOOL render( S32 x, S32 y, S32 width, S32 height ); - void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); - BOOL isBodyRegion( const std::string& region ) { return mInfo->mBodyRegion == region; } - LLTexLayerSetBuffer* getComposite(); - void requestUpdate(); - void requestUpload(); void cancelUpload(); - LLVOAvatarSelf* getAvatar() { return mAvatar; } - void updateComposite(); - BOOL isLocalTextureDataAvailable(); - BOOL isLocalTextureDataFinal(); - void createComposite(); - void destroyComposite(); - void setUpdatesEnabled( BOOL b ); - BOOL getUpdatesEnabled() { return mUpdatesEnabled; } - void deleteCaches(); - void gatherAlphaMasks(U8 *data, S32 width, S32 height); - void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); - const std::string getBodyRegion() { return mInfo->mBodyRegion; } - BOOL hasComposite() { return (mComposite.notNull()); } - LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } - void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } - BOOL isVisible() const { return mIsVisible; } + BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point + static void onTextureUploadComplete(const LLUUID& uuid, + void* userdata, + S32 result, LLExtStat ext_status); + void doUpload(); // Does a read back and upload. +private: + + BOOL mNeedsUpload; // Whether we need to send our baked textures to the server + BOOL mUploadPending; // Whether we have received back the new baked textures + LLUUID mUploadID; // The current upload process (null if none). + S32 mUploadFailCount; // Number of consecutive upload failures + BOOL mNeedsUpdate; + U64 mUploadAfter; // delay upload until after this time (in microseconds) + //-------------------------------------------------------------------- + // Updates + //-------------------------------------------------------------------- public: - static BOOL sHasCaches; - -protected: - typedef std::vector layer_list_t; - layer_list_t mLayerList; - layer_list_t mMaskLayerList; - LLPointer mComposite; - // Backlink only; don't make this an LLPointer. - LLVOAvatarSelf* mAvatar; - BOOL mUpdatesEnabled; - BOOL mIsVisible; - - LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex; - - LLTexLayerSetInfo *mInfo; -}; - -//----------------------------------------------------------------------------- -// LLTexLayer -// A single texture layer -//----------------------------------------------------------------------------- -class LLTexLayer -{ -public: - LLTexLayer( LLTexLayerSet* layer_set ); - ~LLTexLayer(); - - //BOOL parseData(LLXmlTreeNode* node); - LLTexLayerInfo* getInfo() const { return mInfo; } - // This sets mInfo and calls initialization functions - BOOL setInfo(LLTexLayerInfo *info); - - BOOL render( S32 x, S32 y, S32 width, S32 height ); void requestUpdate(); - LLTexLayerSet* getTexLayerSet() { return mTexLayerSet; } - - const std::string& getName() { return mInfo->mName; } - - void addMaskedMorph(LLPolyMorphTarget* morph_target, BOOL invert); - void deleteCaches(); - U8* getAlphaData(); - void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); - - void invalidateMorphMasks(); - ERenderPass getRenderPass() { return mInfo->mRenderPass; } - const std::string& getGlobalColor() { return mInfo->mGlobalColor; } - BOOL findNetColor( LLColor4* color ); - BOOL renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask ); - BOOL renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp ); - BOOL hasAlphaParams() { return (!mParamAlphaList.empty());} - BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); - BOOL isVisibilityMask() const; - BOOL isInvisibleAlphaMask(); - -protected: - LLTexLayerSet* mTexLayerSet; - LLPointer mStaticImageRaw; - - // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order. - typedef std::vector color_list_t; - color_list_t mParamColorList; - // mGlobalColor name stored in mInfo - // mFixedColor value stored in mInfo - - typedef std::vector alpha_list_t; - alpha_list_t mParamAlphaList; - - - typedef std::deque morph_list_t; - morph_list_t mMaskedMorphs; - typedef std::map alpha_cache_t; - alpha_cache_t mAlphaCache; - BOOL mMorphMasksValid; - BOOL mStaticImageInvalid; - - LLTexLayerInfo *mInfo; + BOOL requestUpdateImmediate(); }; -//----------------------------------------------------------------------------- -// LLTexLayerParamAlpha -//----------------------------------------------------------------------------- -class LLTexLayerParamAlpha : public LLViewerVisualParam +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerStaticImageList +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLTexLayerStaticImageList : public LLSingleton { public: - LLTexLayerParamAlpha( LLTexLayer* layer ); - /*virtual*/ ~LLTexLayerParamAlpha(); - - // Special: These functions are overridden by child classes - LLTexLayerParamAlphaInfo* getInfo() const { return (LLTexLayerParamAlphaInfo*)mInfo; } - // This sets mInfo and calls initialization functions - BOOL setInfo(LLTexLayerParamAlphaInfo *info); - - // LLVisualParam Virtual functions - ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); - /*virtual*/ void apply( ESex avatar_sex ) {} - /*virtual*/ void setWeight(F32 weight, BOOL set_by_user); - /*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user); - /*virtual*/ void animate(F32 delta, BOOL set_by_user); - - // LLViewerVisualParam Virtual functions - /*virtual*/ F32 getTotalDistortion() { return 1.f; } - /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; } - /*virtual*/ F32 getMaxDistortion() { return 3.f; } - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);} - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; - - // New functions - BOOL render( S32 x, S32 y, S32 width, S32 height ); - BOOL getSkip(); - void deleteCaches(); - LLTexLayer* getTexLayer() { return mTexLayer; } - BOOL getMultiplyBlend() { return getInfo()->mMultiplyBlend; } - -protected: - LLPointer mCachedProcessedTexture; - LLTexLayer* mTexLayer; - LLPointer mStaticImageTGA; - LLPointer mStaticImageRaw; - BOOL mNeedsCreateTexture; - BOOL mStaticImageInvalid; - LLVector3 mAvgDistortionVec; - F32 mCachedEffectiveWeight; - -public: - // Global list of instances for gathering statistics - static void dumpCacheByteCount(); - static void getCacheByteCount( S32* gl_bytes ); - - typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t; - static param_alpha_ptr_list_t sInstances; -}; - - -//----------------------------------------------------------------------------- -// LLTexGlobalColor -//----------------------------------------------------------------------------- -class LLTexGlobalColor -{ -public: - LLTexGlobalColor( LLVOAvatar* avatar ); - ~LLTexGlobalColor(); - - //BOOL parseData(LLXmlTreeNode* node); - LLTexGlobalColorInfo* getInfo() const { return mInfo; } - // This sets mInfo and calls initialization functions - BOOL setInfo(LLTexGlobalColorInfo *info); - - void requstUpdate(); - LLVOAvatar* getAvatar() { return mAvatar; } - LLColor4 getColor(); - const std::string& getName() { return mInfo->mName; } - -protected: - typedef std::vector param_list_t; - param_list_t mParamList; - LLVOAvatar* mAvatar; // just backlink, don't LLPointer - - LLTexGlobalColorInfo *mInfo; -}; - - -//----------------------------------------------------------------------------- -// LLTexParamColor -//----------------------------------------------------------------------------- -class LLTexParamColor : public LLViewerVisualParam -{ -public: - LLTexParamColor( LLTexGlobalColor* tex_color ); - LLTexParamColor( LLTexLayer* layer ); - /* virtual */ ~LLTexParamColor(); - - // Special: These functions are overridden by child classes - LLTexParamColorInfo* getInfo() const { return (LLTexParamColorInfo*)mInfo; } - // This sets mInfo and calls initialization functions - BOOL setInfo(LLTexParamColorInfo *info); - - // LLVisualParam Virtual functions - ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); - /*virtual*/ void apply( ESex avatar_sex ) {} - /*virtual*/ void setWeight(F32 weight, BOOL set_by_user); - /*virtual*/ void setAnimationTarget(F32 target_value, BOOL set_by_user); - /*virtual*/ void animate(F32 delta, BOOL set_by_user); - - - // LLViewerVisualParam Virtual functions - /*virtual*/ F32 getTotalDistortion() { return 1.f; } - /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; } - /*virtual*/ F32 getMaxDistortion() { return 3.f; } - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); } - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; - - // New functions - LLColor4 getNetColor(); - EColorOperation getOperation() const { return getInfo()->mOperation; } - - -protected: - LLVector3 mAvgDistortionVec; - LLTexGlobalColor* mTexGlobalColor; // either has mTexGlobalColor or mTexLayer as its parent - LLTexLayer* mTexLayer; - LLVOAvatar* mAvatar; // redundant, but simplifies the code (don't LLPointer) -}; - -//----------------------------------------------------------------------------- -// LLTexStaticImageList -//----------------------------------------------------------------------------- - -class LLTexStaticImageList -{ -public: - LLTexStaticImageList(); - ~LLTexStaticImageList(); - - LLImageRaw* getImageRaw( const std::string& file_name ); - LLViewerTexture* getTexture( const std::string& file_name, BOOL is_mask ); - LLImageTGA* getImageTGA( const std::string& file_name ); - + LLTexLayerStaticImageList(); + ~LLTexLayerStaticImageList(); + LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask); + LLImageTGA* getImageTGA(const std::string& file_name); void deleteCachedImages(); void dumpByteCount() const; protected: BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw); - private: - static LLStringTable sImageNames; - + LLStringTable mImageNames; typedef std::map > texture_map_t; texture_map_t mStaticImageList; typedef std::map > image_tga_map_t; image_tga_map_t mStaticImageListTGA; -public: S32 mGLBytes; S32 mTGABytes; }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLBakedUploadData +// // Used by LLTexLayerSetBuffer for a callback. - -// For DEV-DEV-31590, "Heap corruption and crash after outfit -// changes", added the mLayerSet member. The current -// LLTexLayerSetBuffer can be found by querying mLayerSet->mComposite, -// but we still store the original mLayerSetBuffer here so we can -// detect when an upload is out of date. This prevents a memory -// stomp. See LLTexLayerSetBuffer::onTextureUploadComplete() for usage. -class LLBakedUploadData +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +struct LLBakedUploadData { -public: - LLBakedUploadData( LLVOAvatarSelf* avatar, LLTexLayerSet* layerset, LLTexLayerSetBuffer* layerset_buffer, const LLUUID & id); + LLBakedUploadData(const LLVOAvatarSelf* avatar, + LLTexLayerSet* layerset, + const LLUUID& id); ~LLBakedUploadData() {} + const LLUUID mID; + const LLVOAvatarSelf* mAvatar; // note: backlink only; don't LLPointer + LLTexLayerSet* mTexLayerSet; - LLUUID mID; - LLVOAvatarSelf* mAvatar; // just backlink, don't LLPointer - LLTexLayerSet* mTexLayerSet; - LLTexLayerSetBuffer* mLayerSetBuffer; - LLUUID mWearableAssets[LLWearableType::WT_COUNT]; - U64 mStartTime; // Used to measure time baked texture upload requires + const U64 mStartTime; // for measuring baked texture upload time }; -extern LLTexStaticImageList gTexStaticImageList; - - #endif // LL_LLTEXLAYER_H diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp index ee6e534d2..8fb17e0c2 100644 --- a/indra/newview/lltexlayerparams.cpp +++ b/indra/newview/lltexlayerparams.cpp @@ -145,13 +145,6 @@ LLTexLayerParamAlpha::~LLTexLayerParamAlpha() sInstances.remove(this); } -/*virtual*/ LLViewerVisualParam* LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const -{ - LLTexLayerParamAlpha *new_param = new LLTexLayerParamAlpha(mTexLayer); - *new_param = *this; - return new_param; -} - void LLTexLayerParamAlpha::deleteCaches() { mStaticImageTGA = NULL; // deletes image @@ -188,6 +181,7 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake) } mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); mTexLayer->invalidateMorphMasks(); + mAvatar->updateMeshTextures(); } } } @@ -323,14 +317,14 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) // Create the GL texture, and then hang onto it for future use. if (mNeedsCreateTexture) { - mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw); + mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw, 0, TRUE, LLViewerTexture::BOOST_AVATAR_SELF); mNeedsCreateTexture = FALSE; gGL.getTexUnit(0)->bind(mCachedProcessedTexture); mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP); } LLGLSNoAlphaTest gls_no_alpha_test; - gGL.getTexUnit(0)->bind(mCachedProcessedTexture); + gGL.getTexUnit(0)->bind(mCachedProcessedTexture, TRUE); gl_rect_2d_simple_tex(width, height); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); @@ -419,12 +413,6 @@ LLTexLayerParamColor::~LLTexLayerParamColor() { } -/*virtual*/ LLViewerVisualParam* LLTexLayerParamColor::cloneParam(LLWearable* wearable) const -{ - LLTexLayerParamColor *new_param = new LLTexLayerParamColor(mTexLayer); - *new_param = *this; - return new_param; -} LLColor4 LLTexLayerParamColor::getNetColor() const { @@ -521,7 +509,7 @@ LLTexLayerParamColorInfo::LLTexLayerParamColorInfo() : BOOL LLTexLayerParamColorInfo::parseXml(LLXmlTreeNode *node) { - llassert(node->hasName("param") && node->getChildByName("param_color")); + llassert( node->hasName( "param" ) && node->getChildByName( "param_color" ) ); if (!LLViewerVisualParamInfo::parseXml(node)) return FALSE; diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h new file mode 100644 index 000000000..c8ae2017c --- /dev/null +++ b/indra/newview/lltexlayerparams.h @@ -0,0 +1,187 @@ +/** + * @file lltexlayerparams.h + * @brief Texture layer parameters, used by lltexlayer. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLTEXLAYERPARAMS_H +#define LL_LLTEXLAYERPARAMS_H + +#include "llviewervisualparam.h" + +class LLImageRaw; +class LLImageTGA; +class LLTexLayer; +class LLTexLayerInterface; +class LLViewerTexture; +class LLVOAvatar; +class LLWearable; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerParam +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLTexLayerParam : public LLViewerVisualParam +{ +public: + LLTexLayerParam(LLTexLayerInterface *layer); + LLTexLayerParam(LLVOAvatar *avatar); + /*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar ); +protected: + LLTexLayerInterface* mTexLayer; + LLVOAvatar* mAvatar; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerParamAlpha +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLTexLayerParamAlpha : public LLTexLayerParam +{ +public: + LLTexLayerParamAlpha( LLTexLayerInterface* layer ); + LLTexLayerParamAlpha( LLVOAvatar* avatar ); + /*virtual*/ ~LLTexLayerParamAlpha(); + + // LLVisualParam Virtual functions + ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); + /*virtual*/ void apply( ESex avatar_sex ) {} + /*virtual*/ void setWeight(F32 weight, BOOL upload_bake); + /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake); + /*virtual*/ void animate(F32 delta, BOOL upload_bake); + + // LLViewerVisualParam Virtual functions + /*virtual*/ F32 getTotalDistortion() { return 1.f; } + /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; } + /*virtual*/ F32 getMaxDistortion() { return 3.f; } + /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);} + /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; + /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; + + // New functions + BOOL render( S32 x, S32 y, S32 width, S32 height ); + BOOL getSkip() const; + void deleteCaches(); + BOOL getMultiplyBlend() const; + +private: + LLPointer mCachedProcessedTexture; + LLPointer mStaticImageTGA; + LLPointer mStaticImageRaw; + BOOL mNeedsCreateTexture; + BOOL mStaticImageInvalid; + LLVector3 mAvgDistortionVec; + F32 mCachedEffectiveWeight; + +public: + // Global list of instances for gathering statistics + static void dumpCacheByteCount(); + static void getCacheByteCount( S32* gl_bytes ); + + typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t; + static param_alpha_ptr_list_t sInstances; +}; +class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo +{ + friend class LLTexLayerParamAlpha; +public: + LLTexLayerParamAlphaInfo(); + /*virtual*/ ~LLTexLayerParamAlphaInfo() {}; + + /*virtual*/ BOOL parseXml(LLXmlTreeNode* node); + +private: + std::string mStaticImageFileName; + BOOL mMultiplyBlend; + BOOL mSkipIfZeroWeight; + F32 mDomain; +}; +// +// LLTexLayerParamAlpha +//----------------------------------------------------------------------------- + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// LLTexLayerParamColor +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLTexLayerParamColor : public LLTexLayerParam +{ +public: + enum EColorOperation + { + OP_ADD = 0, + OP_MULTIPLY = 1, + OP_BLEND = 2, + OP_COUNT = 3 // Number of operations + }; + + LLTexLayerParamColor( LLTexLayerInterface* layer ); + LLTexLayerParamColor( LLVOAvatar* avatar ); + /* virtual */ ~LLTexLayerParamColor(); + + // LLVisualParam Virtual functions + ///*virtual*/ BOOL parseData(LLXmlTreeNode* node); + /*virtual*/ void apply( ESex avatar_sex ) {} + /*virtual*/ void setWeight(F32 weight, BOOL upload_bake); + /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake); + /*virtual*/ void animate(F32 delta, BOOL upload_bake); + + + // LLViewerVisualParam Virtual functions + /*virtual*/ F32 getTotalDistortion() { return 1.f; } + /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; } + /*virtual*/ F32 getMaxDistortion() { return 3.f; } + /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); } + /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; + /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; + + // New functions + LLColor4 getNetColor() const; +protected: + virtual void onGlobalColorChanged(bool upload_bake) {} +private: + LLVector3 mAvgDistortionVec; +}; + +class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo +{ + friend class LLTexLayerParamColor; + +public: + LLTexLayerParamColorInfo(); + virtual ~LLTexLayerParamColorInfo() {}; + BOOL parseXml( LLXmlTreeNode* node ); + LLTexLayerParamColor::EColorOperation getOperation() const { return mOperation; } +private: + enum { MAX_COLOR_VALUES = 20 }; + LLTexLayerParamColor::EColorOperation mOperation; + LLColor4 mColors[MAX_COLOR_VALUES]; + S32 mNumColors; +}; + +typedef std::vector param_color_list_t; +typedef std::vector param_alpha_list_t; +typedef std::vector param_color_info_list_t; +typedef std::vector param_alpha_info_list_t; + +#endif diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 7a7cd1660..3940662c7 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -45,6 +45,7 @@ #include "llviewerobjectlist.h" #include "llviewertexturelist.h" #include "lltexlayer.h" +#include "lltexlayerparams.h" #include "llsurface.h" #include "llvlmanager.h" #include "llagent.h" @@ -525,7 +526,7 @@ void output_statistics(void*) llinfos << "--------------------------------" << llendl; llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl; - gTexStaticImageList.dumpByteCount(); + LLTexLayerStaticImageList::getInstance()->dumpByteCount(); LLVOAvatarSelf::dumpScratchTextureByteCount(); LLTexLayerSetBuffer::dumpTotalByteCount(); LLVOAvatarSelf::dumpTotalLocalTextureByteCount(); diff --git a/indra/newview/llviewervisualparam.cpp b/indra/newview/llviewervisualparam.cpp index 733fd485e..07d83326b 100644 --- a/indra/newview/llviewervisualparam.cpp +++ b/indra/newview/llviewervisualparam.cpp @@ -119,12 +119,6 @@ LLViewerVisualParam::LLViewerVisualParam() { } -/* -//============================================================================= -// These virtual functions should always be overridden, -// but are included here for use as templates -//============================================================================= - //----------------------------------------------------------------------------- // setInfo() //----------------------------------------------------------------------------- @@ -139,7 +133,7 @@ BOOL LLViewerVisualParam::setInfo(LLViewerVisualParamInfo *info) setWeight(getDefaultWeight(), FALSE ); return TRUE; } - +/* //----------------------------------------------------------------------------- // parseData() //----------------------------------------------------------------------------- diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h index 48d28cebf..77a95db56 100644 --- a/indra/newview/llviewervisualparam.h +++ b/indra/newview/llviewervisualparam.h @@ -90,7 +90,7 @@ public: virtual const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0; // interface methods - F32 getDisplayOrder() { return getInfo()->mEditGroupDisplayOrder; } + F32 getDisplayOrder() const { return getInfo()->mEditGroupDisplayOrder; } S32 getWearableType() const { return getInfo()->mWearableType; } const std::string& getEditGroup() const { return getInfo()->mEditGroup; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 19ee949c6..a28282a3e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1131,7 +1131,7 @@ void LLVOAvatar::deleteCachedImages(bool clearAll) } LLVOAvatarSelf::deleteScratchTextures(); - gTexStaticImageList.deleteCachedImages(); + LLTexLayerStaticImageList::getInstance()->deleteCachedImages(); } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 6dafdcac1..b7fd8755b 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -49,6 +49,7 @@ #include "llrendertarget.h" #include "llwearable.h" #include "llvoavatardefines.h" +#include "lltexglobalcolor.h" #include "emeraldboobutils.h" #include "llavatarname.h" From 06349951d236f2049d5d3c57ead5faf3a213ef16 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 27 Oct 2011 21:41:19 -0500 Subject: [PATCH 3/7] Added tracking of requested(and pending) attachments. Moved Ascent code out of attach/detach functions and into their own for better manageability. --- indra/newview/llinventorybridge.cpp | 18 +- indra/newview/llvoavatarself.cpp | 272 +++++++++++++++++++++------- indra/newview/llvoavatarself.h | 22 +++ 3 files changed, 240 insertions(+), 72 deletions(-) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 132470685..7348b92d4 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4151,9 +4151,20 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach attachment = RlvAttachPtLookup::getAttachPoint(item); } // [/RLVa:KB] + const LLUUID& item_id = item->getLinkedUUID(); + + // Check for duplicate request. + if (isAgentAvatarValid() && + (gAgentAvatarp->attachmentWasRequested(item_id) || + gAgentAvatarp->isWearingAttachment(item_id))) + { + llwarns << "duplicate attachment request, ignoring" << llendl; + return; + } + gAgentAvatarp->addAttachmentRequest(item_id); S32 attach_pt = 0; - if (gAgentAvatarp && attachment) + if (isAgentAvatarValid() && attachment) { for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter) @@ -4167,11 +4178,12 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach } LLSD payload; - payload["item_id"] = item->getLinkedUUID(); // Wear the base object in case this is a link. + payload["item_id"] = item_id; // Wear the base object in case this is a link. payload["attachment_point"] = attach_pt; payload["is_add"] = !replace; - if (replace && attachment && attachment->getNumObjects() > 0) + if (replace && + (attachment && attachment->getNumObjects() > 0)) { // [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a // Block if we can't "replace wear" what's currently there diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 441bea7f9..8279a5efc 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -459,12 +459,86 @@ void LLVOAvatarSelf::resetJointPositions( void ) { return LLVOAvatar::resetJointPositions(); } +// virtual +BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake ) +{ + if (!which_param) + { + return FALSE; + } + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(which_param->getID()); + return setParamWeight(param,weight,upload_bake); +} + +// virtual +BOOL LLVOAvatarSelf::setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake ) +{ + if (!param_name) + { + return FALSE; + } + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(param_name); + return setParamWeight(param,weight,upload_bake); +} + +// virtual +BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake ) +{ + LLViewerVisualParam *param = (LLViewerVisualParam*) LLCharacter::getVisualParam(index); + return setParamWeight(param,weight,upload_bake); +} + +BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake ) +{ + if (!param) + { + return FALSE; + } + + /*if (param->getCrossWearable()) + { + LLWearableType::EType type = (LLWearableType::EType)param->getWearableType(); + U32 size = gAgentWearables.getWearableCount(type); + for (U32 count = 0; count < size; ++count) + { + LLWearable *wearable = gAgentWearables.getWearable(type,count); + if (wearable) + { + wearable->setVisualParamWeight(param->getID(), weight, upload_bake); + } + } + }*/ + + return LLCharacter::setVisualParamWeight(param,weight,upload_bake); +} /*virtual*/ void LLVOAvatarSelf::updateVisualParams() { LLVOAvatar::updateVisualParams(); } + +/*virtual*/ +void LLVOAvatarSelf::idleUpdateAppearanceAnimation() +{ + // Animate all top-level wearable visual parameters + /*gAgentWearables.animateAllWearableParams(calcMorphAmount(), FALSE); + + // apply wearable visual params to avatar + for (U32 type = 0; type < LLWearableType::WT_COUNT; type++) + { + LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type); + if (wearable) + { + wearable->writeToAvatar(); + } + }*/ + + //allow avatar to process updates + LLVOAvatar::idleUpdateAppearanceAnimation(); + +} + // virtual void LLVOAvatarSelf::requestStopMotion(LLMotion* motion) { @@ -813,19 +887,44 @@ BOOL LLVOAvatarSelf::isWearingAttachment( const LLUUID& inv_item_id ) const return FALSE; } -// testzone attachpt -BOOL LLVOAvatarSelf::isWearingUnsupportedAttachment( const LLUUID& inv_item_id ) +//----------------------------------------------------------------------------- +BOOL LLVOAvatarSelf::attachmentWasRequested(const LLUUID& inv_item_id) const { - std::map >::iterator end = mUnsupportedAttachmentPoints.end(); - for(std::map >::iterator iter = mUnsupportedAttachmentPoints.begin(); iter != end; ++iter) + const F32 REQUEST_EXPIRATION_SECONDS = 5.0; // any request older than this is ignored/removed. + std::map::iterator it = mAttachmentRequests.find(inv_item_id); + if (it != mAttachmentRequests.end()) { - if((*iter).second.first == inv_item_id) + const LLTimer& request_time = it->second; + F32 request_time_elapsed = request_time.getElapsedTimeF32(); + if (request_time_elapsed > REQUEST_EXPIRATION_SECONDS) + { + mAttachmentRequests.erase(it); + return FALSE; + } + else { return TRUE; } } - return FALSE; + else + { + return FALSE; + } } + +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::addAttachmentRequest(const LLUUID& inv_item_id) +{ + LLTimer current_time; + mAttachmentRequests[inv_item_id] = current_time; +} + +//----------------------------------------------------------------------------- +void LLVOAvatarSelf::removeAttachmentRequest(const LLUUID& inv_item_id) +{ + mAttachmentRequests.erase(inv_item_id); +} + //----------------------------------------------------------------------------- // getWornAttachment() //----------------------------------------------------------------------------- @@ -882,49 +981,24 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view const LLViewerJointAttachment *attachment = LLVOAvatar::attachObject(viewer_object); if(!attachment) { - // testzone attachpt - S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState()); - LLUUID item_id; - LLNameValue* item_id_nv = viewer_object->getNVPair("AttachItemID"); - if( item_id_nv ) - { - const char* s = item_id_nv->getString(); - if(s) - item_id.set(s); - } - if(!item_id.isNull()) - { - mUnsupportedAttachmentPoints[attachmentID] = std::pair(item_id,viewer_object->getID()); - if (viewer_object->isSelected()) - { - LLSelectMgr::getInstance()->updateSelectionCenter(); - LLSelectMgr::getInstance()->updatePointAt(); - } - - updateAttachmentVisibility(gAgentCamera.getCameraMode()); - - // Then make sure the inventory is in sync with the avatar. - gInventory.addChangedMask( LLInventoryObserver::LABEL, item_id ); - gInventory.notifyObservers(); - } - else - llwarns << "No item ID" << llendl; - // +// + addUnsupportedAttachment(viewer_object); +// return 0; } updateAttachmentVisibility(gAgentCamera.getCameraMode()); // [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a - // NOTE: RLVa event handlers should be invoked *after* LLVOAvatar::attachObject() calls LLViewerJointAttachment::addObject() - if (rlv_handler_t::isEnabled()) - { - RlvAttachmentLockWatchdog::instance().onAttach(viewer_object, attachment); - gRlvHandler.onAttach(viewer_object, attachment); + // NOTE: RLVa event handlers should be invoked *after* LLVOAvatar::attachObject() calls LLViewerJointAttachment::addObject() + if (rlv_handler_t::isEnabled()) + { + RlvAttachmentLockWatchdog::instance().onAttach(viewer_object, attachment); + gRlvHandler.onAttach(viewer_object, attachment); - if ( (attachment->getIsHUDAttachment()) && (!gRlvAttachmentLocks.hasLockedHUD()) ) - gRlvAttachmentLocks.updateLockedHUD(); - } + if ( (attachment->getIsHUDAttachment()) && (!gRlvAttachmentLocks.hasLockedHUD()) ) + gRlvAttachmentLocks.updateLockedHUD(); + } // [/RLVa:KB] // Then make sure the inventory is in sync with the avatar. @@ -934,7 +1008,10 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view // Should just be the last object added if (attachment->isObjectAttached(viewer_object)) { - LLCOFMgr::instance().addAttachment(viewer_object->getAttachmentItemID()); + const LLUUID& attachment_id = viewer_object->getAttachmentItemID(); + LLCOFMgr::instance().addAttachment(attachment_id); + // Clear any pending requests once the attachment arrives. + removeAttachmentRequest(attachment_id); updateLODRiggedAttachments(); } @@ -990,7 +1067,82 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) } return TRUE; } - // testzone attachpt + +// + if(removeUnsupportedAttachment(viewer_object)) + return TRUE; +// + + + return FALSE; +} + +// static +BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id) +{ + LLInventoryItem* item = gInventory.getLinkedItem(item_id); + if ( (item) && (gAgentAvatarp) && (!gAgentAvatarp->isWearingAttachment(item->getUUID())) ) + { + LLCOFMgr::instance().removeAttachment(item->getUUID()); + return FALSE; + } +// if (item) +// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1c) | Added: RLVa-1.2.1c + if ( (item) && ((!rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(item))) ) +// [/RLVa:KB] + { + gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); + gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); + + // This object might have been selected, so let the selection manager know it's gone now + LLViewerObject *found_obj = gObjectList.findObject(item_id); + if (found_obj) + { + LLSelectMgr::getInstance()->remove(found_obj); + } + + return TRUE; + } + return FALSE; +} + +// testzone attachpt +void LLVOAvatarSelf::addUnsupportedAttachment(LLViewerObject *viewer_object) +{ + + S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState()); + LLUUID item_id; + LLNameValue* item_id_nv = viewer_object->getNVPair("AttachItemID"); + if( item_id_nv ) + { + const char* s = item_id_nv->getString(); + if(s) + item_id.set(s); + } + if(!item_id.isNull()) + { + mUnsupportedAttachmentPoints[attachmentID] = std::pair(item_id,viewer_object->getID()); + if (viewer_object->isSelected()) + { + LLSelectMgr::getInstance()->updateSelectionCenter(); + LLSelectMgr::getInstance()->updatePointAt(); + } + + updateAttachmentVisibility(gAgentCamera.getCameraMode()); + + // Then make sure the inventory is in sync with the avatar. + gInventory.addChangedMask( LLInventoryObserver::LABEL, item_id ); + gInventory.notifyObservers(); + } + else + llwarns << "No item ID" << llendl; + +} +bool LLVOAvatarSelf::removeUnsupportedAttachment(LLViewerObject *viewer_object) +{ LLUUID item_id; LLNameValue* item_id_nv = viewer_object->getNVPair("AttachItemID"); if( item_id_nv ) @@ -1037,40 +1189,22 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) { llwarns << "No item ID" << llendl; } - // return FALSE; } -BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id) +BOOL LLVOAvatarSelf::isWearingUnsupportedAttachment( const LLUUID& inv_item_id ) { - LLInventoryItem* item = gInventory.getLinkedItem(item_id); - if ( (item) && (gAgentAvatarp) && (!gAgentAvatarp->isWearingAttachment(item->getUUID())) ) + std::map >::iterator end = mUnsupportedAttachmentPoints.end(); + for(std::map >::iterator iter = mUnsupportedAttachmentPoints.begin(); iter != end; ++iter) { - LLCOFMgr::instance().removeAttachment(item->getUUID()); - return FALSE; - } -// if (item) -// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1c) | Added: RLVa-1.2.1c - if ( (item) && ((!rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(item))) ) -// [/RLVa:KB] - { - gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); - gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); - - // This object might have been selected, so let the selection manager know it's gone now - LLViewerObject *found_obj = gObjectList.findObject(item_id); - if (found_obj) + if((*iter).second.first == inv_item_id) { - LLSelectMgr::getInstance()->remove(found_obj); + return TRUE; } - - return TRUE; } return FALSE; } - +// + U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const { LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index fb0003553..c56d83b00 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -83,7 +83,15 @@ public: void resetJointPositions( void ); + /*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); + /*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE ); + /*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE ); /*virtual*/ void updateVisualParams(); + /*virtual*/ void idleUpdateAppearanceAnimation(); + +private: + // helper function. Passed in param is assumed to be in avatar's parameter list. + BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE ); /** Initialization @@ -259,17 +267,31 @@ protected: public: void updateAttachmentVisibility(U32 camera_mode); BOOL isWearingAttachment(const LLUUID& inv_item_id) const; + BOOL attachmentWasRequested(const LLUUID& inv_item_id) const; + void addAttachmentRequest(const LLUUID& inv_item_id); + void removeAttachmentRequest(const LLUUID& inv_item_id); LLViewerObject* getWornAttachment(const LLUUID& inv_item_id); const std::string getAttachedPointName(const LLUUID& inv_item_id) const; /*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object); /*virtual*/ BOOL detachObject(LLViewerObject *viewer_object); static BOOL detachAttachmentIntoInventory(const LLUUID& item_id); + +private: + // Track attachments that have been requested but have not arrived yet. + mutable std::map mAttachmentRequests; + // testzone attachpt +public: + void addUnsupportedAttachment( LLViewerObject *viewer_object ); + bool removeUnsupportedAttachment( LLViewerObject *viewer_object ); BOOL isWearingUnsupportedAttachment( const LLUUID& inv_item_id ); std::map > mUnsupportedAttachmentPoints; + // + // [RLVa:KB] - Checked: 2010-03-14 (RLVa-1.2.0a) | Added: RLVa-1.1.0i LLViewerJointAttachment* getWornAttachmentPoint(const LLUUID& inv_item_id) const; // [/RLVa:KB] + private: LLViewerJoint* mScreenp; // special purpose joint for HUD attachments From 33827bf8b03f7b216323ac742050b5c9c72c7686 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 31 Oct 2011 20:36:47 -0500 Subject: [PATCH 4/7] Added a bit of debug output for viewer tool states. --- indra/newview/lltoolcomp.cpp | 2 ++ indra/newview/lltoolmgr.cpp | 13 ++++++++----- indra/newview/lltoolmgr.h | 4 +++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index c31717779..31b74c081 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -77,6 +77,8 @@ void LLToolComposite::setCurrentTool( LLTool* new_tool ) { if( mCur != new_tool ) { + if(new_tool) + lldebugs << "Current Tool: " << new_tool->getName() << llendl; if( mSelected ) { mCur->handleDeselect(); diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index eaf6c5a68..c407a6cb4 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -80,11 +80,11 @@ LLToolMgr::LLToolMgr() gToolNull = new LLTool(LLStringUtil::null); // Does nothing setCurrentTool(gToolNull); - gBasicToolset = new LLToolset(); - gCameraToolset = new LLToolset(); -// gLandToolset = new LLToolset(); - gMouselookToolset = new LLToolset(); - gFaceEditToolset = new LLToolset(); + gBasicToolset = new LLToolset("Basic"); + gCameraToolset = new LLToolset("Camera"); +// gLandToolset = new LLToolset("Land"); + gMouselookToolset = new LLToolset("MouseLook"); + gFaceEditToolset = new LLToolset("FaceEdit"); } void LLToolMgr::initTools() @@ -149,6 +149,7 @@ void LLToolMgr::setCurrentToolset(LLToolset* current) { mSelectedTool->handleDeselect(); } + lldebugs << "Current tool set: " << current->getName() << llendl; mCurrentToolset = current; // select first tool of new toolset only if toolset changed mCurrentToolset->selectFirstTool(); @@ -164,6 +165,8 @@ LLToolset* LLToolMgr::getCurrentToolset() void LLToolMgr::setCurrentTool( LLTool* tool ) { + if(tool && mBaseTool!=tool) + lldebugs << "Current Tool: " << tool->getName() << llendl; if (mTransientTool) { mTransientTool = NULL; diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h index 92647c99d..2abba2220 100644 --- a/indra/newview/lltoolmgr.h +++ b/indra/newview/lltoolmgr.h @@ -93,7 +93,7 @@ protected: class LLToolset { public: - LLToolset() : mSelectedTool(NULL) {} + LLToolset(const char *name) : mSelectedTool(NULL), mName(name) {} LLTool* getSelectedTool() { return mSelectedTool; } @@ -109,7 +109,9 @@ public: BOOL isToolSelected( S32 index ); + const char* getName() const {return mName;} protected: + const char* mName; LLTool* mSelectedTool; typedef std::vector tool_list_t; tool_list_t mToolList; From 8376e890b23835fac1c016fde50dbdaca8ada525 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 31 Oct 2011 20:37:11 -0500 Subject: [PATCH 5/7] Hide the mouse cursor a bit better when grabbing items in mouselook. --- indra/newview/lltoolgrab.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index 167d03a5a..b5e764dac 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -738,6 +738,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask) } // HACK to avoid assert: error checking system makes sure that the cursor is set during every handleHover. This is actually a no-op since the cursor is hidden. + gViewerWindow->hideCursor(); gViewerWindow->setCursor(UI_CURSOR_ARROW); lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolGrab (active) [cursor hidden]" << llendl; From 693e3a0555ef35009ff72372db5d3098fa46e7be Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 31 Oct 2011 20:38:29 -0500 Subject: [PATCH 6/7] vary_texture_index only needed in shaders when batching. --- indra/llrender/llshadermgr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 76b3fb711..f4743dd84 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -608,7 +608,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade text[count++] = strdup(decl.c_str()); } - text[count++] = strdup("varying float vary_texture_index;\n"); + if(texture_index_channels != 1) + text[count++] = strdup("varying float vary_texture_index;\n"); text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n"); text[count++] = strdup("{\n"); From d9f674218fdb8d1715359b878ad5c484a900d583 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 31 Oct 2011 20:38:41 -0500 Subject: [PATCH 7/7] Lineending fixup --- indra/llcommon/indra_constants.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 089f8ed38..687e53568 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -153,10 +153,10 @@ const char LAND_LAYER_CODE = 'L'; const char WATER_LAYER_CODE = 'W'; const char WIND_LAYER_CODE = '7'; const char CLOUD_LAYER_CODE = '8'; -// Extended land layer for Aurora Sim +// Extended land layer for Aurora Sim const char AURORA_LAND_LAYER_CODE = 'M'; -const char AURORA_WATER_LAYER_CODE = 'X'; -const char AURORA_WIND_LAYER_CODE = '9'; +const char AURORA_WATER_LAYER_CODE = 'X'; +const char AURORA_WIND_LAYER_CODE = '9'; const char AURORA_CLOUD_LAYER_CODE = ':'; // keys