diff options
-rw-r--r-- | indra/newview/llagentwearables.cpp | 15 | ||||
-rw-r--r-- | indra/newview/llagentwearablesfetch.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 6 | ||||
-rw-r--r-- | indra/newview/lloutfitslist.cpp | 48 | ||||
-rw-r--r-- | indra/newview/lloutfitslist.h | 4 | ||||
-rw-r--r-- | indra/newview/llsidepanelappearance.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llviewermenu.cpp | 98 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 25 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 10 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 236 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.cpp | 10 | ||||
-rw-r--r-- | indra/newview/llwearableitemslist.h | 3 |
12 files changed, 306 insertions, 157 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 337878cf96..25456f7e26 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -388,9 +388,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 const std::string new_name) { LLWearable* old_wearable = getWearable(type, index); - if(!old_wearable) return; - bool name_changed = !new_name.empty() && (new_name != old_wearable->getName()); - if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion()) + if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion())) { LLUUID old_item_id = old_wearable->getItemID(); LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); @@ -406,10 +404,12 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 if (item) { std::string item_name = item->getName(); - if (name_changed) + bool name_changed = false; + if (!new_name.empty() && (new_name != item->getName())) { llinfos << "saveWearable changing name from " << item->getName() << " to " << new_name << llendl; item_name = new_name; + name_changed = true; } // Update existing inventory item LLPointer<LLViewerInventoryItem> template_item = @@ -1756,7 +1756,7 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj LLViewerObject *objectp = (*attachment_iter); if (objectp) { - LLUUID object_item_id = objectp->getItemID(); + LLUUID object_item_id = objectp->getAttachmentItemID(); if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) { // Object currently worn, was requested. @@ -1885,7 +1885,10 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra msg->nextBlockFast(_PREHASH_ObjectData ); msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); - msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point + if (gSavedSettings.getBOOL("MultipleAttachments")) + msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD ); + else + msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); msg->addStringFast(_PREHASH_Name, item->getName()); msg->addStringFast(_PREHASH_Description, item->getDescription()); diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index d911d123f4..f6bb1b9bc9 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -215,7 +215,7 @@ void LLInitialWearablesFetch::processWearablesMessage() { LLViewerObject* attached_object = (*attachment_iter); if (!attached_object) continue; - const LLUUID& item_id = attached_object->getItemID(); + const LLUUID& item_id = attached_object->getAttachmentItemID(); if (item_id.isNull()) continue; ids.push_back(item_id); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ed15f2bd76..cdabbf2ddc 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1270,6 +1270,12 @@ BOOL LLItemBridge::isItemRenameable() const { return FALSE; } + + if (!item->isFinished()) // EXT-8662 + { + return FALSE; + } + return (item->getPermissions().allowModifyBy(gAgent.getID())); } return FALSE; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 2b6c80bac8..a471158c3d 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -1055,25 +1055,37 @@ void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) void LLOutfitsList::onCOFChanged() { - LLInventoryModel::changed_items_t changed_linked_items; + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; - const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs(); - for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items.begin(); - iter != changed_items.end(); - ++iter) + // Collect current COF items + gInventory.collectDescendents( + LLAppearanceMgr::instance().getCOF(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH); + + uuid_vec_t vnew; + uuid_vec_t vadded; + uuid_vec_t vremoved; + + // From gInventory we get the UUIDs of links that are currently in COF. + // These links UUIDs are not the same UUIDs that we have in each wearable items list. + // So we collect base items' UUIDs to find them or links that point to them in wearable + // items lists and update their worn state there. + for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin(); + iter != item_array.end(); + ++iter) { - LLViewerInventoryItem* item = gInventory.getItem(*iter); - if (item) - { - // From gInventory we get the UUIDs of new links added to COF - // or removed from COF. These links UUIDs are not the same UUIDs - // that we have in each wearable items list. So we collect base items - // UUIDs to find all items or links that point to same base items in wearable - // items lists and update their worn state there. - changed_linked_items.insert(item->getLinkedUUID()); - } + vnew.push_back((*iter)->getLinkedUUID()); } + // We need to update only items that were added or removed from COF. + LLCommonUtils::computeDifference(vnew, mCOFLinkedItems, vadded, vremoved); + + // Store the ids of items currently linked from COF. + mCOFLinkedItems = vnew; + for (outfits_map_t::iterator iter = mOutfitsMap.begin(); iter != mOutfitsMap.end(); ++iter) @@ -1084,9 +1096,13 @@ void LLOutfitsList::onCOFChanged() LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); if (!list) continue; + // Append removed ids to added ids because we should update all of them. + vadded.reserve(vadded.size() + vremoved.size()); + vadded.insert(vadded.end(), vremoved.begin(), vremoved.end()); + // Every list updates the labels of changed items or // the links that point to these items. - list->updateChangedItems(changed_linked_items); + list->updateChangedItems(vadded); } } diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 206854b232..4613bdfeb9 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -214,6 +214,10 @@ private: typedef outfits_map_t::value_type outfits_map_value_t; outfits_map_t mOutfitsMap; + // IDs of original items which are worn and linked in COF. + // Used to monitor COF changes for updating items worn state. See EXT-8636. + uuid_vec_t mCOFLinkedItems; + LLOutfitListGearMenu* mGearMenu; LLListContextMenu* mOutfitMenu; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index adfd457664..83329ebccf 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -473,7 +473,7 @@ void LLSidepanelAppearance::fetchInventory() { LLViewerObject* attached_object = (*attachment_iter); if (!attached_object) continue; - const LLUUID& item_id = attached_object->getItemID(); + const LLUUID& item_id = attached_object->getAttachmentItemID(); if (item_id.isNull()) continue; ids.push_back(item_id); } @@ -501,8 +501,8 @@ void LLSidepanelAppearance::inventoryFetched() void LLSidepanelAppearance::setWearablesLoading(bool val) { - getChildView("wearables_loading_indicator")->setVisible( val); - getChildView("edit_outfit_btn")->setVisible( !val); + childSetVisible("wearables_loading_indicator", val); + childSetVisible("edit_outfit_btn", !val); if (!val) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 40bf62acc9..e58f0c9aec 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1083,8 +1083,6 @@ class LLAdvancedToggleWireframe : public view_listener_t bool handleEvent(const LLSD& userdata) { gUseWireframe = !(gUseWireframe); - LLPipeline::updateRenderDeferred(); - gPipeline.resetVertexBuffers(); return true; } }; @@ -2056,9 +2054,9 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t }; ///////////////////////////////////// -// Enable Deferred Rendering sub-options +// Enable Global Illumination /// ///////////////////////////////////// -class LLAdvancedEnableRenderDeferredOptions: public view_listener_t +class LLAdvancedEnableRenderDeferredGI: public view_listener_t { bool handleEvent(const LLSD& userdata) { @@ -5854,7 +5852,6 @@ void handle_buy_land() class LLObjectAttachToAvatar : public view_listener_t { public: - LLObjectAttachToAvatar(bool replace) : mReplace(replace) {} static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; } private: @@ -5868,38 +5865,22 @@ private: LLViewerJointAttachment* attachment_point = NULL; if (index > 0) attachment_point = get_if_there(gAgentAvatarp->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); - confirmReplaceAttachment(0, attachment_point); + confirm_replace_attachment(0, attachment_point); } return true; } - static void onNearAttachObject(BOOL success, void *user_data); - void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point); - - struct CallbackData - { - CallbackData(LLViewerJointAttachment* point, bool replace) : mAttachmentPoint(point), mReplace(replace) {} - - LLViewerJointAttachment* mAttachmentPoint; - bool mReplace; - }; - protected: static LLObjectSelectionHandle sObjectSelection; - bool mReplace; }; LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection; -// static -void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data) +void near_attach_object(BOOL success, void *user_data) { - if (!user_data) return; - CallbackData* cb_data = static_cast<CallbackData*>(user_data); - if (success) { - const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint; + const LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; U8 attachment_id = 0; if (attachment) @@ -5919,15 +5900,12 @@ void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data) // interpret 0 as "default location" attachment_id = 0; } - LLSelectMgr::getInstance()->sendAttach(attachment_id, cb_data->mReplace); + LLSelectMgr::getInstance()->sendAttach(attachment_id); } LLObjectAttachToAvatar::setObjectSelection(NULL); - - delete cb_data; } -// static -void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point) +void confirm_replace_attachment(S32 option, void* user_data) { if (option == 0/*YES*/) { @@ -5952,9 +5930,7 @@ void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointA delta = delta * 0.5f; walkToSpot -= delta; - // The callback will be called even if avatar fails to get close enough to the object, so we won't get a memory leak. - CallbackData* user_data = new CallbackData(attachment_point, mReplace); - gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance); + gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, near_attach_object, user_data, stop_distance); gAgentCamera.clearFocusObject(); } } @@ -6074,7 +6050,7 @@ static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data) const LLViewerObject* attached_object = (*attachment_iter); if (attached_object) { - LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getItemID()); + LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); if (itemp) { label += std::string(" (") + itemp->getName() + std::string(")"); @@ -6193,14 +6169,14 @@ class LLAttachmentEnableDrop : public view_listener_t { // make sure item is in your inventory (it could be a delayed attach message being sent from the sim) // so check to see if the item is in the inventory already - item = gInventory.getItem((*attachment_iter)->getItemID()); + item = gInventory.getItem((*attachment_iter)->getAttachmentItemID()); if (!item) { // Item does not exist, make an observer to enable the pie menu // when the item finishes fetching worst case scenario // if a fetch is already out there (being sent from a slow sim) // we refetch and there are 2 fetches - LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getItemID()); + LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getAttachmentItemID()); worn_item_fetched->startFetch(); gInventory.addObserver(worn_item_fetched); } @@ -6547,7 +6523,7 @@ void handle_dump_attachments(void*) !attached_object->mDrawable->isRenderType(0)); LLVector3 pos; if (visible) pos = attached_object->mDrawable->getPosition(); - llinfos << "ATTACHMENT " << key << ": item_id=" << attached_object->getItemID() + llinfos << "ATTACHMENT " << key << ": item_id=" << attached_object->getAttachmentItemID() << (attached_object ? " present " : " absent ") << (visible ? "visible " : "invisible ") << " at " << pos @@ -6558,7 +6534,7 @@ void handle_dump_attachments(void*) } -// these are used in the gl menus to set control values, generically. +// these are used in the gl menus to set control values. class LLToggleControl : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -6577,44 +6553,8 @@ class LLCheckControl : public view_listener_t std::string callback_data = userdata.asString(); bool new_value = gSavedSettings.getBOOL(callback_data); return new_value; - } -}; - -// not so generic - -class LLAdvancedCheckRenderShadowOption: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - std::string control_name = userdata.asString(); - S32 current_shadow_level = gSavedSettings.getS32(control_name); - if (current_shadow_level == 0) // is off - { - return false; - } - else // is on - { - return true; - } - } -}; +} -class LLAdvancedClickRenderShadowOption: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - std::string control_name = userdata.asString(); - S32 current_shadow_level = gSavedSettings.getS32(control_name); - if (current_shadow_level == 0) // upgrade to level 2 - { - gSavedSettings.setS32(control_name, 2); - } - else // downgrade to level 0 - { - gSavedSettings.setS32(control_name, 0); - } - return true; - } }; void menu_toggle_attached_lights(void* user_data) @@ -7939,7 +7879,7 @@ void initialize_menus() // Help menu // most items use the ShowFloater method - // Advanced menu + // Advance menu view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole"); view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); @@ -7966,13 +7906,12 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo"); view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe"); view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); - // Develop > Render view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas"); view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas"); view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion"); view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO"); view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred"); - view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions"); + view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredGI(), "Advanced.EnableRenderDeferredGI"); view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame"); @@ -7981,8 +7920,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedToggleFrameTest(), "Advanced.ToggleFrameTest"); view_listener_t::addMenu(new LLAdvancedCheckFrameTest(), "Advanced.CheckFrameTest"); view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles"); - view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption"); - view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption"); #ifdef TOGGLE_HACKED_GODLIKE_VIEWER @@ -8139,8 +8076,7 @@ void initialize_menus() commit.add("Object.Touch", boost::bind(&handle_object_touch)); commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand)); commit.add("Object.Delete", boost::bind(&handle_object_delete)); - view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar"); - view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar"); + view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar"); view_listener_t::addMenu(new LLObjectReturn(), "Object.Return"); view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse"); view_listener_t::addMenu(new LLObjectMute(), "Object.Mute"); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 15bdf126c5..d3e6f01bc8 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5233,3 +5233,28 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif return ; } +const LLUUID &LLViewerObject::getAttachmentItemID() const +{ + return mAttachmentItemID; +} + +void LLViewerObject::setAttachmentItemID(const LLUUID &id) +{ + mAttachmentItemID = id; +} + +const LLUUID &LLViewerObject::extractAttachmentItemID() +{ + LLUUID item_id = LLUUID::null; + LLNameValue* item_id_nv = getNVPair("AttachItemID"); + if( item_id_nv ) + { + const char* s = item_id_nv->getString(); + if( s ) + { + item_id.set(s); + } + } + setAttachmentItemID(item_id); + return getAttachmentItemID(); +} diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index be83fb7ef8..33fda9fa2d 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -678,11 +678,15 @@ protected: private: static S32 sNumObjects; + //-------------------------------------------------------------------- + // For objects that are attachments + //-------------------------------------------------------------------- public: - const LLUUID &getItemID() const { return mAttachmentItemID; } - void setItemID(const LLUUID &id) { mAttachmentItemID = id; } + const LLUUID &getAttachmentItemID() const; + void setAttachmentItemID(const LLUUID &id); + const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object private: - LLUUID mAttachmentItemID; // ItemID when item is in user inventory. + LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. }; /////////////////// diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 6392aad248..4e00355bbe 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -702,8 +702,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i); } - mDirtyMesh = 2; // Dirty geometry, need to regenerate. + mDirtyMesh = TRUE; // Dirty geometry, need to regenerate. mMeshTexturesDirty = FALSE; + mShadow0Facep = NULL; + mShadow1Facep = NULL; mHeadp = NULL; mIsBuilt = FALSE; @@ -739,6 +741,12 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mRippleTimeLast = 0.f; + mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c"); + + // GL NOT ACTIVE HERE + //gGL.getTexUnit(0)->bind(mShadowImagep.get()); + //mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); + mInAir = FALSE; mStepOnLand = TRUE; @@ -1967,7 +1975,7 @@ void LLVOAvatar::updateMeshData() } if(num_vertices < 1)//skip empty meshes { - continue ; + break ; } if(last_v_num > 0)//put the last inserted part into next vertex buffer. { @@ -1989,8 +1997,6 @@ void LLVOAvatar::updateMeshData() // resize immediately facep->setSize(num_vertices, num_indices); - bool terse_update = false; - if(facep->mVertexBuffer.isNull()) { facep->mVertexBuffer = new LLVertexBufferAvatar(); @@ -1998,16 +2004,8 @@ void LLVOAvatar::updateMeshData() } else { - if (facep->mVertexBuffer->getRequestedIndices() == num_indices && - facep->mVertexBuffer->getRequestedVerts() == num_vertices) - { - terse_update = true; - } - else - { facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; } - } facep->setGeomIndex(0); facep->setIndicesIndex(0); @@ -2021,7 +2019,7 @@ void LLVOAvatar::updateMeshData() for(S32 k = j ; k < part_index ; k++) { - mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update); + mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR); } stop_glerror(); @@ -2431,6 +2429,12 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) LLJoint::sNumUpdates = 0; LLJoint::sNumTouches = 0; + // *NOTE: this is necessary for the floating name text above your head. + if (mDrawable.notNull()) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_SHADOW, TRUE); + } + BOOL visible = isVisible() || mNeedsAnimUpdate; // update attachments positions @@ -3783,20 +3787,13 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) return num_indices; } - LLFace* face = mDrawable->getFace(0); - - bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); - - if (needs_rebuild || mDirtyMesh) + if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) { //LOD changed or new mesh created, allocate new vertex buffer if needed - if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4) - { updateMeshData(); - mDirtyMesh = 0; + mDirtyMesh = FALSE; mNeedsSkin = TRUE; mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } - } if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) { @@ -4043,6 +4040,54 @@ U32 LLVOAvatar::renderRigid() return num_indices; } +U32 LLVOAvatar::renderFootShadows() +{ + U32 num_indices = 0; + + if (!mIsBuilt) + { + return 0; + } + + if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead())) + { + return 0; + } + + if (!mIsBuilt) + { + return 0; + } + + // Don't render foot shadows if your lower body is completely invisible. + // (non-humanoid avatars rule!) + if (!isTextureVisible(TEX_LOWER_BAKED)) + { + return 0; + } + + // Update the shadow, tractor, and text label geometry. + if (mDrawable->isState(LLDrawable::REBUILD_SHADOW) && !isImpostor()) + { + updateShadowFaces(); + mDrawable->clearState(LLDrawable::REBUILD_SHADOW); + } + + U32 foot_mask = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD0; + + LLGLDepthTest test(GL_TRUE, GL_FALSE); + //render foot shadows + LLGLEnable blend(GL_BLEND); + gGL.getTexUnit(0)->bind(mShadowImagep, TRUE); + glColor4fv(mShadow0Facep->getRenderColor().mV); + mShadow0Facep->renderIndexed(foot_mask); + glColor4fv(mShadow1Facep->getRenderColor().mV); + mShadow1Facep->renderIndexed(foot_mask); + + return num_indices; +} + U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) { if (!mImpostor.isComplete()) @@ -4168,6 +4213,11 @@ void LLVOAvatar::updateTextures() { setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea))); } + + if( render_avatar ) + { + mShadowImagep->addTextureStats(mPixelArea); + } } @@ -5434,7 +5484,7 @@ BOOL LLVOAvatar::updateJointLODs() if (res) { sNumLODChangesThisFrame++; - dirtyMesh(2); + dirtyMesh(); return TRUE; } } @@ -5458,9 +5508,18 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) mDrawable->addFace(poolp, NULL); mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR); + LLFace *facep; + + // Add faces for the foot shadows + facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep); + mShadow0Facep = facep; + + facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep); + mShadow1Facep = facep; + mNumInitFaces = mDrawable->getNumFaces() ; - dirtyMesh(2); + dirtyMesh(); return mDrawable; } @@ -5500,6 +5559,107 @@ BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable) } //----------------------------------------------------------------------------- +// updateShadowFaces() +//----------------------------------------------------------------------------- +void LLVOAvatar::updateShadowFaces() +{ + LLFace *face0p = mShadow0Facep; + LLFace *face1p = mShadow1Facep; + + // + // render avatar shadows + // + if (mInAir || mUpdatePeriod >= IMPOSTOR_PERIOD) + { + face0p->setSize(0, 0); + face1p->setSize(0, 0); + return; + } + + LLSprite sprite(mShadowImagep.notNull() ? mShadowImagep->getID() : LLUUID::null); + sprite.setFollow(FALSE); + const F32 cos_angle = gSky.getSunDirection().mV[2]; + F32 cos_elev = sqrt(1 - cos_angle * cos_angle); + if (cos_angle < 0) cos_elev = -cos_elev; + sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f); + LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f); + + if (mShadowImagep->hasGLTexture()) + { + LLVector3 normal; + LLVector3d shadow_pos; + LLVector3 shadow_pos_agent; + F32 foot_height; + + if (mFootLeftp) + { + LLVector3 joint_world_pos = mFootLeftp->getWorldPosition(); + // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now + // but we make an explicit ray trace call in expectation of future improvements + resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos), + gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal); + shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos); + foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ]; + + // Pull sprite in direction of surface normal + shadow_pos_agent += normal * SHADOW_OFFSET_AMT; + + // Render sprite + sprite.setNormal(normal); + if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) + { + sprite.setColor(0.f, 0.f, 0.f, 0.f); + } + else + { + sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f)); + } + sprite.setPosition(shadow_pos_agent); + + LLVector3 foot_to_knee = mKneeLeftp->getWorldPosition() - joint_world_pos; + //foot_to_knee.normalize(); + foot_to_knee -= projected_vec(foot_to_knee, sun_vec); + sprite.setYaw(azimuth(sun_vec - foot_to_knee)); + + sprite.updateFace(*face0p); + } + + if (mFootRightp) + { + LLVector3 joint_world_pos = mFootRightp->getWorldPosition(); + // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now + // but we make an explicit ray trace call in expectation of future improvements + resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos), + gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal); + shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos); + foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ]; + + // Pull sprite in direction of surface normal + shadow_pos_agent += normal * SHADOW_OFFSET_AMT; + + // Render sprite + sprite.setNormal(normal); + if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) + { + sprite.setColor(0.f, 0.f, 0.f, 0.f); + } + else + { + sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f)); + } + sprite.setPosition(shadow_pos_agent); + + LLVector3 foot_to_knee = mKneeRightp->getWorldPosition() - joint_world_pos; + //foot_to_knee.normalize(); + foot_to_knee -= projected_vec(foot_to_knee, sun_vec); + sprite.setYaw(azimuth(sun_vec - foot_to_knee)); + + sprite.updateFace(*face1p); + } + } +} + +//----------------------------------------------------------------------------- // updateSexDependentLayerSets() //----------------------------------------------------------------------------- void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake ) @@ -5514,12 +5674,9 @@ void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake ) //----------------------------------------------------------------------------- void LLVOAvatar::dirtyMesh() { - dirtyMesh(1); -} -void LLVOAvatar::dirtyMesh(S32 priority) -{ - mDirtyMesh = llmax(mDirtyMesh, priority); + mDirtyMesh = TRUE; } + //----------------------------------------------------------------------------- // hideSkirt() //----------------------------------------------------------------------------- @@ -5553,6 +5710,7 @@ BOOL LLVOAvatar::setParent(LLViewerObject* parent) void LLVOAvatar::addChild(LLViewerObject *childp) { + childp->extractAttachmentItemID(); // find the inventory item this object is associated with. LLViewerObject::addChild(childp); if (childp->mDrawable) { @@ -5642,15 +5800,6 @@ BOOL LLVOAvatar::canAttachMoreObjects() const } //----------------------------------------------------------------------------- -// canAttachMoreObjects() -// Returns true if we can attach <n> more objects. -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const -{ - return (getNumAttachments() + n) <= MAX_AGENT_ATTACHMENTS; -} - -//----------------------------------------------------------------------------- // lazyAttach() //----------------------------------------------------------------------------- void LLVOAvatar::lazyAttach() @@ -7793,15 +7942,18 @@ BOOL LLVOAvatar::updateLOD() BOOL res = updateJointLODs(); LLFace* facep = mDrawable->getFace(0); - if (facep->mVertexBuffer.isNull()) + if (facep->mVertexBuffer.isNull() || + (LLVertexBuffer::sEnableVBOs && + ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) != + (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))) { - dirtyMesh(2); + mDirtyMesh = TRUE; } - if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) + if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) { //LOD changed or new mesh created, allocate new vertex buffer if needed updateMeshData(); - mDirtyMesh = 0; + mDirtyMesh = FALSE; mNeedsSkin = TRUE; mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 5e23965f62..bff4b9bcbd 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -124,7 +124,11 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name, { std::string search_label = name; - if (mWornIndicationEnabled && get_is_item_worn(mInventoryItemUUID)) + // Updating item's worn status depending on whether it is linked in COF or not. + // We don't use get_is_item_worn() here because this update is triggered by + // an inventory observer upon link in COF beind added or removed so actual + // worn status of a linked item may still remain unchanged. + if (mWornIndicationEnabled && LLAppearanceMgr::instance().isLinkInCOF(mInventoryItemUUID)) { search_label += LLTrans::getString("worn"); item_state = IS_WORN; @@ -659,7 +663,7 @@ void LLWearableItemsList::updateList(const LLUUID& category_id) refreshList(item_array); } -void LLWearableItemsList::updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids) +void LLWearableItemsList::updateChangedItems(const uuid_vec_t& changed_items_uuids) { // nothing to update if (changed_items_uuids.empty()) return; @@ -681,7 +685,7 @@ void LLWearableItemsList::updateChangedItems(const LLInventoryModel::changed_ite LLUUID linked_uuid = inv_item->getLinkedUUID(); - for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items_uuids.begin(); + for (uuid_vec_t::const_iterator iter = changed_items_uuids.begin(); iter != changed_items_uuids.end(); ++iter) { diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 237ba1af43..ac4eac4764 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -39,7 +39,6 @@ // newview #include "llinventoryitemslist.h" #include "llinventorylistitem.h" -#include "llinventorymodel.h" #include "lllistcontextmenu.h" #include "llwearabletype.h" @@ -441,7 +440,7 @@ public: * Update items that match UUIDs from changed_items_uuids * or links that point at such items. */ - void updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids); + void updateChangedItems(const uuid_vec_t& changed_items_uuids); bool isStandalone() const { return mIsStandalone; } |