diff --git a/.gitignore b/.gitignore index a587c8b5ca..f528053f82 100755 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,4 @@ indra/tracy firestorm.code-workspace .cache/clangd/index/ +*-compiled.glsl diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 4aa5a3a58e..f5199477c5 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.8 +6.6.9 diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index b26194f278..1280bc20a8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -227,7 +227,7 @@ void main() vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); diffcol.rgb *= vertex_color.rgb; -#ifdef HAS_ALPHA_MASK +#if HAS_ALPHA_MASK && (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) #if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND if (diffcol.a*vertex_color.a < minimum_alpha) #else diff --git a/indra/newview/fsareasearch.cpp b/indra/newview/fsareasearch.cpp index 8fc1699282..e7605a2ede 100644 --- a/indra/newview/fsareasearch.cpp +++ b/indra/newview/fsareasearch.cpp @@ -67,19 +67,19 @@ #include "rlvhandler.h" // max number of objects that can be (de-)selected in a single packet. -const S32 MAX_OBJECTS_PER_PACKET = 255; +constexpr S32 MAX_OBJECTS_PER_PACKET = 255; // time in seconds between refreshes when active -const F32 REFRESH_INTERVAL = 1.0f; +constexpr F32 REFRESH_INTERVAL = 1.0f; // this is used to prevent refreshing too often and affecting performance. -const F32 MIN_REFRESH_INTERVAL = 0.25f; +constexpr F32 MIN_REFRESH_INTERVAL = 0.25f; // how far the avatar needs to move to trigger a distance update -const F32 MIN_DISTANCE_MOVED = 1.0f; +constexpr F32 MIN_DISTANCE_MOVED = 1.0f; // timeout to resend object properties request again -const F32 REQUEST_TIMEOUT = 30.0f; +constexpr F32 REQUEST_TIMEOUT = 30.0f; std::string RLVa_hideNameIfRestricted(std::string const &name) { @@ -1185,7 +1185,7 @@ void FSAreaSearch::callbackLoadFullName(const LLUUID& id, const std::string& ful } } - mPanelList->updateName(id, full_name); + mPanelList->updateName(id, full_name); } void FSAreaSearch::updateCounterText() @@ -1283,7 +1283,7 @@ void FSAreaSearch::onCommitLine() } } -bool FSAreaSearch::regexTest(std::string text) +bool FSAreaSearch::regexTest(std::string_view text) { // couple regex patters one can use for testing. The regex will match a UUID. // boost::regex pattern("[\\w]{8}-[\\w]{4}-[\\w]{4}-[\\w]{4}-[\\w]{12}"); @@ -1292,8 +1292,8 @@ bool FSAreaSearch::regexTest(std::string text) try { - std::string test_text = "asdfghjklqwerty1234567890"; - boost::regex pattern(text.c_str()); + static const std::string test_text = "asdfghjklqwerty1234567890"; + boost::regex pattern(text.data()); boost::regex_match(test_text, pattern); } catch(boost::regex_error& e) @@ -1822,15 +1822,15 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) if (camera_aspect < 1.0f || invert) { angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect()); - distance = width * 0.5 * 1.1 / tanf(angle_of_view * 0.5f); + distance = width * 0.5f * 1.1f / tanf(angle_of_view * 0.5f); } else { angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getView()); - distance = height * 0.5 * 1.1 / tanf(angle_of_view * 0.5f); + distance = height * 0.5f * 1.1f / tanf(angle_of_view * 0.5f); } - distance += depth * 0.5; + distance += depth * 0.5f; // Verify that the bounding box isn't inside the near clip. Using OBB-plane intersection to check if the // near-clip plane intersects with the bounding box, and if it does, adjust the distance such that the diff --git a/indra/newview/fsareasearch.h b/indra/newview/fsareasearch.h index 9ffdcb4499..8401ec47d1 100644 --- a/indra/newview/fsareasearch.h +++ b/indra/newview/fsareasearch.h @@ -175,7 +175,7 @@ private: void getNameFromUUID(const LLUUID& id, std::string& name, bool group, bool& name_requested); void updateCounterText(); - bool regexTest(std::string text); + bool regexTest(std::string_view text); void findObjects(); void processRequestQueue(); diff --git a/indra/newview/fslslbridge.cpp b/indra/newview/fslslbridge.cpp index b2ec6834e3..7e169ace50 100644 --- a/indra/newview/fslslbridge.cpp +++ b/indra/newview/fslslbridge.cpp @@ -64,9 +64,9 @@ static const std::string FS_ERROR_ATTRIBUTE = "error="; class NameCollectFunctor : public LLInventoryCollectFunctor { public: - NameCollectFunctor(std::string name) + NameCollectFunctor(std::string_view name) { - sName = name; + sName = static_cast(name); } virtual ~NameCollectFunctor() {} virtual bool operator()(LLInventoryCategory* cat, @@ -147,7 +147,7 @@ void FSLSLBridge::setTimerResult(TimerResult result) mTimerResult = result; } -bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID, const LLUUID& ownerID) +bool FSLSLBridge::lslToViewer(std::string_view message, const LLUUID& fromID, const LLUUID& ownerID) { LL_DEBUGS("FSLSLBridge") << message << LL_ENDL; @@ -175,7 +175,7 @@ bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID, { return false; } - std::string tag = message.substr(0, tagend + 1); + std::string_view tag = message.substr(0, tagend + 1); std::string ourBridge = findFSCategory().asString(); // FIRE-962 @@ -199,9 +199,9 @@ bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID, size_t authEnd = message.find(""); size_t verStart = message.find(bridge_ver_tag) + bridge_ver_tag.size(); size_t verEnd = message.find(""); - std::string bURL = message.substr(urlStart,urlEnd - urlStart); - std::string bAuth = message.substr(authStart,authEnd - authStart); - std::string bVer = message.substr(verStart,verEnd - verStart); + std::string bURL = static_cast(message.substr(urlStart,urlEnd - urlStart)); + std::string bAuth = static_cast(message.substr(authStart,authEnd - authStart)); + std::string bVer = static_cast(message.substr(verStart,verEnd - verStart)); // Verify Authorization if (ourBridge != bAuth) @@ -402,7 +402,7 @@ bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID, size_t getScriptInfoEnd = message.find(""); if (getScriptInfoEnd != std::string::npos) { - std::string getScriptInfoString = message.substr(tag_size, getScriptInfoEnd - tag_size); + std::string getScriptInfoString = static_cast(message.substr(tag_size, getScriptInfoEnd - tag_size)); std::istringstream strStreamGetScriptInfo(getScriptInfoString); std::string scriptInfoToken; LLSD scriptInfoArray = LLSD::emptyArray(); @@ -556,7 +556,7 @@ bool FSLSLBridge::canUseBridge() return (isBridgeValid() && sUseLSLBridge && !mCurrentURL.empty()); } -bool FSLSLBridge::viewerToLSL(const std::string& message, Callback_t aCallback) +bool FSLSLBridge::viewerToLSL(std::string_view message, Callback_t aCallback) { LL_DEBUGS("FSLSLBridge") << message << LL_ENDL; @@ -571,32 +571,21 @@ bool FSLSLBridge::viewerToLSL(const std::string& message, Callback_t aCallback) pCallback = FSLSLBridgeRequest_Success; } - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(mCurrentURL, LLSD(message), pCallback, FSLSLBridgeRequest_Failure); + // Calling data() should be fine here since message is a view on a null-terminated string + LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(mCurrentURL, LLSD(message.data()), pCallback, FSLSLBridgeRequest_Failure); return true; } bool FSLSLBridge::updateBoolSettingValue(const std::string& msgVal) { - std::string boolVal = "0"; - - if (gSavedPerAccountSettings.getBOOL(msgVal)) - { - boolVal = "1"; - } - - return viewerToLSL(msgVal + "|" + boolVal ); + const std::string boolVal = gSavedPerAccountSettings.getBOOL(msgVal) ? "1" : "0"; + return viewerToLSL(msgVal + "|" + boolVal); } bool FSLSLBridge::updateBoolSettingValue(const std::string& msgVal, bool contentVal) { - std::string boolVal = "0"; - - if (contentVal) - { - boolVal = "1"; - } - + const std::string boolVal = contentVal ? "1" : "0"; return viewerToLSL(msgVal + "|" + boolVal); } @@ -677,9 +666,9 @@ void FSLSLBridge::cleanUpPreCreation() gInventory.collectDescendentsIf(findFSCategory(), cats, items, FALSE, namefunctor); mAllowedDetachables.clear(); - for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + for (const auto& item : items) { - LLUUID item_id= (*it)->getUUID(); + const LLUUID& item_id = item->getUUID(); if (get_is_item_worn(item_id)) { LL_INFOS("FSLSLBridge") << "Found worn object " << item_id << " bridge category - detaching..." << LL_ENDL; @@ -712,10 +701,10 @@ void FSLSLBridge::finishCleanUpPreCreation() NameCollectFunctor namefunctor(mCurrentFullName); gInventory.collectDescendentsIf(findFSCategory(), cats, items, FALSE, namefunctor); - for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + for (const auto& item : items) { - LL_INFOS("FSLSLBridge") << "Bridge folder cleanup: Deleting " << (*it)->getName() << " (" << (*it)->getUUID() << ")" << LL_ENDL; - remove_inventory_item((*it)->getUUID(), nullptr, true); // Don't wait for callback from server to update inventory model + LL_INFOS("FSLSLBridge") << "Bridge folder cleanup: Deleting " << item->getName() << " (" << item->getUUID() << ")" << LL_ENDL; + remove_inventory_item(item->getUUID(), nullptr, true); // Don't wait for callback from server to update inventory model } gInventory.notifyObservers(); @@ -1143,6 +1132,9 @@ void FSLSLBridge::processDetach(LLViewerObject* object, const LLViewerJointAttac void FSLSLBridge::setupBridgePrim(LLViewerObject* object) { LL_DEBUGS("FSLSLBridge") << "Entering bridge container setup..." << LL_ENDL; + + if (!object->getRegion()) + return; LLProfileParams profParams(LL_PCODE_PROFILE_CIRCLE, 0.230f, 0.250f, 0.95f); LLPathParams pathParams(LL_PCODE_PATH_CIRCLE, 0.2f, 0.22f, @@ -1509,11 +1501,11 @@ LLUUID FSLSLBridge::findFSCategory() gInventory.getDirectDescendentsOf(fsCatID, cats, items); if (cats) { - for (LLInventoryModel::cat_array_t::iterator it = cats->begin(); it != cats->end(); ++it) + for (const auto& cat : *cats) { - if ((*it)->getName() == FS_BRIDGE_FOLDER) + if (cat->getName() == FS_BRIDGE_FOLDER) { - bridgeCatID = (*it)->getUUID(); + bridgeCatID = cat->getUUID(); break; } } @@ -1551,11 +1543,11 @@ LLUUID FSLSLBridge::findFSBridgeContainerCategory() gInventory.getDirectDescendentsOf(LibRootID, cats, items); if (cats) { - for (LLInventoryModel::cat_array_t::iterator it = cats->begin(); it != cats->end(); ++it) + for (const auto& cat : *cats) { - if ((*it)->getName() == "Objects") + if (cat->getName() == "Objects") { - LLUUID LibObjectsCatID = (*it)->getUUID(); + const LLUUID& LibObjectsCatID = cat->getUUID(); if (LibObjectsCatID.notNull()) { LLInventoryModel::item_array_t* objects_items; @@ -1563,11 +1555,11 @@ LLUUID FSLSLBridge::findFSBridgeContainerCategory() gInventory.getDirectDescendentsOf(LibObjectsCatID, objects_cats, objects_items); if (objects_cats) { - for (LLInventoryModel::cat_array_t::iterator object_it = objects_cats->begin(); object_it != objects_cats->end(); ++object_it) + for (const auto& object_cat : *objects_cats) { - if ((*object_it)->getName() == FS_BRIDGE_CONTAINER_FOLDER) + if (object_cat->getName() == FS_BRIDGE_CONTAINER_FOLDER) { - mBridgeContainerFolderID = (*object_it)->getUUID(); + mBridgeContainerFolderID = object_cat->getUUID(); LL_INFOS("FSLSLBridge") << "FSBridge container category found in library. UUID: " << mBridgeContainerFolderID << LL_ENDL; gInventory.fetchDescendentsOf(mBridgeContainerFolderID); return mBridgeContainerFolderID; @@ -1594,12 +1586,11 @@ LLViewerInventoryItem* FSLSLBridge::findInvObject(const std::string& obj_name, c gInventory.collectDescendentsIf(catID, cats, items, FALSE, namefunctor); - for (LLViewerInventoryItem::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + for (const auto& item : items) { - const LLViewerInventoryItem* itemp = *it; - if (!itemp->getIsLinkType() && (itemp->getType() == LLAssetType::AT_OBJECT)) + if (!item->getIsLinkType() && (item->getType() == LLAssetType::AT_OBJECT)) { - itemID = itemp->getUUID(); + itemID = item->getUUID(); break; } } @@ -1631,13 +1622,12 @@ void FSLSLBridge::cleanUpBridgeFolder(const std::string& nameToCleanUp) NameCollectFunctor namefunctor(nameToCleanUp); gInventory.collectDescendentsIf(catID, cats, items, FALSE, namefunctor); - for (LLViewerInventoryItem::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + for (const auto& item : items) { - const LLViewerInventoryItem* itemp = *it; - if (!itemp->getIsLinkType() && (itemp->getUUID() != mpBridge->getUUID())) + if (!item->getIsLinkType() && (item->getUUID() != mpBridge->getUUID())) { - LL_INFOS("FSLSLBridge") << "Bridge folder cleanup: Deleting " << itemp->getName() << " (" << itemp->getUUID() << ")" << LL_ENDL; - remove_inventory_item(itemp->getUUID(), nullptr, true); + LL_INFOS("FSLSLBridge") << "Bridge folder cleanup: Deleting " << item->getName() << " (" << item->getUUID() << ")" << LL_ENDL; + remove_inventory_item(item->getUUID(), nullptr, true); } } @@ -1684,13 +1674,12 @@ void FSLSLBridge::detachOtherBridges() //detach everything except current valid bridge - if any gInventory.collectDescendents(catID, cats, items, FALSE); - for (LLViewerInventoryItem::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + for (const auto& item : items) { - const LLViewerInventoryItem* itemp = *it; - if (get_is_item_worn(itemp->getUUID()) && - ((!fsBridge) || (itemp->getUUID() != fsBridge->getUUID()))) + if (get_is_item_worn(item->getUUID()) && + ((!fsBridge) || (item->getUUID() != fsBridge->getUUID()))) { - LLVOAvatarSelf::detachAttachmentIntoInventory(itemp->getUUID()); + LLVOAvatarSelf::detachAttachmentIntoInventory(item->getUUID()); } } } diff --git a/indra/newview/fslslbridge.h b/indra/newview/fslslbridge.h index 76722b8530..31a0be7df9 100644 --- a/indra/newview/fslslbridge.h +++ b/indra/newview/fslslbridge.h @@ -65,8 +65,8 @@ public: typedef std::function Callback_t; - bool lslToViewer(const std::string& message, const LLUUID& fromID, const LLUUID& ownerID); - bool viewerToLSL(const std::string& message, Callback_t = nullptr); + bool lslToViewer(std::string_view message, const LLUUID& fromID, const LLUUID& ownerID); + bool viewerToLSL(std::string_view message, Callback_t = nullptr); bool updateBoolSettingValue(const std::string& msgVal); bool updateBoolSettingValue(const std::string& msgVal, bool contentVal); diff --git a/indra/newview/fspanelcontactsets.h b/indra/newview/fspanelcontactsets.h index 0f30a0fa81..98f5deb4de 100644 --- a/indra/newview/fspanelcontactsets.h +++ b/indra/newview/fspanelcontactsets.h @@ -63,7 +63,6 @@ private: void onClickRemovePseudonym(); void refreshContactSets(); - void removeAvatarFromSet(); void resetControls(); void updateSets(LGGContactSets::EContactSetUpdate type); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 672afb6923..b9f2943a47 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -1266,7 +1266,9 @@ void LLAvatarActions::shareWithAvatars(LLView * panel) LLFloater* root_floater = gFloaterView->getParentFloater(panel); LLInventoryPanel* inv_panel = dynamic_cast(panel); LLFloaterAvatarPicker* picker = - LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2, inv_panel), TRUE, FALSE, FALSE, root_floater->getName()); + // FIRE-32377: Don't include own avatar when sharing items + //LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2, inv_panel), TRUE, FALSE, FALSE, root_floater->getName()); + LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2, inv_panel), TRUE, FALSE, TRUE, root_floater->getName()); if (!picker) { return; diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index 1a4d8dd476..c5aaa70459 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -203,35 +203,34 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape(const LLPhysicsVolumeParam { specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; } - else if (volume_params.isMeshSculpt() && - // Check overall dimensions, not individual triangles. - (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || - scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || - scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE - ) ) - { - // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. - specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; - } + // restore proper behaviour. + // else if (volume_params.isMeshSculpt() && + // // Check overall dimensions, not individual triangles. + // (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + // scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + // scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE + // ) ) + // { + // // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. + // specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + // } + // else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) { // [BUG-134006] Viewer code is not aligned to server code when calculating physics shape for thin objects. specOut.mType = PhysicsShapeSpecification::INVALID; // FIRE-23053 - add decomp check analysed mesh physics is not correctly displayed for thin meshes // if (volume_params.isMeshSculpt()){ - if (volume_params.isMeshSculpt() && !hasDecomp){ - static const float SHAPE_BUILDER_CONVEXIFICATION_SIZE_MESH = 0.5; - // it's a mesh and only one size is smaller than min. - for (S32 i = 0; i < 3; ++i) - { - if (scale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE_MESH) - { - specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; - } - } + if ( (volume_params.isMeshSculpt() && !hasDecomp) && + (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE + ) ) + { + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; } if (specOut.mType == PhysicsShapeSpecification::INVALID) - // + // note: dangling if....(hopefully this will go away with PR sent to LL) specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; } else // Resort to mesh diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp index 128766d7ea..096ea63e6e 100644 --- a/indra/newview/llviewerhelp.cpp +++ b/indra/newview/llviewerhelp.cpp @@ -37,6 +37,7 @@ #include "llviewerhelputil.h" #include "llviewerhelp.h" +#include "llweb.h" // Support for opening help in external browser // support for secondlife:///app/help/{TOPIC} SLapps class LLHelpHandler : public LLCommandHandler @@ -95,6 +96,14 @@ std::string LLViewerHelp::getURL(const std::string &topic) void LLViewerHelp::showTopic(const std::string& topic) { + // allow external browser for help topics + auto url = getURL(topic); + if ( LLWeb::useExternalBrowser(url) ) + { + LLWeb::loadURLExternal(url); + } + else + // LLFloaterReg::showInstance("help_browser", topic); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 81bb1af56d..98be2ddb35 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6753,7 +6753,8 @@ class LLToolsSelectNextPartFace : public view_listener_t bool iprev = (userdata.asString() == "includeprevious"); // Make shift+click on forward/back buttons work like includenext/previous - if (gKeyboard->currentMask(false) & MASK_SHIFT) + // (filter out the menu shortcuts by testing for ifwd / iprev) + if (gKeyboard->currentMask(false) & MASK_SHIFT && !ifwd && !iprev) { ifwd = fwd; iprev = prev;