diff --git a/.hgtags b/.hgtags index 4cd72d473d..4ffe313f51 100755 --- a/.hgtags +++ b/.hgtags @@ -581,3 +581,4 @@ ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release 23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release 52422540bfe54b71155aa455360bee6e3ef1fd96 5.1.9-release 821edfcd14919c0e95c590866171c61fb57e8623 6.0.0-release +21b7604680ef6b6ea67f8bebaaa588d6e263bdc1 6.0.1-release diff --git a/autobuild.xml b/autobuild.xml index 5d2667e3dc..5de58b4484 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1988,9 +1988,9 @@ archive hash - 814bec3fa5045a18dce2bc4ce78b585d + 1b87073540bf081136e60777d99f09f2 url - file:///opt/firestorm/kdu-7.A.4-darwin-180792321.tar.bz2 + file:///opt/firestorm/kdu-7.A.5-darwin-182950050.tar.bz2 name darwin64 @@ -2820,9 +2820,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - bb8bed08fd5973a040c509ef8b545ec8 + 2c17cfd900c88914e06947fe0f1fdae4 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/490/1046/ogg_vorbis-1.2.2-1.3.2.500397-darwin64-500397.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25395/199641/ogg_vorbis-1.3.3-1.3.6.520171-darwin64-520171.tar.bz2 name darwin64 @@ -2856,9 +2856,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - f7edf86dcf2d9be7bee98c91256fa569 + 1818627d4d1f05b49709717e240bdcf4 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/512/1108/ogg_vorbis-1.2.2-1.3.2.500397-windows-500397.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25396/199634/ogg_vorbis-1.3.3-1.3.6.520171-windows-520171.tar.bz2 name windows @@ -2868,16 +2868,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 497ec6ac26c2e136ee65acbed86cb2ef + d124788c798684c890c1803fca541a10 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/511/1105/ogg_vorbis-1.2.2-1.3.2.500397-windows64-500397.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/25397/199631/ogg_vorbis-1.3.3-1.3.6.520171-windows64-520171.tar.bz2 name windows64 version - 1.2.2-1.3.2.500397 + 1.3.3-1.3.6.520171 open-libndofdev diff --git a/doc/contributions.txt b/doc/contributions.txt index c8fec8dbe8..ecae4098ce 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -344,6 +344,8 @@ Celierra Darling Chantal Harvey Charles Courtois Charlie Sazaland +Chaser Zaks + BUG-225599 Cherry Cheevers ChickyBabes Zuzu Christopher Organiser @@ -369,6 +371,7 @@ Cinder Roxley STORM-2053 STORM-2098 STORM-2113 + STORM-2116 STORM-2124 STORM-2127 STORM-2136 diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index b28b04f643..8b13789179 100644 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -1,3 +1 @@ - - diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 9af6e28115..cc45df36a7 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -2180,3 +2180,19 @@ LLAvatarAppearance::LLMaskedMorph::LLMaskedMorph(LLVisualParam *morph_target, BO target->addPendingMorphMask(); } } + +// Get attachment point name from ID +//static +std::string LLAvatarAppearance::getAttachmentPointName(S32 attachmentPointId) +{ + for (auto attachmentPoint : sAvatarXmlInfo->mAttachmentInfoList) + { + if (attachmentPoint->mAttachmentID == attachmentPointId) + { + return attachmentPoint->mName; + } + } + + return std::string(); +} +// diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 976efcbaf8..d539226dc0 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -228,6 +228,10 @@ protected: static LLAvatarSkeletonInfo* sAvatarSkeletonInfo; static LLAvatarXmlInfo* sAvatarXmlInfo; +// Get attachment point name from ID +public: + static std::string getAttachmentPointName(S32 attachmentPointId); +// /** Skeleton ** ** diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp index 29642be099..381665a1d5 100644 --- a/indra/llappearance/llavatarjoint.cpp +++ b/indra/llappearance/llavatarjoint.cpp @@ -181,7 +181,11 @@ BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate) for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); ++iter) { - LLAvatarJoint* joint = dynamic_cast(*iter); +// Make this s static cast. The dynamic cast must be working or it would have been crashing on the nullptr in the next line. +// LLAvatarJoint* joint = dynamic_cast(*iter); + LLAvatarJoint* joint = static_cast(*iter); +// + F32 jointLOD = joint->getLOD(); if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD) diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 800add3e47..a4432a1f13 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -390,15 +390,22 @@ namespace { llifstream file(filename().c_str()); - if (file.is_open()) + if (!file.is_open()) { - LLSDSerialize::fromXML(configuration, file); + LL_WARNS() << filename() << " failed to open file; not changing configuration" << LL_ENDL; + return false; } - if (configuration.isUndefined()) + if (LLSDSerialize::fromXML(configuration, file) == LLSDParser::PARSE_FAILURE) { - LL_WARNS() << filename() << " missing, ill-formed," - " or simply undefined; not changing configuration" + LL_WARNS() << filename() << " parcing error; not changing configuration" << LL_ENDL; + return false; + } + + if (configuration.isUndefined() || !configuration.isMap() || configuration.emptyMap()) + { + LL_WARNS() << filename() << " missing, ill-formed, or simply undefined" + " content; not changing configuration" << LL_ENDL; return false; } @@ -895,19 +902,24 @@ namespace LLError setEnabledLogTypesMask(config["enabled-log-types-mask"].asInteger()); } - LLSD sets = config["settings"]; - LLSD::array_const_iterator a, end; - for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a) - { - const LLSD& entry = *a; - - ELevel level = decodeLevel(entry["level"]); - - setLevels(s->mFunctionLevelMap, entry["functions"], level); - setLevels(s->mClassLevelMap, entry["classes"], level); - setLevels(s->mFileLevelMap, entry["files"], level); - setLevels(s->mTagLevelMap, entry["tags"], level); - } + if (config.has("settings") && config["settings"].isArray()) + { + LLSD sets = config["settings"]; + LLSD::array_const_iterator a, end; + for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a) + { + const LLSD& entry = *a; + if (entry.isMap() && !entry.emptyMap()) + { + ELevel level = decodeLevel(entry["level"]); + + setLevels(s->mFunctionLevelMap, entry["functions"], level); + setLevels(s->mClassLevelMap, entry["classes"], level); + setLevels(s->mFileLevelMap, entry["files"], level); + setLevels(s->mTagLevelMap, entry["tags"], level); + } + } + } } } @@ -1068,7 +1080,7 @@ namespace } } */ - void writeToRecorders(const LLError::CallSite& site, const std::string& escaped_message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true) + void writeToRecorders(const LLError::CallSite& site, const std::string& escaped_message) { LLError::ELevel level = site.mLevel; LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig(); @@ -1092,7 +1104,7 @@ namespace } message_stream << " "; - if (show_level && r->wantsLevel()) + if (r->wantsLevel()) { message_stream << site.mLevelString; } @@ -1110,7 +1122,7 @@ namespace } message_stream << " "; - if (show_function && r->wantsFunctionName()) + if (r->wantsFunctionName()) { message_stream << site.mFunctionString; } diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 1a1f641be5..f562bdc62b 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -43,7 +43,8 @@ template class LLTextBox* LLView::getChild( LLTextBox::LLTextBox(const LLTextBox::Params& p) : LLTextBase(p), - mClickedCallback(NULL) + mClickedCallback(NULL), + mShowCursorHand(true) {} LLTextBox::~LLTextBox() @@ -107,7 +108,7 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask) BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask) { BOOL handled = LLTextBase::handleHover(x, y, mask); - if (!handled && mClickedCallback) + if (!handled && mClickedCallback && mShowCursorHand) { // Clickable text boxes change the cursor to a hand LLUI::getWindow()->setCursor(UI_CURSOR_HAND); diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 14927756a8..499042366a 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -68,6 +68,8 @@ public: /*virtual*/ LLSD getValue() const; /*virtual*/ BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); + void setShowCursorHand(bool show_cursor) { mShowCursorHand = show_cursor; } + // // Set all LLUIStrings to dirty after currency symbol change to force them to be updated. void updateCurrencySymbols() { mText.updateCurrencySymbols(); LLTextBase::setText(mText.getString()); mLabel.updateCurrencySymbols(); } @@ -78,6 +80,7 @@ protected: LLUIString mText; callback_t mClickedCallback; + bool mShowCursorHand; // Searchable text for UI filter protected: virtual std::string _getSearchText() const diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 5fe6072304..9b9a244206 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.0.1 +6.0.2 diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 7f1f3385dc..4bbb424776 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -286,6 +286,13 @@ is_running_parameters="FSRenderFriendsOnly" checkbox_control="FSRenderFriendsOnlyPersistsTP" /> + Value 3 + AvatarExtentRefreshPeriodBatch + + Comment + how many frames do we spread over by default when refreshing extents (default is 4) + Persist + 1 + Type + S32 + Value + 4 + + AvatarExtentRefreshMaxPerBatch + + Comment + how many avatars do we want to handle in total per batch (default is 5) + Persist + 1 + Type + S32 + Value + 5 + DebugAvatarAppearanceMessage Comment @@ -6526,6 +6548,28 @@ Value 0 + FSEnableAggressiveComplexityUpdates + + Comment + Enable active complexity calculations. This may have a significant detrimental performance impact if enabled. + Persist + 1 + Type + Boolean + Value + 0 + + FSDisableRiggedMeshMatrixCaching + + Comment + Disable the caching of Rigged mesh matrix pallettes.Non-persistant. + Persist + 0 + Type + Boolean + Value + 0 + FullScreenAspectRatio Comment @@ -8950,8 +8994,201 @@ Backup 0 + MeshPreviewCanvasColor + + Comment + Canvas colour for the Mesh uploader + Persist + 1 + Type + Color4 + Value + + 0.169 + 0.169 + 0.169 + 1.0 + + + MeshPreviewEdgeColor + + Comment + Edge colour for the Mesh uploader preview + Persist + 1 + Type + Color4 + Value + + 0.4 + 0.4 + 0.4 + 1.0 + + + MeshPreviewBaseColor + + Comment + Canvas colour for the Mesh uploader + Persist + 1 + Type + Color4 + Value + + 1.0 + 1.0 + 1.0 + 1.0 + + + MeshPreviewBrightnessColor + + Comment + Brightness modifier + Persist + 1 + Type + Color3 + Value + + 0.9 + 0.9 + 0.9 + + + MeshPreviewEdgeWidth + + Comment + line thickness used when display edges is selected in mesh preview + Persist + 1 + Type + F32 + Value + 1.0 + + MeshPreviewPhysicsEdgeColor + + Comment + Edge colour for the Mesh uploader physics preview + Persist + 1 + Type + Color4 + Value + + 0.0 + 0.25 + 0.5 + 0.25 + + + MeshPreviewPhysicsFillColor + + Comment + Fill colour for the Mesh uploader physics preview + Persist + 1 + Type + Color4 + Value + + 0.0 + 0.5 + 1.0 + 0.5 + + + MeshPreviewPhysicsEdgeWidth + + Comment + line thickness used when display physics is selected in mesh preview + Persist + 1 + Type + F32 + Value + 1.0 + + MeshPreviewDegenerateEdgeColor + + Comment + Edge colour for the Mesh uploader Degenerate preview + Persist + 1 + Type + Color4 + Value + + 1.0 + 0.0 + 0.0 + 1.0 + + + MeshPreviewDegenerateFillColor + + Comment + Fill colour for the Mesh uploader Degenerate preview + Persist + 1 + Type + Color4 + Value + + 1.0 + 0.0 + 0.0 + 0.5 + + + MeshPreviewDegenerateEdgeWidth + + Comment + line thickness used when display Degenerate is selected in mesh preview + Persist + 1 + Type + F32 + Value + 3.0 + + MeshPreviewDegeneratePointSize + + Comment + Large point size used to highlight degenerate triangle vertices in Mesh preview + Persist + 1 + Type + F32 + Value + 8.0 + + MeshPreviewZoomLimit + + Comment + Maximum Zoom level in preview + Persist + 1 + Type + F32 + Value + 10.0 + + FSMeshPreviewUVGuideFile + + Comment + filename of the texture to use as a UV guide for mesh preview. + Persist + 1 + Type + String + Value + salt_and_pepper.jpg + MigrateCacheDirectory - + Comment Check for old version of disk cache to migrate to current location Persist @@ -10284,7 +10521,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 13 - + PreviewRenderSize + + Comment + Resolution of the image rendered for the mesh upload preview + Persist + 1 + Type + S32 + Value + 1024 + PreviewAmbientColor Comment @@ -10301,8 +10548,6 @@ Change of this parameter will affect the layout of buttons in notification toast 1.0 - - PreviewDiffuse0 Comment @@ -11520,7 +11765,7 @@ Change of this parameter will affect the layout of buttons in notification toast RenderAnimateRes Comment - Animate rezing prims. + (Obsolete) Does nothing Animate rezing prims. Persist 1 Type @@ -24870,6 +25115,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + FSScriptInfoExtended + + Comment + If enabled, extend basic script info feature with various details useful for builders. + Persist + 1 + Type + Boolean + Value + 0 + diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl index 7f3f84398b..55f6597498 100644 --- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl @@ -91,8 +91,9 @@ void main() // Collect normal lights (need to be divided by two, as we later multiply by 2) col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz); - col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z); - col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z); - +// col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z); + col.rgb += light_diffuse[2].rgb * calcDirectionalLight(norm, light_position[2].xyz); +// col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z); + col /= 2.0; vertex_color = col*color; } diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index 84b0515e90..f842c51971 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -1684,6 +1684,7 @@ LLUUID cmdline_partial_name2key(std::string partial_name) { std::string av_name; LLStringUtil::toLower(partial_name); + LLStringUtil::replaceString(partial_name, ".", " "); FSRadar* radar = FSRadar::getInstance(); if (radar) diff --git a/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt b/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt index da36906b69..fc0cf86170 100644 --- a/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt +++ b/indra/newview/fs_resources/EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt @@ -7,7 +7,7 @@ // // Bridge platform - string BRIDGE_VERSION = "2.23"; // This should match fslslbridge.cpp + string BRIDGE_VERSION = "2.24"; // This should match fslslbridge.cpp string gLatestURL; integer gViewerIsFirestorm; integer gTryHandshakeOnce = TRUE; @@ -491,15 +491,40 @@ default else if (cmd == "getScriptInfo") { - list details = llGetObjectDetails(llList2Key(commandList, 1), ([OBJECT_NAME, OBJECT_RUNNING_SCRIPT_COUNT, OBJECT_TOTAL_SCRIPT_COUNT, OBJECT_SCRIPT_MEMORY, OBJECT_SCRIPT_TIME, OBJECT_CHARACTER_TIME])); - if (llGetListLength(details) == 6) + + key targetkey = llList2Key(commandList, 1); + integer extended = llList2Integer(commandList, 2); + integer elements; + list details; + vector currentPosition; + + if (extended) { - llOwnerSay("" + llList2CSV([llStringToBase64(llStringTrim(llList2String(details, 0), STRING_TRIM)), llList2String(details, 1), llList2String(details, 2), llList2Integer(details, 3) / 1024, llList2Float(details, 4) * 1000.0, llList2Float(details, 5) * 1000.0]) + ""); + currentPosition = llGetPos(); + details = llGetObjectDetails(targetkey, ([OBJECT_NAME, OBJECT_RUNNING_SCRIPT_COUNT, OBJECT_TOTAL_SCRIPT_COUNT, OBJECT_SCRIPT_MEMORY, OBJECT_SCRIPT_TIME, OBJECT_CHARACTER_TIME, OBJECT_DESC, OBJECT_ROOT, OBJECT_PRIM_COUNT, OBJECT_PRIM_EQUIVALENCE, OBJECT_TOTAL_INVENTORY_COUNT, OBJECT_VELOCITY, OBJECT_POS, OBJECT_ROT, OBJECT_OMEGA, OBJECT_CREATOR, OBJECT_OWNER, OBJECT_LAST_OWNER_ID, OBJECT_REZZER_KEY, OBJECT_GROUP, OBJECT_CREATION_TIME, OBJECT_PATHFINDING_TYPE, OBJECT_ATTACHED_POINT, OBJECT_TEMP_ATTACHED])); + details = details + [currentPosition, targetkey]; + elements = 26; + } + else + { + details = llGetObjectDetails(targetkey, ([OBJECT_NAME, OBJECT_RUNNING_SCRIPT_COUNT, OBJECT_TOTAL_SCRIPT_COUNT, OBJECT_SCRIPT_MEMORY, OBJECT_SCRIPT_TIME, OBJECT_CHARACTER_TIME])); + elements = 6; + } + + if (llGetListLength(details) == elements) + { + list returnedList = [llStringToBase64(llStringTrim(llList2String(details, 0), STRING_TRIM)), llList2String(details, 1), llList2String(details, 2), llList2Integer(details, 3) / 1024, llList2Float(details, 4) * 1000.0, llList2Float(details, 5) * 1000.0]; + if (extended) + { + returnedList = returnedList + [llStringToBase64(llStringTrim(llList2String(details, 6), STRING_TRIM)), llList2String(details, 7), llList2Integer(details, 8), llList2Integer(details, 9), llList2Integer(details, 10), llStringToBase64(llList2String(details, 11)), llStringToBase64(llList2String(details, 12) + " (" + (string)llVecDist(llList2Vector(details, 12), currentPosition) + " m)"), llStringToBase64(llList2String(details, 13) + " (" + (string)(RAD_TO_DEG * llRot2Euler(llList2Rot(details, 13))) + ")"), llStringToBase64(llList2String(details, 14)), llList2Key(details, 15), llList2Key(details, 16), llList2Key(details, 17), llList2Key(details, 18), llList2Key(details, 19), llList2String(details, 20), llList2Integer(details, 21), llList2Integer(details, 22), llList2Integer(details, 23), llStringToBase64(llList2String(details, 24)), llList2Key(details, 25)]; + } + llOwnerSay("" + llList2CSV(returnedList) + ""); } else { llOwnerSay(""); } + } else if (cmd == "UseLSLFlightAssist") diff --git a/indra/newview/fsareasearch.cpp b/indra/newview/fsareasearch.cpp index b54db831f2..b6af482f20 100644 --- a/indra/newview/fsareasearch.cpp +++ b/indra/newview/fsareasearch.cpp @@ -1650,7 +1650,7 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) } break; case 's': // script - FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + (*item_it)->getUUID().asString()); + FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + (*item_it)->getUUID().asString() + "|" + (gSavedSettings.getBOOL("FSScriptInfoExtended") ? "1" : "0")); break; case 'l': // blacklist { diff --git a/indra/newview/fsdata.cpp b/indra/newview/fsdata.cpp index dcd4c4c65c..0c25e81319 100644 --- a/indra/newview/fsdata.cpp +++ b/indra/newview/fsdata.cpp @@ -38,7 +38,6 @@ /* boost: will not compile unless equivalent is undef'd, beware. */ #include "fix_macros.h" #include -#include #include "llappviewer.h" #include "llagent.h" @@ -64,15 +63,6 @@ const std::string LEGACY_CLIENT_LIST_URL = "http://phoenixviewer.com/app/client_tags/client_list_v2.xml"; const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730"); -const F32 HTTP_TIMEOUT = 30.f; - -#if LL_DARWIN -size_t strnlen(const char *s, size_t n) -{ - const char *p = (const char *)memchr(s, 0, n); - return(p ? p-s : n); -} -#endif FSData::FSData() : mLegacySearch(true), @@ -306,7 +296,7 @@ void downloadError(LLSD const &aData, std::string const &aURL) void FSData::startDownload() { mFSdataFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "fsdata.xml"); - mFSdataDefaultsFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "fsdata_defaults.xml"); + mFSdataDefaultsFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, llformat("fsdata_defaults.%s.xml", LLVersionInfo::getShortVersion().c_str())); mClientTagsFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "client_list_v2.xml"); { @@ -341,8 +331,8 @@ void FSData::startDownload() } #if OPENSIM - std::string filenames[] = {"scriptlibrary_ossl.xml", "scriptlibrary_aa.xml"}; - BOOST_FOREACH(std::string script_name, filenames) + std::string filenames[] = { "scriptlibrary_ossl.xml", "scriptlibrary_aa.xml" }; + for (auto const& script_name : filenames) { std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, script_name); time_t last_modified = 0; diff --git a/indra/newview/fslslbridge.cpp b/indra/newview/fslslbridge.cpp index a1dbd4bf2b..8e44db095d 100644 --- a/indra/newview/fslslbridge.cpp +++ b/indra/newview/fslslbridge.cpp @@ -33,17 +33,19 @@ #include "apr_base64.h" // For getScriptInfo() #include "llagent.h" -#include "llattachmentsmgr.h" #include "llappearancemgr.h" +#include "llattachmentsmgr.h" +#include "llavatarappearance.h" #include "llinventoryfunctions.h" #include "llmaniptranslate.h" #include "llpreviewscript.h" #include "llselectmgr.h" +#include "llsdutil.h" +#include "llslurl.h" #include "lltrans.h" +#include "llviewerassetupload.h" #include "llviewercontrol.h" #include "llviewerregion.h" -#include "llviewerassetupload.h" -#include "llsdutil.h" #if OPENSIM #include "llviewernetwork.h" @@ -52,7 +54,7 @@ static const std::string FS_BRIDGE_FOLDER = "#LSL Bridge"; static const std::string FS_BRIDGE_CONTAINER_FOLDER = "Landscaping"; static const U32 FS_BRIDGE_MAJOR_VERSION = 2; -static const U32 FS_BRIDGE_MINOR_VERSION = 23; +static const U32 FS_BRIDGE_MINOR_VERSION = 24; static const U32 FS_MAX_MINOR_VERSION = 99; static const std::string UPLOAD_SCRIPT_CURRENT = "EBEDD1D2-A320-43f5-88CF-DD47BBCA5DFB.lsltxt"; static const std::string FS_STATE_ATTRIBUTE = "state="; @@ -79,18 +81,13 @@ private: std::string sName; }; -void uploadDone(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) -{ - FSLSLBridge::getInstance()->setTimerResult(FSLSLBridge::SCRIPT_UPLOAD_FINISHED); -} - // // // Bridge functionality // FSLSLBridge::FSLSLBridge(): mBridgeCreating(false), - mpBridge(NULL), + mpBridge(nullptr), mIsFirstCallDone(false), mAllowDetach(false), mFinishCreation(false), @@ -352,7 +349,7 @@ bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID, while (std::getline(strStreamGetScriptInfo, scriptInfoToken, ',')) { LLStringUtil::trim(scriptInfoToken); - if (scriptInfoArrayCount == 0) + if (scriptInfoArrayCount == 0 || scriptInfoArrayCount == 6 || scriptInfoArrayCount == 11 || scriptInfoArrayCount == 12 || scriptInfoArrayCount == 13 || scriptInfoArrayCount == 14 || scriptInfoArrayCount == 24) { // First value, OBJECT_NAME, should be passed from Bridge as encoded in base64 // Encoding eliminates problems with special characters and commas for CSV @@ -368,14 +365,14 @@ bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID, } else { - LL_WARNS("FSLSLBridge") << "ScriptInfo - OBJECT_NAME cannot be decoded" << LL_ENDL; + LL_WARNS("FSLSLBridge") << "ScriptInfo - value with index " << scriptInfoArrayCount << " cannot be decoded" << LL_ENDL; } } scriptInfoArray.append(scriptInfoToken); ++scriptInfoArrayCount; } - if (scriptInfoArrayCount == 6) + if (scriptInfoArrayCount == 6 || scriptInfoArrayCount == 26) { LLStringUtil::format_map_t args; args["OBJECT_NAME"] = scriptInfoArray[0].asString(); @@ -394,6 +391,31 @@ bool FSLSLBridge::lslToViewer(const std::string& message, const LLUUID& fromID, args["PATHFINDING_TEXT"] = ""; } report_to_nearby_chat(format_string(LLTrans::getString("fsbridge_script_info"), args)); + if (scriptInfoArrayCount == 26) + { + LLStringUtil::format_map_t args3; + args3["OBJECT_DESC"] = scriptInfoArray[6].asString(); + args3["OBJECT_ROOT"] = scriptInfoArray[7].asString(); + args3["OBJECT_PRIM_COUNT"] = scriptInfoArray[8].asString(); + args3["OBJECT_PRIM_EQUIVALENCE"] = scriptInfoArray[9].asString(); + args3["OBJECT_TOTAL_INVENTORY_COUNT"] = scriptInfoArray[10].asString(); + args3["OBJECT_VELOCITY"] = scriptInfoArray[11].asString(); + args3["OBJECT_POS"] = scriptInfoArray[12].asString(); + args3["OBJECT_ROT"] = scriptInfoArray[13].asString(); + args3["OBJECT_OMEGA"] = scriptInfoArray[14].asString(); + args3["OBJECT_CREATOR"] = LLSLURL("agent", scriptInfoArray[15].asUUID(), "inspect").getSLURLString(); + args3["OBJECT_OWNER"] = scriptInfoArray[16].asUUID().isNull() ? LLTrans::getString("GroupOwned") : LLSLURL("agent", scriptInfoArray[16].asUUID(), "inspect").getSLURLString(); + args3["OBJECT_LAST_OWNER_ID"] = scriptInfoArray[17].asUUID().notNull() ? LLSLURL("agent", scriptInfoArray[17].asUUID(), "inspect").getSLURLString() : "---"; + args3["OBJECT_REZZER_KEY"] = scriptInfoArray[18].asString(); + args3["OBJECT_GROUP"] = scriptInfoArray[19].asUUID().notNull() ? LLSLURL("group", scriptInfoArray[19].asUUID(), "inspect").getSLURLString() : "---"; + args3["OBJECT_CREATION_TIME"] = scriptInfoArray[20].asString(); + args3["OBJECT_PATHFINDING_TYPE"] = scriptInfoArray[21].asString(); + args3["OBJECT_ATTACHED_POINT"] = (scriptInfoArray[22].asInteger() < 1 || scriptInfoArray[22].asInteger() > 255) ? "---" : LLTrans::getString(LLAvatarAppearance::getAttachmentPointName(scriptInfoArray[22].asInteger())); + args3["OBJECT_TEMP_ATTACHED"] = scriptInfoArray[23].asInteger() == 1 ? LLTrans::getString("Yes") : LLTrans::getString("No"); + args3["AVATAR_POS"] = scriptInfoArray[24].asString(); + args3["INSPECTING_KEY"] = scriptInfoArray[25].asString(); + report_to_nearby_chat(format_string(LLTrans::getString("fsbridge_script_info_ext"), args3)); + } } else { @@ -472,7 +494,7 @@ bool FSLSLBridge::canUseBridge() return (isBridgeValid() && sUseLSLBridge && !mCurrentURL.empty()); } -bool FSLSLBridge::viewerToLSL(const std::string& message, tCallback aCallback ) +bool FSLSLBridge::viewerToLSL(const std::string& message, Callback_t aCallback) { LL_DEBUGS("FSLSLBridge") << message << LL_ENDL; @@ -481,11 +503,13 @@ bool FSLSLBridge::viewerToLSL(const std::string& message, tCallback aCallback ) return false; } - tCallback pCallback = aCallback; - if( !pCallback ) + Callback_t pCallback = aCallback; + if (!pCallback) + { pCallback = FSLSLBridgeRequest_Success; + } - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(mCurrentURL, LLSD(message), pCallback, FSLSLBridgeRequest_Failure ); + LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(mCurrentURL, LLSD(message), pCallback, FSLSLBridgeRequest_Failure); return true; } @@ -629,12 +653,12 @@ void FSLSLBridge::finishCleanUpPreCreation() for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) { LL_INFOS("FSLSLBridge") << "Bridge folder cleanup: Deleting " << (*it)->getName() << " (" << (*it)->getUUID() << ")" << LL_ENDL; - remove_inventory_item((*it)->getUUID(), NULL, true); // Don't wait for callback from server to update inventory model + remove_inventory_item((*it)->getUUID(), nullptr, true); // Don't wait for callback from server to update inventory model } gInventory.notifyObservers(); // clear the stored bridge ID - we are starting over. - mpBridge = NULL; //the object itself will get cleaned up when new one is created. + mpBridge = nullptr; //the object itself will get cleaned up when new one is created. mCurrentURL.clear(); setBridgeCreating(true); @@ -767,7 +791,7 @@ void FSLSLBridge::createNewBridge() const LLUUID libID = gInventory.getLibraryRootFolderID(); LLViewerInventoryItem* libRock = findInvObject(LIB_ROCK_NAME, libID); //shouldn't happen but just in case - if (libRock != NULL) + if (libRock) { LL_INFOS("FSLSLBridge") << "Cloning a new Bridge container from the Library..." << LL_ENDL; @@ -868,7 +892,7 @@ void FSLSLBridge::processAttach(LLViewerObject* object, const LLViewerJointAttac // AH: We need to request objects inventory first before we can // do anything with it! LL_INFOS("FSLSLBridge") << "Requesting bridge inventory contents..." << LL_ENDL; - object->registerInventoryListener(this, NULL); + object->registerInventoryListener(this, nullptr); object->requestInventory(); } else @@ -1009,14 +1033,14 @@ void FSLSLBridge::processDetach(LLViewerObject* object, const LLViewerJointAttac } mAllowDetach = false; - if (gAgentAvatarp.isNull() || (!gAgentAvatarp->isSelf()) || (attachment == NULL) || (attachment->getName() != FS_BRIDGE_ATTACHMENT_POINT_NAME)) + if (gAgentAvatarp.isNull() || (!gAgentAvatarp->isSelf()) || (!attachment) || (attachment->getName() != FS_BRIDGE_ATTACHMENT_POINT_NAME)) { LL_WARNS("FSLSLBridge") << "Couldn't detach bridge, object has wrong name or avatar wasn't self." << LL_ENDL; return; } LLViewerInventoryItem* fsObject = gInventory.getItem(object->getAttachmentItemID()); - if (fsObject == NULL) //just in case + if (!fsObject) //just in case { LL_WARNS("FSLSLBridge") << "Couldn't detach bridge. inventory object was NULL." << LL_ENDL; return; @@ -1040,7 +1064,7 @@ void FSLSLBridge::processDetach(LLViewerObject* object, const LLViewerJointAttac } if (mpBridge && mpBridge->getUUID() == fsObject->getUUID()) { - mpBridge = NULL; + mpBridge = nullptr; report_to_nearby_chat(LLTrans::getString("fsbridge_detached")); mIsFirstCallDone = false; if (mBridgeCreating) @@ -1118,8 +1142,8 @@ void FSLSLBridge::create_script_inner() const LLUUID catID = findFSCategory(); LLPointer cb = new FSLSLBridgeScriptCallback(); - create_inventory_item(gAgent.getID(), - gAgent.getSessionID(), + create_inventory_item(gAgentID, + gAgentSessionID, catID, LLTransactionID::tnull, mCurrentFullName, @@ -1129,19 +1153,11 @@ void FSLSLBridge::create_script_inner() NOT_WEARABLE, PERM_ALL, cb); - } // // Bridge rez callback // -FSLSLBridgeRezCallback::FSLSLBridgeRezCallback() -{ -} -FSLSLBridgeRezCallback::~FSLSLBridgeRezCallback() -{ -} - void FSLSLBridgeRezCallback::fire(const LLUUID& inv_item) { // this is the first attach - librock got copied and worn on hand - but the ID is now real. @@ -1191,29 +1207,6 @@ void FSLSLBridgeRezCallback::fire(const LLUUID& inv_item) // // Bridge script creation callback // -FSLSLBridgeScriptCallback::FSLSLBridgeScriptCallback() -{ -} -FSLSLBridgeScriptCallback::~FSLSLBridgeScriptCallback() -{ -} - -class FSMonoScriptAssetUpload: public LLScriptAssetUpload -{ -public: - FSMonoScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish) - : LLScriptAssetUpload( itemId, buffer, finish) - { - } - - virtual LLSD generatePostBody() - { - LLSD body = LLScriptAssetUpload::generatePostBody(); - body["target"] = "mono"; - return body; - } -}; - void FSLSLBridgeScriptCallback::fire(const LLUUID& inv_item) { if (inv_item.isNull() || !FSLSLBridge::instance().getBridgeCreating()) @@ -1238,7 +1231,7 @@ void FSLSLBridgeScriptCallback::fire(const LLUUID& inv_item) gInventory.updateItem(item); gInventory.notifyObservers(); - LLViewerObject* obj(NULL); + LLViewerObject* obj(nullptr); if (FSLSLBridge::instance().isBridgeValid()) { @@ -1259,11 +1252,14 @@ void FSLSLBridgeScriptCallback::fire(const LLUUID& inv_item) const std::string fName = prepUploadFile(buffer); if (!fName.empty()) { - LLResourceUploadInfo::ptr_t uploadInfo(new FSMonoScriptAssetUpload( inv_item, buffer, uploadDone )); - LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); - - LL_INFOS("FSLSLBridge") << "updating script ID for bridge" << LL_ENDL; + LL_INFOS("FSLSLBridge") << "Updating script ID for bridge and enqueing upload. Inventory ID: " << inv_item.asString() << LL_ENDL; FSLSLBridge::instance().mScriptItemID = inv_item; + + LLResourceUploadInfo::ptr_t uploadInfo(boost::make_shared(obj->getID(), inv_item, LLScriptAssetUpload::MONO, true, LLUUID::null, buffer, + [](LLUUID, LLUUID, LLUUID, LLSD) { + FSLSLBridge::getInstance()->setTimerResult(FSLSLBridge::SCRIPT_UPLOAD_FINISHED); + })); + LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } else { @@ -1288,14 +1284,14 @@ void FSLSLBridgeScriptCallback::fire(const LLUUID& inv_item) FSLSLBridge::instance().cleanUpBridge(); //also clean up script remains - remove_inventory_item(item->getUUID(), NULL, true); + remove_inventory_item(item->getUUID(), nullptr, true); gInventory.notifyObservers(); LL_WARNS("FSLSLBridge") << "Can't update bridge script. Purging bridge." << LL_ENDL; return; } } -std::string FSLSLBridgeScriptCallback::prepUploadFile( std::string &aBuffer ) +std::string FSLSLBridgeScriptCallback::prepUploadFile(std::string &aBuffer) { const std::string fName = gDirUtilp->getExpandedFilename(LL_PATH_FS_RESOURCES, UPLOAD_SCRIPT_CURRENT); const std::string fNew = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,UPLOAD_SCRIPT_CURRENT); @@ -1304,7 +1300,7 @@ std::string FSLSLBridgeScriptCallback::prepUploadFile( std::string &aBuffer ) if (!fpIn) { LL_WARNS("FSLSLBridge") << "Cannot open script resource file" << LL_ENDL; - return ""; + return std::string(); } fseek(fpIn, 0, SEEK_END); long lSize = ftell(fpIn); @@ -1322,13 +1318,19 @@ std::string FSLSLBridgeScriptCallback::prepUploadFile( std::string &aBuffer ) aBuffer = ( (char const*)&vctData[0] ); const std::string bridgekey = "BRIDGEKEY"; - aBuffer.replace(aBuffer.find(bridgekey), bridgekey.length(), FSLSLBridge::getInstance()->findFSCategory().asString()); + size_t pos = aBuffer.find(bridgekey); + if (pos == std::string::npos) + { + LL_WARNS("FSLSLBridge") << "Invalid bridge script" << LL_ENDL; + return std::string(); + } + aBuffer.replace(pos, bridgekey.length(), FSLSLBridge::getInstance()->findFSCategory().asString()); LLFILE *fpOut = LLFile::fopen(fNew, "wt"); if (!fpOut) { LL_WARNS("FSLSLBridge") << "Cannot open script upload file" << LL_ENDL; - return ""; + return std::string(); } if (aBuffer.size() != fwrite(aBuffer.c_str(), 1, aBuffer.size(), fpOut)) @@ -1371,7 +1373,9 @@ void FSLSLBridge::checkBridgeScriptName() cleanUpBridge(); return; } - obj->saveScript(gInventory.getItem(mScriptItemID), TRUE, false); + + LL_INFOS("FSLSLBridge") << "Saving script " << mScriptItemID.asString() << " in object" << LL_ENDL; + obj->saveScript(gInventory.getItem(mScriptItemID), TRUE, true); new FSLSLBridgeCleanupTimer(); } @@ -1383,11 +1387,11 @@ void FSLSLBridge::cleanUpBridge() if (isBridgeValid()) { - remove_inventory_item(mpBridge->getUUID(), NULL, true); + remove_inventory_item(mpBridge->getUUID(), nullptr, true); } gInventory.notifyObservers(); - mpBridge = NULL; + mpBridge = nullptr; mAllowedDetachables.clear(); setBridgeCreating(false); } @@ -1543,7 +1547,7 @@ LLViewerInventoryItem* FSLSLBridge::findInvObject(const std::string& obj_name, c LLViewerInventoryItem* item = gInventory.getItem(itemID); return item; } - return NULL; + return nullptr; } void FSLSLBridge::cleanUpBridgeFolder(const std::string& nameToCleanUp) @@ -1571,7 +1575,7 @@ void FSLSLBridge::cleanUpBridgeFolder(const std::string& nameToCleanUp) if (!itemp->getIsLinkType() && (itemp->getUUID() != mpBridge->getUUID())) { LL_INFOS("FSLSLBridge") << "Bridge folder cleanup: Deleting " << itemp->getName() << " (" << itemp->getUUID() << ")" << LL_ENDL; - remove_inventory_item(itemp->getUUID(), NULL, true); + remove_inventory_item(itemp->getUUID(), nullptr, true); } } @@ -1616,13 +1620,13 @@ void FSLSLBridge::detachOtherBridges() LLViewerInventoryItem* fsBridge = findInvObject(mCurrentFullName, catID); //detach everything except current valid bridge - if any - gInventory.collectDescendents(catID,cats,items,FALSE); + gInventory.collectDescendents(catID, cats, items, FALSE); for (LLViewerInventoryItem::item_array_t::iterator it = items.begin(); it != items.end(); ++it) { const LLViewerInventoryItem* itemp = *it; if (get_is_item_worn(itemp->getUUID()) && - ((fsBridge == NULL) || (itemp->getUUID() != fsBridge->getUUID()))) + ((!fsBridge) || (itemp->getUUID() != fsBridge->getUUID()))) { LLVOAvatarSelf::detachAttachmentIntoInventory(itemp->getUUID()); } diff --git a/indra/newview/fslslbridge.h b/indra/newview/fslslbridge.h index b0e4d5b5be..76722b8530 100644 --- a/indra/newview/fslslbridge.h +++ b/indra/newview/fslslbridge.h @@ -63,10 +63,10 @@ public: NO_TIMER }; - typedef boost::function tCallback; + typedef std::function Callback_t; bool lslToViewer(const std::string& message, const LLUUID& fromID, const LLUUID& ownerID); - bool viewerToLSL(const std::string& message, tCallback = NULL ); + bool viewerToLSL(const std::string& message, Callback_t = nullptr); bool updateBoolSettingValue(const std::string& msgVal); bool updateBoolSettingValue(const std::string& msgVal, bool contentVal); @@ -83,7 +83,7 @@ public: void setBridge(LLViewerInventoryItem* item) { mpBridge = item; }; LLViewerInventoryItem* getBridge() { return mpBridge; }; bool canUseBridge(); - bool isBridgeValid() const { return NULL != mpBridge; } + bool isBridgeValid() const { return nullptr != mpBridge; } void checkBridgeScriptName(); std::string currentFullName() { return mCurrentFullName; } @@ -147,22 +147,22 @@ protected: class FSLSLBridgeRezCallback : public LLInventoryCallback { public: - FSLSLBridgeRezCallback(); + FSLSLBridgeRezCallback() {} void fire(const LLUUID& inv_item); protected: - ~FSLSLBridgeRezCallback(); + ~FSLSLBridgeRezCallback() {} }; class FSLSLBridgeScriptCallback : public LLInventoryCallback { public: - FSLSLBridgeScriptCallback(); + FSLSLBridgeScriptCallback() {} void fire(const LLUUID& inv_item); - std::string prepUploadFile( std::string& ); + std::string prepUploadFile(std::string& aBuffer); protected: - ~FSLSLBridgeScriptCallback(); + ~FSLSLBridgeScriptCallback() {} }; class FSLSLBridgeInventoryObserver : public LLInventoryFetchDescendentsObserver @@ -174,7 +174,6 @@ public: protected: ~FSLSLBridgeInventoryObserver() {} - }; class FSLSLBridgeInventoryPreCreationCleanupObserver : public LLInventoryFetchDescendentsObserver @@ -185,14 +184,12 @@ public: protected: ~FSLSLBridgeInventoryPreCreationCleanupObserver() {} - }; - class FSLSLBridgeCleanupTimer : public LLEventTimer { public: - FSLSLBridgeCleanupTimer() : LLEventTimer(1.f) {} + FSLSLBridgeCleanupTimer() : LLEventTimer(12.f) {} BOOL tick(); }; diff --git a/indra/newview/fslslbridgerequest.cpp b/indra/newview/fslslbridgerequest.cpp index c03a8bf077..6f92921731 100644 --- a/indra/newview/fslslbridgerequest.cpp +++ b/indra/newview/fslslbridgerequest.cpp @@ -36,28 +36,28 @@ //If we get back a normal response, handle it here -void FSLSLBridgeRequest_Success( LLSD const &aData ) +void FSLSLBridgeRequest_Success(LLSD const &aData) { - LL_DEBUGS() << ll_pretty_print_sd( aData ) << LL_ENDL; + LL_DEBUGS("FSLSLBridge") << ll_pretty_print_sd(aData) << LL_ENDL; //do not use - infinite loop, only here for testing. //FSLSLBridge::instance().viewerToLSL("Response_to_response|" + strContent); } //If we get back an error (not found, etc...), handle it here -void FSLSLBridgeRequest_Failure( LLSD const &aData ) +void FSLSLBridgeRequest_Failure(LLSD const &aData) { - LL_WARNS() << "FSLSLBridgeRequest::error(" << ll_pretty_print_sd( aData ) << ")" << LL_ENDL; + LL_WARNS("FSLSLBridge") << "FSLSLBridgeRequest::error(" << ll_pretty_print_sd(aData) << ")" << LL_ENDL; } -void FSLSLBridgeRequestRadarPos_Success( LLSD const &aData ) +void FSLSLBridgeRequestRadarPos_Success(LLSD const &aData) { FSRadar* radar = FSRadar::getInstance(); - LL_DEBUGS() << ll_pretty_print_sd( aData ) << LL_ENDL; - if (radar && aData.has( LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT ) ) + LL_DEBUGS("FSLSLBridge") << ll_pretty_print_sd(aData) << LL_ENDL; + if (radar && aData.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT)) { - std::string strContent = aData[ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT ].asString(); - //LL_INFOS() << "Got info: " << strContent << LL_ENDL; - // AO: parse content into pairs of [agent UUID,agent zHeight] , update our peoplepanel radar for each one + std::string strContent = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT].asString(); + //LL_INFOS("FSLSLBridge") << "Got info: " << strContent << LL_ENDL; + // AO: parse content into pairs of [agent UUID,agent zHeight] , update our radar for each one LLUUID targetAv; F32 targetZ; @@ -74,9 +74,8 @@ void FSLSLBridgeRequestRadarPos_Success( LLSD const &aData ) if (entry) { entry->setZOffset(targetZ); - //LL_INFOS() << targetAv << " ::: " << targetZ << LL_ENDL; + //LL_INFOS("FSLSLBridge") << targetAv << " ::: " << targetZ << LL_ENDL; } } } } - diff --git a/indra/newview/fslslbridgerequest.h b/indra/newview/fslslbridgerequest.h index 45c57e932d..bfcb3d5030 100644 --- a/indra/newview/fslslbridgerequest.h +++ b/indra/newview/fslslbridgerequest.h @@ -28,8 +28,8 @@ #ifndef FS_LSLBRIDGEREQUEST_H #define FS_LSLBRIDGEREQUEST_H -void FSLSLBridgeRequest_Success( LLSD const &aData ); -void FSLSLBridgeRequest_Failure( LLSD const &aData ); -void FSLSLBridgeRequestRadarPos_Success( LLSD const &aData ); +void FSLSLBridgeRequest_Success(LLSD const &aData); +void FSLSLBridgeRequest_Failure(LLSD const &aData); +void FSLSLBridgeRequestRadarPos_Success(LLSD const &aData); #endif // FS_LSLBRIDGEREQUEST_H diff --git a/indra/newview/fspanelprofile.cpp b/indra/newview/fspanelprofile.cpp index 5de1195704..8b7f2febbb 100644 --- a/indra/newview/fspanelprofile.cpp +++ b/indra/newview/fspanelprofile.cpp @@ -162,15 +162,6 @@ void FSPanelProfileTab::setApplyProgress(bool started) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -bool enable_god() -{ - return gAgent.isGodlike(); -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - FSPanelProfileSecondLife::FSPanelProfileSecondLife() : FSPanelProfileTab() , mStatusText(NULL) @@ -217,16 +208,17 @@ BOOL FSPanelProfileSecondLife::postBuild() mStatusText->setVisible(FALSE); LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("Profile.Call", boost::bind(&FSPanelProfileSecondLife::onCallButtonClick, this)); - registrar.add("Profile.Share", boost::bind(&FSPanelProfileSecondLife::share, this)); - registrar.add("Profile.Kick", boost::bind(&FSPanelProfileSecondLife::kick, this)); - registrar.add("Profile.Freeze", boost::bind(&FSPanelProfileSecondLife::freeze, this)); - registrar.add("Profile.Unfreeze", boost::bind(&FSPanelProfileSecondLife::unfreeze, this)); - registrar.add("Profile.CSR", boost::bind(&FSPanelProfileSecondLife::csr, this)); - registrar.add("Profile.CopyNameToClipboard", boost::bind(&FSPanelProfileSecondLife::onCopyToClipboard, this)); - registrar.add("Profile.CopyURI", boost::bind(&FSPanelProfileSecondLife::onCopyURI, this)); - registrar.add("Profile.CopyKey", boost::bind(&FSPanelProfileSecondLife::onCopyKey, this)); - registrar.add("Profile.Report", boost::bind(&FSPanelProfileSecondLife::onReport, this)); + registrar.add("Profile.Call", [this](LLUICtrl*, const LLSD&) { LLAvatarActions::startCall(getAvatarId()); }); + registrar.add("Profile.AddToContactSet", [this](LLUICtrl*, const LLSD&) { LLAvatarActions::addToContactSet(getAvatarId()); }); + registrar.add("Profile.Share", [this](LLUICtrl*, const LLSD&) { LLAvatarActions::share(getAvatarId()); }); + registrar.add("Profile.Kick", [this](LLUICtrl*, const LLSD&) { LLAvatarActions::kick(getAvatarId()); }); + registrar.add("Profile.Freeze", [this](LLUICtrl*, const LLSD&) { LLAvatarActions::freeze(getAvatarId()); }); + registrar.add("Profile.Unfreeze", [this](LLUICtrl*, const LLSD&) { LLAvatarActions::unfreeze(getAvatarId()); }); + registrar.add("Profile.CSR", [this](LLUICtrl*, const LLSD&) { LLAvatarName av_name; LLAvatarNameCache::get(getAvatarId(), &av_name); std::string name = av_name.getUserName(); LLAvatarActions::csr(getAvatarId(), name); }); + registrar.add("Profile.CopyNameToClipboard", [this](LLUICtrl*, const LLSD&) { onCopyToClipboard(); }); + registrar.add("Profile.CopyURI", [this](LLUICtrl*, const LLSD&) { onCopyURI(); }); + registrar.add("Profile.CopyKey", [this](LLUICtrl*, const LLSD&) { LLClipboard::instance().copyToClipboard(utf8str_to_wstring(getAvatarId().asString()), 0, getAvatarId().asString().size() ); }); + registrar.add("Profile.Report", [this](LLUICtrl*, const LLSD&) { LLAvatarActions::report(getAvatarId()); }); mAddFriendButton->setCommitCallback(boost::bind(&FSPanelProfileSecondLife::onAddFriendButtonClick, this)); mIMButton->setCommitCallback(boost::bind(&FSPanelProfileSecondLife::onIMButtonClick, this)); @@ -239,8 +231,8 @@ BOOL FSPanelProfileSecondLife::postBuild() mDisplayNameButton->setCommitCallback(boost::bind(&FSPanelProfileSecondLife::onClickSetName, this)); LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable; - enable.add("Profile.EnableCall", boost::bind(&FSPanelProfileSecondLife::enableCall, this)); - enable.add("Profile.EnableGod", boost::bind(&enable_god)); + enable.add("Profile.EnableCall", [this](LLUICtrl*, const LLSD&) { return mVoiceStatus; }); + enable.add("Profile.EnableGod", [](LLUICtrl*, const LLSD&) { return gAgent.isGodlike(); }); mGroupList->setDoubleClickCallback(boost::bind(&FSPanelProfileSecondLife::openGroupProfile, this)); mGroupList->setReturnCallback(boost::bind(&FSPanelProfileSecondLife::openGroupProfile, this)); @@ -582,11 +574,6 @@ void FSPanelProfileSecondLife::pay() LLAvatarActions::pay(getAvatarId()); } -void FSPanelProfileSecondLife::share() -{ - LLAvatarActions::share(getAvatarId()); -} - void FSPanelProfileSecondLife::toggleBlock() { LLAvatarActions::toggleBlock(getAvatarId()); @@ -594,34 +581,6 @@ void FSPanelProfileSecondLife::toggleBlock() updateButtons(); } -bool FSPanelProfileSecondLife::enableCall() -{ - return mVoiceStatus; -} - -void FSPanelProfileSecondLife::kick() -{ - LLAvatarActions::kick(getAvatarId()); -} - -void FSPanelProfileSecondLife::freeze() -{ - LLAvatarActions::freeze(getAvatarId()); -} - -void FSPanelProfileSecondLife::unfreeze() -{ - LLAvatarActions::unfreeze(getAvatarId()); -} - -void FSPanelProfileSecondLife::csr() -{ - LLAvatarName av_name; - LLAvatarNameCache::get(getAvatarId(), &av_name); - std::string name = av_name.getUserName(); - LLAvatarActions::csr(getAvatarId(), name); -} - void FSPanelProfileSecondLife::onAddFriendButtonClick() { LLAvatarActions::requestFriendshipDialog(getAvatarId()); @@ -637,11 +596,6 @@ void FSPanelProfileSecondLife::onTeleportButtonClick() LLAvatarActions::offerTeleport(getAvatarId()); } -void FSPanelProfileSecondLife::onCallButtonClick() -{ - LLAvatarActions::startCall(getAvatarId()); -} - void FSPanelProfileSecondLife::onCopyToClipboard() { std::string name = getChild("complete_name")->getValue().asString(); @@ -654,21 +608,11 @@ void FSPanelProfileSecondLife::onCopyURI() LLClipboard::instance().copyToClipboard(utf8str_to_wstring(name), 0, name.size() ); } -void FSPanelProfileSecondLife::onCopyKey() -{ - LLClipboard::instance().copyToClipboard(utf8str_to_wstring(getAvatarId().asString()), 0, getAvatarId().asString().size() ); -} - void FSPanelProfileSecondLife::onGroupInvite() { LLAvatarActions::inviteToGroup(getAvatarId()); } -void FSPanelProfileSecondLife::onReport() -{ - LLAvatarActions::report(getAvatarId()); -} - // virtual, called by LLAvatarTracker void FSPanelProfileSecondLife::changed(U32 mask) { diff --git a/indra/newview/fspanelprofile.h b/indra/newview/fspanelprofile.h index ae8372d796..a403f805ef 100644 --- a/indra/newview/fspanelprofile.h +++ b/indra/newview/fspanelprofile.h @@ -194,11 +194,6 @@ protected: */ void pay(); - /** - * opens inventory and IM for sharing items - */ - void share(); - /** * Add/remove resident to/from your block list. */ @@ -206,23 +201,13 @@ protected: void updateButtons(); - void kick(); - void freeze(); - void unfreeze(); - void csr(); - - bool enableCall(); - void onAddFriendButtonClick(); void onIMButtonClick(); - void onCallButtonClick(); void onTeleportButtonClick(); void onCopyToClipboard(); void onCopyURI(); - void onCopyKey(); void onGroupInvite(); - void onReport(); bool isGrantedToSeeOnlineStatus(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e7ac95f5fa..644acf328f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2836,7 +2836,7 @@ bool LLAppViewer::initConfiguration() // // load defaults overide here. Can not use settings_files.xml as path is different then above loading of defaults. - std::string fsdata_defaults = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "fsdata_defaults.xml"); + std::string fsdata_defaults = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, llformat("fsdata_defaults.%s.xml", LLVersionInfo::getShortVersion().c_str())); std::string fsdata_global = "Global"; LLControlGroup* settings_group = LLControlGroup::getInstance(fsdata_global); if(settings_group && settings_group->loadFromFile(fsdata_defaults, set_defaults)) diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 4dcd06ce88..1e5d1d89f9 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -1776,7 +1776,7 @@ void LLAvatarActions::zoomIn(const LLUUID& idAgent) void LLAvatarActions::getScriptInfo(const LLUUID& idAgent) { LL_INFOS() << "Reporting Script Info for avatar: " << idAgent.asString() << LL_ENDL; - FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + idAgent.asString()); + FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + idAgent.asString() + "|" + (gSavedSettings.getBOOL("FSScriptInfoExtended") ? "1" : "0")); } diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index d0c3dafc94..0fe3b3af26 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -53,6 +53,7 @@ #include "llvocache.h" #include "llcontrolavatar.h" #include "lldrawpoolavatar.h" +#include "llskinningutil.h" const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -94,7 +95,10 @@ void LLDrawable::incrementVisible() LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE), LLTrace::MemTrackable("LLDrawable"), - mVObjp(vobj) + mVObjp(vobj), + mSkinningMatCache(nullptr), + mLastSkinningMatCacheFrame(0), + mCacheSize(0) { init(new_entry); } @@ -140,7 +144,7 @@ void LLDrawable::init(bool new_entry) llassert(!vo_entry->getGroup()); //not in the object cache octree. } - + llassert(!vo_entry || vo_entry->getEntry() == mEntry); initVisible(sCurVisible - 2);//invisible for the current frame and the last frame. @@ -164,7 +168,6 @@ void LLDrawable::unload() } facep->clearState(LLFace::RIGGED); } - pVVol->markForUpdate(TRUE); } @@ -199,8 +202,14 @@ void LLDrawable::destroy() std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); mFaces.clear(); - - + + // close up potential memory leak + if (mSkinningMatCache) + { + ll_aligned_free_16(mSkinningMatCache); + } + // + /*if (!(sNumZombieDrawables % 10)) { LL_INFOS() << "- Zombie drawables: " << sNumZombieDrawables << LL_ENDL; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index c65ccb78b7..ec970f1916 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -66,7 +66,9 @@ class LLDrawable public: LLDrawable(const LLDrawable& rhs) : LLTrace::MemTrackable("LLDrawable"), - LLViewerOctreeEntryData(rhs) + LLViewerOctreeEntryData(rhs), + mLastSkinningMatCacheFrame(0), + mCacheSize(0) { *this = rhs; } @@ -79,6 +81,12 @@ public: static void initClass(); + // per frame matrix cache + LL_ALIGN_16(LLMatrix4a* mSkinningMatCache); + U32 mLastSkinningMatCacheFrame; + U32 mCacheSize; + // + LLDrawable(LLViewerObject *vobj, bool new_entry = false); void markDead(); // Mark this drawable as dead diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 81cd2785ff..e8e79ce93b 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1954,9 +1954,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; //build matrix palette - LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + // per frame cache of skinning matrices + //LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + //U32 count = LLSkinningUtil::getMeshJointCount(skin); + //LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar); + U32 count = LLSkinningUtil::getMeshJointCount(skin); + auto mat = getCacheSkinningMats(drawable, skin, count, avatar); + // LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin); LLMatrix4a bind_shape_matrix; @@ -1992,6 +1996,40 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( } } +// cache per frame Skinning mats +LLMatrix4a* LLDrawPoolAvatar::getCacheSkinningMats(LLDrawable* drawable, const LLMeshSkinInfo* skin, + U32 count, LLVOAvatar* avatar) +{ + if (drawable->mCacheSize < count || !drawable->mSkinningMatCache) + { +// delete[](drawable->mSkinningMatCache); + if (drawable->mSkinningMatCache) + { + ll_aligned_free_16(drawable->mSkinningMatCache); + } + drawable->mCacheSize = count; +// drawable->mSkinningMatCache = new LLMatrix4a[count]; + drawable->mSkinningMatCache = (LLMatrix4a*)ll_aligned_malloc_16(sizeof(LLMatrix4a)*count); + } + + static LLCachedControl disableMatCache(gSavedSettings, "FSDisableRiggedMeshMatrixCaching"); // FIRE-23331 - disable matrix caching during appearance update due to weird side effects + if (disableMatCache || + (avatar->isSelf() && avatar->isEditingAppearance()) || + (drawable->mSkinningMatCache && LLFrameTimer::getFrameCount() != drawable->mLastSkinningMatCacheFrame)) + { +// LL_DEBUGS("Skinning") << "Call InitSkinningMatrixPalette for drawable @" << (U64)drawable << LL_ENDL; + // add caching of matrix pallette as high up the stack as we can + drawable->mLastSkinningMatCacheFrame = LLFrameTimer::getFrameCount(); + LLSkinningUtil::initSkinningMatrixPalette(drawable->mSkinningMatCache, count, skin, avatar); + } + else + { +// LL_DEBUGS("Skinning") << "Avoiding InitSkinningMatrixPalette for drawable @" << (U64)drawable << LL_ENDL; + } + return drawable->mSkinningMatCache; +} +// + void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { if (!avatar->shouldRenderRigged()) @@ -2134,11 +2172,16 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { if (sShaderLevel > 0) { - // upload matrix palette to shader - LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar); + // upload matrix palette to shader + // per frame cache of skinning matrices + //LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; + //U32 count = LLSkinningUtil::getMeshJointCount(skin); + //LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar); + U32 count = LLSkinningUtil::getMeshJointCount(skin); + auto mat = getCacheSkinningMats(drawable, skin, count, avatar); + // + stop_glerror(); F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12]; diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 128462803b..68ac46e500 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -28,6 +28,7 @@ #define LL_LLDRAWPOOLAVATAR_H #include "lldrawpool.h" +#include "fsareasearch.h" class LLVOAvatar; class LLGLSLShader; @@ -57,6 +58,7 @@ public: ~LLDrawPoolAvatar(); /*virtual*/ BOOL isDead(); + typedef enum { RIGGED_MATERIAL=0, @@ -181,6 +183,11 @@ typedef enum static LLMatrix4& getModelView(); + // per frame cache + static LLMatrix4a* getCacheSkinningMats(LLDrawable* drawable, const LLMeshSkinInfo* skin, U32 count, + LLVOAvatar* avatar); + // + /*virtual*/ LLDrawPool *instancePool(); /*virtual*/ S32 getNumPasses(); diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index fa9a0712fa..117b8f62d7 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -125,11 +125,17 @@ BOOL LLViewerDynamicTexture::render() //----------------------------------------------------------------------------- void LLViewerDynamicTexture::preRender(BOOL clear_depth) { - //only images up to 512x512 are supported - llassert(mFullHeight <= 512); - llassert(mFullWidth <= 512); + // changes to support higher resolution rendering in the preview + ////only images up to 512x512 are supported + //llassert(mFullHeight <= 512); + //llassert(mFullWidth <= 512); + gPipeline.allocatePhysicsBuffer(); + llassert(mFullWidth <= static_cast(gPipeline.mPhysicsDisplay.getWidth())); + llassert(mFullWidth <= static_cast(gPipeline.mPhysicsDisplay.getHeight())); - if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI) +// if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI) + if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI) +// { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -215,14 +221,15 @@ BOOL LLViewerDynamicTexture::updateAllInstances() { return TRUE; } - - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI; - + // changes to support higher resolution rendering in the preview + // bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI; + bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI; if (use_fbo) { - gPipeline.mWaterDis.bindTarget(); +// gPipeline.mWaterDis.bindTarget(); + gPipeline.mPhysicsDisplay.bindTarget(); } - + // LLGLSLShader::bindNoShader(); LLVertexBuffer::unbind(); @@ -258,7 +265,10 @@ BOOL LLViewerDynamicTexture::updateAllInstances() if (use_fbo) { - gPipeline.mWaterDis.flush(); + // changes to support higher resolution rendering in the preview + // gPipeline.mWaterDis.flush(); + gPipeline.mPhysicsDisplay.flush(); + // } return ret; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 945a44c814..993437f031 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -39,6 +39,7 @@ #include "llvertexbuffer.h" #include "llviewertexture.h" #include "lldrawable.h" +#include "lljoint.h" class LLFacePool; class LLVolume; @@ -267,7 +268,6 @@ public: private: LLPointer mVertexBuffer; - U32 mState; LLFacePool* mDrawPoolp; U32 mPoolType; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index c743275dc8..77a68b82ba 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -336,6 +336,7 @@ BOOL LLFloaterModelPreview::postBuild() getChild("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); getChild("show_skin_weight")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); getChild("show_joint_positions")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); + getChild("show_uv_guide")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); // - Add UV guide overlay to pmesh preview childDisable("upload_skin"); childDisable("upload_joints"); @@ -464,8 +465,11 @@ void LLFloaterModelPreview::initModelPreview() { delete mModelPreview; } - - mModelPreview = new LLModelPreview(512, 512, this ); + // mesh uploader changes to allow higher resolution render + // mModelPreview = new LLModelPreview(512, 512, this); + auto size = gSavedSettings.getS32("PreviewRenderSize"); + mModelPreview = new LLModelPreview(size, size, this ); + // mModelPreview->setPreviewTarget(16.f); mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5)); mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1)); @@ -476,7 +480,6 @@ void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl) if (mModelPreview) { mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()]; - mModelPreview->refresh(); } } @@ -704,6 +707,62 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit) } } +// extracted method to simplify changes in layout +void LLFloaterModelPreview::draw3dPreview() +{ + gGL.color3f(1.f, 1.f, 1.f); + + gGL.getTexUnit(0)->bind(mModelPreview); + + + LLView* preview_panel = getChild("preview_panel"); + + if (!preview_panel) + { + LL_WARNS() << "preview_panel not found in floater definition" << LL_ENDL; + } + LLRect rect = preview_panel->getRect(); + + if (rect != mPreviewRect) + { + mModelPreview->refresh(); + mPreviewRect = preview_panel->getRect(); + } + + // Remove QUADS rendering mode + //gGL.begin( LLRender::QUADS ); + //{ + // gGL.texCoord2f(0.f, 1.f); + // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1); + // gGL.texCoord2f(0.f, 0.f); + // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); + // gGL.texCoord2f(1.f, 0.f); + // gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom); + // gGL.texCoord2f(1.f, 1.f); + // gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1); + //} + //gGL.end(); + gGL.begin(LLRender::TRIANGLES); + { + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop - 1); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(mPreviewRect.mRight - 1, mPreviewRect.mBottom); + + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(mPreviewRect.mRight - 1, mPreviewRect.mBottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(mPreviewRect.mRight - 1, mPreviewRect.mTop - 1); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop - 1); + } + gGL.end(); + // + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +} //----------------------------------------------------------------------------- // draw() @@ -749,57 +808,62 @@ void LLFloaterModelPreview::draw() childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost)); childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size())); +// Fixup mesh uploader refactor to a function and relocate call point to allow overlaying + // if (mModelPreview->lodsReady()) + //{ + // gGL.color3f(1.f, 1.f, 1.f); - if (mModelPreview->lodsReady()) + // gGL.getTexUnit(0)->bind(mModelPreview); + + + // LLView* preview_panel = getChild("preview_panel"); + + // LLRect rect = preview_panel->getRect(); + // if (rect != mPreviewRect) + // { + // mModelPreview->refresh(); + // mPreviewRect = preview_panel->getRect(); + // } + + // // Remove QUADS rendering mode + // //gGL.begin( LLRender::QUADS ); + // //{ + // // gGL.texCoord2f(0.f, 1.f); + // // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1); + // // gGL.texCoord2f(0.f, 0.f); + // // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); + // // gGL.texCoord2f(1.f, 0.f); + // // gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom); + // // gGL.texCoord2f(1.f, 1.f); + // // gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1); + // //} + // //gGL.end(); + // gGL.begin( LLRender::TRIANGLES ); + // { + // gGL.texCoord2f(0.f, 1.f); + // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1); + // gGL.texCoord2f(0.f, 0.f); + // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); + // gGL.texCoord2f(1.f, 0.f); + // gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom); + + // gGL.texCoord2f(1.f, 0.f); + // gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom); + // gGL.texCoord2f( 1.f, 1.f ); + // gGL.vertex2i( mPreviewRect.mRight - 1, mPreviewRect.mTop - 1 ); + // gGL.texCoord2f( 0.f, 1.f ); + // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1); + // } + // gGL.end(); + // // + + // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + //} + if (!isMinimized() && mModelPreview->lodsReady()) { - gGL.color3f(1.f, 1.f, 1.f); - - gGL.getTexUnit(0)->bind(mModelPreview); - - - LLView* preview_panel = getChild("preview_panel"); - - LLRect rect = preview_panel->getRect(); - if (rect != mPreviewRect) - { - mModelPreview->refresh(); - mPreviewRect = preview_panel->getRect(); - } - - // Remove QUADS rendering mode - //gGL.begin( LLRender::QUADS ); - //{ - // gGL.texCoord2f(0.f, 1.f); - // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1); - // gGL.texCoord2f(0.f, 0.f); - // gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); - // gGL.texCoord2f(1.f, 0.f); - // gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom); - // gGL.texCoord2f(1.f, 1.f); - // gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1); - //} - //gGL.end(); - gGL.begin( LLRender::TRIANGLES ); - { - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom); - - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom); - gGL.texCoord2f( 1.f, 1.f ); - gGL.vertex2i( mPreviewRect.mRight - 1, mPreviewRect.mTop - 1 ); - gGL.texCoord2f( 0.f, 1.f ); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1); - } - gGL.end(); - // - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + draw3dPreview(); } + // } //----------------------------------------------------------------------------- @@ -1288,6 +1352,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) , mResetJoints( false ) , mModelNoErrors( true ) , mLastJointUpdate( false ) +, mHasDegenerate( false ) // { mNeedsUpdate = TRUE; mCameraDistance = 0.f; @@ -1308,6 +1373,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) mBuildQueueMode = GLOD_QUEUE_GREEDY; mBuildBorderMode = GLOD_BORDER_UNLOCK; mBuildOperator = GLOD_OPERATOR_EDGE_COLLAPSE; + mUVGuideTexture = LLViewerTextureManager::getFetchedTextureFromFile(gSavedSettings.getString("FSMeshPreviewUVGuideFile"), FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW); // - Add UV guide overlay to pmesh preview for (U32 i = 0; i < LLModel::NUM_LODS; ++i) { @@ -2876,8 +2942,20 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim void LLModelPreview::updateStatusMessages() { +// bit mask values for physics errors. used to prevent overwrite of single line status +// TODO: use this to provied multiline status + enum PhysicsError + { + NONE=0, + NOHAVOK=1, + DEGENERATE=2, + TOOMANYHULLS=4, + TOOMANYVERTSINHULL=8 + }; +// assert_main_thread(); + U32 has_physics_error{ PhysicsError::NONE }; // physics error bitmap //triangle/vertex/submesh count for each mesh asset for each lod std::vector tris[LLModel::NUM_LODS]; std::vector verts[LLModel::NUM_LODS]; @@ -2966,21 +3044,21 @@ void LLModelPreview::updateStatusMessages() { mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH]; } - - bool has_degenerate = false; - + // make has_degenerate a member so that we can use it in the render method + // has_degenerate = false + mHasDegenerate = false; {//check for degenerate triangles in physics mesh U32 lod = LLModel::LOD_PHYSICS; const LLVector4a scale(0.5f); - for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i) + for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)// make has_degenerate a member { //for each model in the lod if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty()) { //no decomp exists S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces(); - for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j) + for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)// make has_degenerate a member { //for each submesh (face), add triangles and vertices to current total LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j); - for (S32 k = 0; (k < face.mNumIndices) && !has_degenerate; ) + for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )// make has_degenerate a member { U16 index_a = face.mIndices[k+0]; U16 index_b = face.mIndices[k+1]; @@ -2992,7 +3070,7 @@ void LLModelPreview::updateStatusMessages() if (ll_is_degenerate(v1,v2,v3)) { - has_degenerate = true; + mHasDegenerate = true;// make has_degenerate a member } else { @@ -3004,6 +3082,13 @@ void LLModelPreview::updateStatusMessages() } } + // flag degenerates here rather than deferring to a MAV error later + if (mHasDegenerate) + { + has_physics_error |= PhysicsError::DEGENERATE; + } + // + mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH])); std::string mesh_status_na = mFMP->getString("mesh_status_na"); @@ -3111,14 +3196,17 @@ void LLModelPreview::updateStatusMessages() //warn if hulls have more than 256 points in them BOOL physExceededVertexLimit = FALSE; - for (U32 i = 0; mModelNoErrors && i < mModel[LLModel::LOD_PHYSICS].size(); ++i) + for (U32 i = 0; mModelNoErrors && (i < mModel[LLModel::LOD_PHYSICS].size()); ++i) { LLModel* mdl = mModel[LLModel::LOD_PHYSICS][i]; if (mdl) { - for (U32 j = 0; j < mdl->mPhysics.mHull.size(); ++j) - { + // Better error handling + auto num_hulls = mdl->mPhysics.mHull.size(); + for (U32 j = 0; j < num_hulls; ++j) + { + // if (mdl->mPhysics.mHull[j].size() > 256) { physExceededVertexLimit = TRUE; @@ -3126,18 +3214,82 @@ void LLModelPreview::updateStatusMessages() break; } } + // Better error handling + if (num_hulls > 256) // decomp cannot have more than 256 hulls (http://wiki.secondlife.com/wiki/Mesh/Mesh_physics) + { + LL_INFOS() << "Physical model " << mdl->mLabel << " exceeds 256 hull limitation." << LL_ENDL; + has_physics_error |= PhysicsError::TOOMANYHULLS; + } + // } } - mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit); - LLIconCtrl* physStatusIcon = mFMP->getChild("physics_status_message_icon"); - physStatusIcon->setVisible(physExceededVertexLimit); + if (physExceededVertexLimit) { - mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded")); - LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning"); - physStatusIcon->setImage(img); + has_physics_error |= PhysicsError::TOOMANYVERTSINHULL; } +// standardise error handling + //if (!(has_physics_error & PhysicsError::DEGENERATE)){ // only update this field (incluides clearing it) if it is not already in use. + // mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit); + // LLIconCtrl* physStatusIcon = mFMP->getChild("physics_status_message_icon"); + // physStatusIcon->setVisible(physExceededVertexLimit); + // if (physExceededVertexLimit) + // { + // mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded")); + // LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning"); + // physStatusIcon->setImage(img); + // } + //} +#ifdef OPENSIM + has_physics_error |= PhysicsError::NOHAVOK; +#endif + + auto physStatusIcon = mFMP->getChild("physics_status_message_icon"); + + if (has_physics_error != PhysicsError::NONE) + { + mFMP->childSetVisible("physics_status_message_text", true); //display or clear + physStatusIcon->setVisible(true); + // The order here is important. + if (has_physics_error & PhysicsError::TOOMANYHULLS) + { + mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_hull_limit_exceeded")); + LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error"); + physStatusIcon->setImage(img); + } + else if (has_physics_error & PhysicsError::TOOMANYVERTSINHULL) + { + mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded")); + LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error"); + physStatusIcon->setImage(img); + } + else if (has_physics_error & PhysicsError::DEGENERATE) + { + mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_degenerate_triangles")); + LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error"); + physStatusIcon->setImage(img); + } + else if (has_physics_error & PhysicsError::NOHAVOK) + { + mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_no_havok")); + LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning"); + physStatusIcon->setImage(img); + } + else + { + // This should not happen + mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_unknown_error")); + LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning"); + physStatusIcon->setImage(img); + } + } + else + { + mFMP->childSetVisible("physics_status_message_text", false); //display or clear + physStatusIcon->setVisible(false); + } +// if (getLoadState() >= LLModelLoader::ERROR_PARSING) { mModelNoErrors = false; @@ -3164,12 +3316,21 @@ void LLModelPreview::updateStatusMessages() mModelNoErrors = false; } } - - // Todo: investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics - // current use of has_degenerate won't block upload permanently - later checks will restore the button - if (!mModelNoErrors || has_degenerate) + // Improve the error checking the TO DO here is no longer applicable but not an FS comment so edited to stop it being picked up + //// To do investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics + //// current use of has_degenerate won't block upload permanently - later checks will restore the button + //if (!mModelNoErrors || mHasDegenerate) + //{ + // mFMP->childDisable("ok_btn"); + if (!mModelNoErrors || (has_physics_error > PhysicsError::NOHAVOK)) // block for all cases of phsyics error except NOHAVOK { mFMP->childDisable("ok_btn"); + mFMP->childDisable("calculate_btn"); + } + else + { + mFMP->childEnable("ok_btn"); + mFMP->childEnable("calculate_btn"); } //add up physics triangles etc @@ -3240,14 +3401,41 @@ void LLModelPreview::updateStatusMessages() mViewOption["show_physics"] = true; fmp->childSetValue("show_physics", true); } + // handle hiding of hull only explode slider + //else + //{ + // fmp->disableViewOption("show_physics"); + // mViewOption["show_physics"] = false; + // fmp->childSetValue("show_physics", false); + + //} + mViewOption["show_physics"] = true; + if (phys_hulls > 0) + { + fmp->enableViewOption("physics_explode"); + fmp->enableViewOption("exploder_label"); + fmp->childSetVisible("physics_explode", true); + fmp->childSetVisible("exploder_label", true); + } + else + { + fmp->disableViewOption("physics_explode"); + fmp->disableViewOption("exploder_label"); + fmp->childSetVisible("physics_explode", false); + fmp->childSetVisible("exploder_label", false); + } } else { fmp->disableViewOption("show_physics"); + fmp->childSetVisible("physics_explode", false); + fmp->disableViewOption("physics_explode"); + fmp->childSetVisible("exploder_label", false); + fmp->disableViewOption("exploder_label"); mViewOption["show_physics"] = false; fmp->childSetValue("show_physics", false); - } + // //bool use_hull = fmp->childGetValue("physics_use_hull").asBoolean(); @@ -3289,7 +3477,6 @@ void LLModelPreview::updateStatusMessages() { fmp->childEnable("Simplify"); } - // Enable mesh analysis in SL only for now //if (phys_tris || phys_hulls > 0) //{ @@ -3303,29 +3490,30 @@ void LLModelPreview::updateStatusMessages() fmp->childEnable("simplify_cancel"); fmp->childEnable("decompose_cancel"); } - } + // move the closing bracket for the if(fmp) to prevent possible crash + // } - - LLCtrlSelectionInterface* iface = fmp->childGetSelectionInterface("physics_lod_combo"); - S32 which_mode = 0; - S32 file_mode = 1; - if (iface) - { - which_mode = iface->getFirstSelectedIndex(); - file_mode = iface->getItemCount() - 1; - } + LLCtrlSelectionInterface* iface = fmp->childGetSelectionInterface("physics_lod_combo"); + S32 which_mode = 0; + S32 file_mode = 1; + if (iface) + { + which_mode = iface->getFirstSelectedIndex(); + file_mode = iface->getItemCount() - 1; + } - if (which_mode == file_mode) - { - mFMP->childEnable("physics_file"); - mFMP->childEnable("physics_browse"); + if (which_mode == file_mode) + { + mFMP->childEnable("physics_file"); + mFMP->childEnable("physics_browse"); + } + else + { + mFMP->childDisable("physics_file"); + mFMP->childDisable("physics_browse"); + } } - else - { - mFMP->childDisable("physics_file"); - mFMP->childDisable("physics_browse"); - } - + // LLSpinCtrl* crease = mFMP->getChild("crease_angle"); if (mRequestedCreaseAngle[mPreviewLOD] == -1.f) @@ -3806,12 +3994,32 @@ BOOL LLModelPreview::render() bool skin_weight = mViewOption["show_skin_weight"]; bool textures = mViewOption["show_textures"]; bool physics = mViewOption["show_physics"]; + bool uv_guide = mViewOption["show_uv_guide"]; // Add UV guide overlay in mesh preview + // Extra configurability, to be exposed later as controls? + static LLCachedControl canvas_col(gSavedSettings, "MeshPreviewCanvasColor"); + static LLCachedControl edge_col(gSavedSettings, "MeshPreviewEdgeColor"); + static LLCachedControl base_col(gSavedSettings, "MeshPreviewBaseColor"); + static LLCachedControl brightness(gSavedSettings, "MeshPreviewBrightnessColor"); + static LLCachedControl edge_width(gSavedSettings, "MeshPreviewEdgeWidth"); + static LLCachedControl phys_edge_col(gSavedSettings, "MeshPreviewPhysicsEdgeColor"); + static LLCachedControl phys_fill_col(gSavedSettings, "MeshPreviewPhysicsFillColor"); + static LLCachedControl phys_edge_width(gSavedSettings, "MeshPreviewPhysicsEdgeWidth"); + static LLCachedControl deg_edge_col(gSavedSettings, "MeshPreviewDegenerateEdgeColor"); + static LLCachedControl deg_fill_col(gSavedSettings, "MeshPreviewDegenerateFillColor"); + static LLCachedControl deg_edge_width(gSavedSettings, "MeshPreviewDegenerateEdgeWidth"); + static LLCachedControl deg_point_size(gSavedSettings, "MeshPreviewDegeneratePointSize"); + // S32 width = getWidth(); S32 height = getHeight(); LLGLSUIDefault def; LLGLDisable no_blend(GL_BLEND); +// Clean up render of mesh preview +// LLGLEnable blend(GL_BLEND); +// gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); +// + LLGLEnable cull(GL_CULL_FACE); LLGLDepthTest depth(GL_TRUE); LLGLDisable fog(GL_FOG); @@ -3830,9 +4038,9 @@ BOOL LLModelPreview::render() gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); gGL.loadIdentity(); - - gGL.color4f(0.169f, 0.169f, 0.169f, 1.f); - + // uploader improvements + //gGL.color4f(0.169f, 0.169f, 0.169f, 1.f); + gGL.color4fv(static_cast(canvas_col).mV); gl_rect_2d_simple( width, height ); gGL.matrixMode(LLRender::MM_PROJECTION); @@ -3980,8 +4188,11 @@ BOOL LLModelPreview::render() stop_glerror(); gGL.pushMatrix(); - const F32 BRIGHTNESS = 0.9f; - gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + // mesh uploader improvements configurable brightness + //const F32 BRIGHTNESS = 0.9f; + //gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + gGL.color4fv(edge_col().mV); + // const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; @@ -4063,19 +4274,40 @@ BOOL LLModelPreview::render() mTextureSet.insert(tex); } } + // improved mesh uploader + // else + // { + // gGL.diffuseColor4f(1,1,1,1); + // } + } + else if (uv_guide) + { + if(mUVGuideTexture) + { + if (mUVGuideTexture->getDiscardLevel() > -1) + { + gGL.getTexUnit(0)->bind(mUVGuideTexture, true); + } + } + gGL.diffuseColor4fv(static_cast(base_col).mV); + } else { - gGL.diffuseColor4f(1,1,1,1); - } + // gGL.diffuseColor4f(1,1,1,1); + gGL.diffuseColor4fv(static_cast(base_col).mV); + // + } buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.diffuseColor3f(0.4f, 0.4f, 0.4f); - + // improved mesh uploader + //gGL.diffuseColor3f(0.4f, 0.4f, 0.4f); + gGL.diffuseColor4fv(static_cast(edge_col).mV); + // if (edges) { - glLineWidth(3.f); + glLineWidth(edge_width); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -4087,11 +4319,25 @@ BOOL LLModelPreview::render() if (physics) { + // model upload improvements - use the settings + ////Vector4a physicsFillColour(0.4, 0.4, 0.4, 0.4); + //const LLColor4 physicsFillColour(0.0, 0.5, 1.0, 0.5); + ////LLVector4a physicsEdgeColour(1.0, 1.0, 0.0, 1.0); + //const LLColor4 physicsEdgeColour=physicsFillColour*0.5; + //const LLColor4 degenerateFill(1.0, 0.0, 0.0, 0.5); + //const LLColor4 degenerateEdge(1.0,0.0,0.0,1.0); + // + glClear(GL_DEPTH_BUFFER_BIT); - - for (U32 i = 0; i < 2; i++) + // refactor to remove silly variable names + // for (U32 i = 0; i < 2; i++) + for (U32 pass = 0; pass < 2; pass++) + // { - if (i == 0) + // refactor to remove silly variable names + //if (i == 0) + if (pass == 0) + // { //depth only pass gGL.setColorMask(false, false); } @@ -4101,119 +4347,13 @@ BOOL LLModelPreview::render() } //enable alpha blending on second pass but not first pass - LLGLState blend(GL_BLEND, i); - + // refactor to remove silly variable names + //LLGLState blend(GL_BLEND, i); + LLGLState blend(GL_BLEND, pass); + // + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) - { - LLModelInstance& instance = *iter; - - LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS]; - - if (!model) - { - continue; - } - - gGL.pushMatrix(); - LLMatrix4 mat = instance.mTransform; - - gGL.multMatrix((GLfloat*) mat.mMatrix); - - - bool render_mesh = true; - - LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; - if (decomp) - { - LLMutexLock(decomp->mMutex); - - LLModel::Decomposition& physics = model->mPhysics; - - if (!physics.mHull.empty()) - { - render_mesh = false; - - if (physics.mMesh.empty()) - { //build vertex buffer for physics mesh - gMeshRepo.buildPhysicsMesh(physics); - } - - if (!physics.mMesh.empty()) - { //render hull instead of mesh - for (U32 i = 0; i < physics.mMesh.size(); ++i) - { - if (explode > 0.f) - { - gGL.pushMatrix(); - - LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters; - offset *= explode; - - gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); - } - - static std::vector hull_colors; - - if (i+1 >= hull_colors.size()) - { - hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128)); - } - - gGL.diffuseColor4ubv(hull_colors[i].mV); - LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); - - if (explode > 0.f) - { - gGL.popMatrix(); - } - } - } - } - } - - if (render_mesh) - { - if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) - { - genBuffers(LLModel::LOD_PHYSICS, false); - } - - U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); - for (U32 i = 0; i < num_models; ++i) - { - LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.diffuseColor4f(0.4f, 0.4f, 0.0f, 0.4f); - - buffer->setBuffer(type_mask & buffer->getTypeMask()); - buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); - - gGL.diffuseColor3f(1.f, 1.f, 0.f); - - glLineWidth(2.f); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glLineWidth(1.f); - } - } - - gGL.popMatrix(); - } - - glLineWidth(3.f); - glPointSize(8.f); - gPipeline.enableLightsFullbright(LLColor4::white); - //show degenerate triangles - LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - LLGLDisable cull(GL_CULL_FACE); - gGL.diffuseColor4f(1.f,0.f,0.f,1.f); - const LLVector4a scale(0.5f); - for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) { LLModelInstance& instance = *iter; @@ -4228,9 +4368,10 @@ BOOL LLModelPreview::render() gGL.pushMatrix(); LLMatrix4 mat = instance.mTransform; - gGL.multMatrix((GLfloat*) mat.mMatrix); + gGL.multMatrix((GLfloat*)mat.mMatrix); + bool render_mesh = true; LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; if (decomp) { @@ -4238,48 +4379,177 @@ BOOL LLModelPreview::render() LLModel::Decomposition& physics = model->mPhysics; - if (physics.mHull.empty()) + if (!physics.mHull.empty()) { - if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) - { - genBuffers(LLModel::LOD_PHYSICS, false); + render_mesh = false; + + if (physics.mMesh.empty()) + { //build vertex buffer for physics mesh + gMeshRepo.buildPhysicsMesh(physics); } - - for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i) - { - LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; - buffer->setBuffer(type_mask & buffer->getTypeMask()); - - LLStrider pos_strider; - buffer->getVertexStrider(pos_strider, 0); - LLVector4a* pos = (LLVector4a*) pos_strider.get(); - - LLStrider idx; - buffer->getIndexStrider(idx, 0); - - for (U32 i = 0; i < buffer->getNumIndices(); i += 3) + if (!physics.mMesh.empty()) + { //render hull instead of mesh + for (U32 i = 0; i < physics.mMesh.size(); ++i) { - LLVector4a v1; v1.setMul(pos[*idx++], scale); - LLVector4a v2; v2.setMul(pos[*idx++], scale); - LLVector4a v3; v3.setMul(pos[*idx++], scale); - - if (ll_is_degenerate(v1,v2,v3)) + if (explode > 0.f) { - buffer->draw(LLRender::LINE_LOOP, 3, i); - buffer->draw(LLRender::POINTS, 3, i); + gGL.pushMatrix(); + + LLVector3 offset = model->mHullCenter[i] - model->mCenterOfHullCenters; + offset *= explode; + + gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); + } + + static std::vector hull_colors; + + if (i + 1 >= hull_colors.size()) + { + hull_colors.push_back(LLColor4U(rand() % 128 + 127, rand() % 128 + 127, rand() % 128 + 127, 128)); + } + + gGL.diffuseColor4ubv(hull_colors[i].mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); + + if (explode > 0.f) + { + gGL.popMatrix(); } } } } } + if (render_mesh) + { + if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) + { + genBuffers(LLModel::LOD_PHYSICS, false); + } + + U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); + if (pass > 0){ + for (U32 i = 0; i < num_models; ++i) + { + LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.diffuseColor4fv(phys_fill_col().mV); + + buffer->setBuffer(type_mask & buffer->getTypeMask()); + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0); + + gGL.diffuseColor4fv(phys_edge_col().mV); + glLineWidth(phys_edge_width); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glLineWidth(1.f); + } + } + } + gGL.popMatrix(); } - glLineWidth(1.f); - glPointSize(1.f); - gPipeline.enableLightsPreview(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + + // refactor to remove silly variable names + // also only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks] + //if (i > 0) + if (pass > 0 && mHasDegenerate) + // + { + glLineWidth(deg_edge_width); + glPointSize(deg_point_size); +// This single line is why the degenerate triangles display has been crap forever. +// gPipeline.enableLightsFullbright(LLColor4::white); + //show degenerate triangles + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + LLGLDisable cull(GL_CULL_FACE); + const LLVector4a scale(0.5f); + + for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + { + LLModelInstance& instance = *iter; + + LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS]; + + if (!model) + { + continue; + } + + gGL.pushMatrix(); + LLMatrix4 mat = instance.mTransform; + + gGL.multMatrix((GLfloat*)mat.mMatrix); + + + LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; + if (decomp) + { + LLMutexLock(decomp->mMutex); + + LLModel::Decomposition& physics = model->mPhysics; + + if (physics.mHull.empty()) + { + if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) + { + genBuffers(LLModel::LOD_PHYSICS, false); + } + + auto num_degenerate = 0; + // More nested i variable silliness + // for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i) + auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); + for (U32 v = 0; v < num_models; ++v) + { + LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v]; + // + if(buffer->getNumVerts() < 3)continue; + + buffer->setBuffer(type_mask & buffer->getTypeMask()); + + LLStrider pos_strider; + buffer->getVertexStrider(pos_strider, 0); + LLVector4a* pos = (LLVector4a*)pos_strider.get(); + + LLStrider idx; + buffer->getIndexStrider(idx, 0); + + LLVector4a v1, v2, v3; + // rename inner most i to avoid merge confusion + for (U32 indices_offset = 0; indices_offset < buffer->getNumIndices(); indices_offset += 3) + { + v1.setMul(pos[*idx++], scale); + v2.setMul(pos[*idx++], scale); + v3.setMul(pos[*idx++], scale); + + if (ll_is_degenerate(v1, v2, v3)) + { + num_degenerate++; + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + gGL.diffuseColor3fv(deg_edge_col().mV); + buffer->drawRange(LLRender::TRIANGLES, 0, 2, 3, indices_offset); + buffer->drawRange(LLRender::POINTS, 0, 2, 3, indices_offset); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + gGL.diffuseColor3fv(deg_fill_col().mV); + buffer->drawRange(LLRender::TRIANGLES, 0, 2, 3, indices_offset); + } + } + } + } + } + + gGL.popMatrix(); + } + glLineWidth(1.f); + glPointSize(1.f); + gPipeline.enableLightsPreview(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } } } } @@ -4318,12 +4588,16 @@ BOOL LLModelPreview::render() //quick 'n dirty software vertex skinning //build matrix palette - + // use Mat4a part of the caching changes, no point in using the cache itself in the preview though. + //LLMatrix4 mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; - const LLMeshSkinInfo *skin = &model->mSkinInfo; + const LLMeshSkinInfo *skin = &model->mSkinInfo; U32 count = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, - skin, getPreviewAvatar()); + //LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, + // skin, getPreviewAvatar()); + LLSkinningUtil::initSkinningMatrixPalette(mat, count, + skin, getPreviewAvatar()); + // LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); U32 max_joints = LLSkinningUtil::getMaxJointCount(); @@ -4378,16 +4652,19 @@ BOOL LLModelPreview::render() } // buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); - gGL.diffuseColor3f(0.4f, 0.4f, 0.4f); + // configurable colour and width + //gGL.diffuseColor3f(0.4f, 0.4f, 0.4f); if (edges) { - glLineWidth(3.f); + gGL.diffuseColor4fv(edge_col().mV); + glLineWidth(edge_width); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1.f); } + // } } } @@ -4445,8 +4722,11 @@ void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians) void LLModelPreview::zoom(F32 zoom_amt) { F32 new_zoom = mCameraZoom+zoom_amt; - - mCameraZoom = llclamp(new_zoom, 1.f, 10.f); + // add configurable zoom TODO: stop clamping in render + // mCameraZoom = llclamp(new_zoom, 1.f, 10.f); + static LLCachedControl zoom_limit(gSavedSettings, "MeshPreviewZoomLimit"); + mCameraZoom = llclamp(new_zoom, 1.f, zoom_limit()); + // } void LLModelPreview::pan(F32 right, F32 up) @@ -4654,11 +4934,22 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible) childSetTextArg("server_weight", "[SIM]", tbd); childSetTextArg("physics_weight", "[PH]", tbd); childSetTextArg("upload_fee", "[FEE]", tbd); - childSetTextArg("price_breakdown", "[STREAMING]", tbd); - childSetTextArg("price_breakdown", "[PHYSICS]", tbd); - childSetTextArg("price_breakdown", "[INSTANCES]", tbd); - childSetTextArg("price_breakdown", "[TEXTURES]", tbd); - childSetTextArg("price_breakdown", "[MODEL]", tbd); + // add extended info fields + //childSetTextArg("price_breakdown", "[STREAMING]", dashes); + //childSetTextArg("price_breakdown", "[PHYSICS]", dashes); + //childSetTextArg("price_breakdown", "[INSTANCES]", dashes); + //childSetTextArg("price_breakdown", "[TEXTURES]", dashes); + //childSetTextArg("price_breakdown", "[MODEL]", dashes); + std::string dashes = hasString("--") ? getString("--") : "--"; + childSetTextArg("price_breakdown", "[STREAMING]", dashes); + childSetTextArg("price_breakdown", "[PHYSICS]", dashes); + childSetTextArg("price_breakdown", "[INSTANCES]", dashes); + childSetTextArg("price_breakdown", "[TEXTURES]", dashes); + childSetTextArg("price_breakdown", "[MODEL]", dashes); + childSetTextArg("physics_breakdown", "[PCH]", dashes); + childSetTextArg("physics_breakdown", "[PM]", dashes); + childSetTextArg("physics_breakdown", "[PHU]", dashes); + // } } @@ -4708,6 +4999,16 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived() childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger())); childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger())); childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger())); +// Updates for enhanced Mesh feedback at upload + childSetTextArg("physics_breakdown", "[PCH]", llformat("%0.3f", result["model_physics_cost"]["hull"].asReal())); + childSetTextArg("physics_breakdown", "[PM]", llformat("%0.3f", result["model_physics_cost"]["mesh"].asReal())); + childSetTextArg("physics_breakdown", "[PHU]", llformat("%0.3f", result["model_physics_cost"]["decomposition"].asReal())); + childSetTextArg("streaming_breakdown", "[STR_TOTAL]", llformat("%d", result["streaming_cost"].asInteger())); + childSetTextArg("streaming_breakdown", "[STR_HIGH]", llformat("%d", result["streaming_params"]["high_lod"].asInteger())); + childSetTextArg("streaming_breakdown", "[STR_MED]", llformat("%d", result["streaming_params"]["medium_lod"].asInteger())); + childSetTextArg("streaming_breakdown", "[STR_LOW]", llformat("%d", result["streaming_params"]["low_lod"].asInteger())); + childSetTextArg("streaming_breakdown", "[STR_LOWEST]", llformat("%d", result["streaming_params"]["lowest_lod"].asInteger())); +// childSetVisible("upload_fee", true); childSetVisible("price_breakdown", true); mUploadBtn->setEnabled(isModelUploadAllowed()); diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 7ec6a58ac7..4e9b575882 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -152,6 +152,7 @@ protected: static void onAutoFillCommit(LLUICtrl*,void*); void onLODParamCommit(S32 lod, bool enforce_tri_limit); + void draw3dPreview(); static void onExplodeCommit(LLUICtrl*, void*); @@ -310,6 +311,7 @@ public: static bool sIgnoreLoadedCallback; std::vector mLodsQuery; std::vector mLodsWithParsingError; + bool mHasDegenerate; protected: @@ -337,6 +339,7 @@ private: LLFloater* mFMP; + LLPointer mUVGuideTexture; // Add UV Guide texture overlay BOOL mNeedsUpdate; bool mDirty; bool mGenLOD; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 018a8c68d6..d0d0c7ccd0 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -884,16 +884,6 @@ void LLFloaterPreference::onDoNotDisturbResponseChanged() LLFloaterPreference::~LLFloaterPreference() { - /* Dead code - "windowsize combo" is not in any of the skin files, except for the - * dutch translation, which hints at a removed control. Apart from that, I don't - * even understand what this code does O.o -Zi - // clean up user data - LLComboBox* ctrl_window_size = getChild("windowsize combo"); - for (S32 i = 0; i < ctrl_window_size->getItemCount(); i++) - { - ctrl_window_size->setCurrentByIndex(i); - }*/ - LLConversationLog::instance().removeObserver(this); delete mSearchData; @@ -3673,6 +3663,12 @@ BOOL LLPanelPreference::postBuild() { getChild("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2)); } + // Disable running multiple viewers warning + //if (hasChild("allow_multiple_viewer_check", TRUE)) + //{ + // getChild("allow_multiple_viewer_check")->setCommitCallback(boost::bind(&showMultipleViewersWarning, _1, _2)); + //} + // if (hasChild("favorites_on_login_check", TRUE)) { getChild("favorites_on_login_check")->setCommitCallback(boost::bind(&handleFavoritesOnLoginChanged, _1, _2)); @@ -3682,6 +3678,11 @@ BOOL LLPanelPreference::postBuild() // [FS Login Panel] getChild("favorites_on_login_check")->setValue(show_favorites_at_login); } + if (hasChild("mute_chb_label", TRUE)) + { + getChild("mute_chb_label")->setShowCursorHand(false); + getChild("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized)); + } //////////////////////PanelAdvanced /////////////////// if (hasChild("modifier_combo", TRUE)) @@ -3806,6 +3807,14 @@ void LLPanelPreference::saveSettings() } } +void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLSD& value) +{ + if (checkbox && checkbox->getValue()) + { + LLNotificationsUtil::add("AllowMultipleViewers"); + } +} + void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value) { if (checkbox && checkbox->getValue()) @@ -3832,6 +3841,12 @@ void LLPanelPreference::handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const } } +void LLPanelPreference::toggleMuteWhenMinimized() +{ + std::string mute("MuteWhenMinimized"); + gSavedSettings.setBOOL(mute, !gSavedSettings.getBOOL(mute)); +} + // Only enable Growl checkboxes if Growl is usable void LLPanelPreference::onEnableGrowlChanged() { diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index ec0f820ce0..0b8d96bb6b 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -331,12 +331,16 @@ protected: private: //for "Only friends and groups can call or IM me" static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&); + //for "Allow Multiple Viewers" + static void showMultipleViewersWarning(LLUICtrl*, const LLSD&); - static void showCustomPortWarning(LLUICtrl*, const LLSD&); // -WoLf + static void showCustomPortWarning(LLUICtrl*, const LLSD&); // //for "Show my Favorite Landmarks at Login" static void handleFavoritesOnLoginChanged(LLUICtrl* checkbox, const LLSD& value); + static void toggleMuteWhenMinimized(); + // Only enable Growl checkboxes if Growl is usable void onEnableGrowlChanged(); // Flash chat toolbar button notification diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp index 9664725f27..951ddcc73f 100644 --- a/indra/newview/llfloaterscriptdebug.cpp +++ b/indra/newview/llfloaterscriptdebug.cpp @@ -167,9 +167,12 @@ void LLFloaterScriptDebug::addScriptLine(const LLChat& chat) { if(objectp->isHUDAttachment()) { - ((LLViewerObject*)gAgentAvatarp)->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); - // Mark script error icons - ((LLViewerObject*)gAgentAvatarp)->getIcon()->setScriptError(); + if (isAgentAvatarValid()) + { + ((LLViewerObject*)gAgentAvatarp)->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI)); + // Mark script error icons + ((LLViewerObject*)gAgentAvatarp)->getIcon()->setScriptError(); + } } else { diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 0f0d6ddb84..7f13a136f1 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -353,8 +353,8 @@ BOOL LLFloaterWorldMap::postBuild() landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); mListLandmarkCombo = dynamic_cast(landmark_combo); - mCurZoomVal = log(LLWorldMapView::sMapScale)/log(2.f); - getChild("zoom slider")->setValue(LLWorldMapView::sMapScale); + mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f); + getChild("zoom slider")->setValue(mCurZoomVal); setDefaultBtn(NULL); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index c7a02e7115..d6683f136b 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2740,6 +2740,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // FIRE-1392: Allow dragging all asset types into Landmarks folder //const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false); + const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND, false); const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); const BOOL move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id); @@ -2747,6 +2748,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, const BOOL move_is_into_current_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_CURRENT_OUTFIT); // FIRE-1392: Allow dragging all asset types into Landmarks folder //const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id); + const BOOL move_is_into_lost_and_found = model->isObjectDescendentOf(mUUID, lost_and_found_id); //-------------------------------------------------------------------------------- // Determine if folder can be moved. @@ -2796,6 +2798,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, { is_movable = FALSE; } + if (is_movable && move_is_into_lost_and_found) + { + is_movable = FALSE; + } if (is_movable && (mUUID == model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE))) { is_movable = FALSE; @@ -3954,12 +3960,14 @@ void LLFolderBridge::perform_pasteFromClipboard() const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false); + const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND, false); const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id); const BOOL move_is_into_outfit = move_is_into_my_outfits || (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id); const BOOL move_is_into_favorites = (mUUID == favorites_id); + const BOOL move_is_into_lost_and_found = model->isObjectDescendentOf(mUUID, lost_and_found_id); std::vector objects; LLClipboard::instance().pasteFromClipboard(objects); @@ -4035,6 +4043,13 @@ void LLFolderBridge::perform_pasteFromClipboard() LLInventoryObject *obj = model->getObject(item_id); if (obj) { + if (move_is_into_lost_and_found) + { + if (LLAssetType::AT_CATEGORY == obj->getType()) + { + return; + } + } if (move_is_into_current_outfit || move_is_into_outfit) { if (item && can_move_to_outfit(item, move_is_into_current_outfit)) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 760ba93112..4c404f65b0 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1221,12 +1221,16 @@ void LLInventoryPanel::onSelectionChange(const std::deque& it mCompletionObserver->reset(); for (std::deque::const_iterator it = items.begin(); it != items.end(); ++it) { - LLUUID id = static_cast((*it)->getViewModelItem())->getUUID(); - LLViewerInventoryItem* inv_item = mInventory->getItem(id); - - if (inv_item && !inv_item->isFinished()) + LLFolderViewModelItemInventory* view_model = static_cast((*it)->getViewModelItem()); + if (view_model) { - mCompletionObserver->watchItem(id); + LLUUID id = view_model->getUUID(); + LLViewerInventoryItem* inv_item = mInventory->getItem(id); + + if (inv_item && !inv_item->isFinished()) + { + mCompletionObserver->watchItem(id); + } } } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 9b3500305a..57a8341001 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -841,11 +841,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool identical_color = false; if(mColorSwatch) - { + { LLSelectedTE::getColor(color, identical_color); + LLColor4 prev_color = mColorSwatch->get(); mColorSwatch->setOriginal(color); - mColorSwatch->set(color, TRUE); + mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable); mColorSwatch->setValid(editable); mColorSwatch->setEnabled( editable ); @@ -1463,8 +1464,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) // if (!material->getSpecularID().isNull()) { - getChild("shinycolorswatch")->setOriginal(material->getSpecularLightColor()); - getChild("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE); + LLColorSwatchCtrl* shiny_swatch = getChild("shinycolorswatch"); + LLColor4 new_color = material->getSpecularLightColor(); + LLColor4 old_color = shiny_swatch->get(); + + shiny_swatch->setOriginal(new_color); + shiny_swatch->set(new_color, force_set_values || old_color != new_color || !editable); } // Bumpy (normal) diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index b89e397ef7..06d873a5a8 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -2358,8 +2358,8 @@ class FSScriptAssetUpload: public LLScriptAssetUpload { bool m_bMono; public: - FSScriptAssetUpload( LLUUID itemId, std::string buffer, invnUploadFinish_f finish, bool a_bMono ) - : LLScriptAssetUpload( itemId, buffer, finish ) + FSScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish, bool a_bMono) + : LLScriptAssetUpload(itemId, buffer, finish) { m_bMono = a_bMono; } @@ -2367,7 +2367,7 @@ public: virtual LLSD generatePostBody() { LLSD body = LLScriptAssetUpload::generatePostBody(); - if( m_bMono ) + if (m_bMono) body["target"] = "mono"; else body["target"] = "lsl2"; @@ -2407,36 +2407,45 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/) // NaCL - LSL Preprocessor mScriptEd->enableSave(FALSE); // Clear the enable save flag (FIRE-10173) - BOOL domono = FSLSLPreprocessor::mono_directive(mScriptEd->getScriptText()); - if(domono == FALSE) + bool domono = gSavedSettings.getBOOL("FSSaveInventoryScriptsAsMono"); + if (gSavedSettings.getBOOL("_NACL_LSLPreprocessor")) { - LLSD row; - if(gSavedSettings.getBOOL("_NACL_SaveInventoryScriptsAsMono")) + bool mono_directive = FSLSLPreprocessor::mono_directive(mScriptEd->getScriptText(), domono); + + if (mono_directive != domono) { - row["columns"][0]["value"] = "Detected compile-as-LSL2 directive, but debug setting SaveInventoryScriptsAsMono overrided it."; - domono = TRUE; - }else row["columns"][0]["value"] = "Detected compile-as-LSL2 directive"; - //domono = FALSE; - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - mScriptEd->mErrorList->addElement(row); + std::string message; + if (mono_directive) + { + message = LLTrans::getString("fs_preprocessor_mono_directive_override"); + } + else + { + message = LLTrans::getString("fs_preprocessor_lsl2_directive_override"); + } + domono = mono_directive; + mScriptEd->mErrorList->addCommentText(message); + } } // NaCl End + if(inv_item) { getWindow()->incBusyCount(); mPendingUploads++; if (!url.empty()) { - // Script Preprocessor + // Script Preprocessor // std::string buffer(mScriptEd->mEditor->getText()); - std::string buffer(mScriptEd->getScriptText()); - // Script Preprocessor + std::string buffer(mScriptEd->getScriptText()); + // Script Preprocessor LLBufferedAssetUploadInfo::invnUploadFinish_f proc = boost::bind(&LLPreviewLSL::finishedLSLUpload, _1, _4); + // DoMono needs to be passed/set here. // LLResourceUploadInfo::ptr_t uploadInfo(new LLScriptAssetUpload(mItemUUID, buffer, proc)); - LLResourceUploadInfo::ptr_t uploadInfo(new FSScriptAssetUpload(mItemUUID, buffer, proc, domono )); + LLResourceUploadInfo::ptr_t uploadInfo(new FSScriptAssetUpload(mItemUUID, buffer, proc, domono )); - LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); // DoMono needs to be passed/set here. + LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } } } diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 70ef135665..1573a77bf6 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -128,49 +128,100 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin skin->mInvalidJointsScrubbed = true; } +// Per frame SkinningMatrix Caching +//void LLSkinningUtil::initSkinningMatrixPalette( +// LLMatrix4* mat, +// S32 count, +// const LLMeshSkinInfo* skin, +// LLVOAvatar *avatar) +//{ +// initJointNums(const_cast(skin), avatar); +// for (U32 j = 0; j < count; ++j) +// { +// LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); +// if (joint) +// { +//#define MAT_USE_SSE +//#ifdef MAT_USE_SSE +// LLMatrix4a bind, world, res; +// bind.loadu(skin->mInvBindMatrix[j]); +// world.loadu(joint->getWorldMatrix()); +// matMul(bind, world, res); +// memcpy(mat[j].mMatrix, res.mMatrix, 16 * sizeof(float)); +//#else +// mat[j] = skin->mInvBindMatrix[j]; +// mat[j] *= joint->getWorldMatrix(); +//#endif +// } +// else +// { +// mat[j] = skin->mInvBindMatrix[j]; +// // This shouldn't happen - in mesh upload, skinned +// // rendering should be disabled unless all joints are +// // valid. In other cases of skinned rendering, invalid +// // joints should already have been removed during scrubInvalidJoints(). +// LL_WARNS_ONCE("Avatar") << avatar->getFullname() +// << " rigged to invalid joint name " << skin->mJointNames[j] +// << " num " << skin->mJointNums[j] << LL_ENDL; +// LL_WARNS_ONCE("Avatar") << avatar->getFullname() +// << " avatar build state: isBuilt() " << avatar->isBuilt() +// << " mInitFlags " << avatar->mInitFlags << LL_ENDL; +//#if 0 +// dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); +//#endif +// } +// } +//} + +#ifndef LL_RELEASE_FOR_DOWNLOAD +static LLTrace::BlockTimerStatHandle FTM_SKINNING_INIT("Init Skinning Mats"); +#endif + void LLSkinningUtil::initSkinningMatrixPalette( - LLMatrix4* mat, + LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar) { - initJointNums(const_cast(skin), avatar); - for (U32 j = 0; j < count; ++j) +#ifndef LL_RELEASE_FOR_DOWNLOAD + // This timer is too hot for normal use (though better now with caching) + LL_RECORD_BLOCK_TIME(FTM_SKINNING_INIT); +#endif + LLMatrix4a bind[LL_MAX_JOINTS_PER_MESH_OBJECT]; + LLMatrix4a world[LL_MAX_JOINTS_PER_MESH_OBJECT]; + + initJointNums(const_cast(skin), avatar); +// TODO: Refactored to encourage the compiler to optimise better but it's too old and stubborn. Need to hand tool the SIMD. +// TODO: There are two overheads in this function casued by the unaligned loads. use Matrix4a +// TODO: getWorldMatrix forces a reverse recursion up through the skelly. Check if this is happening efficiently. + for (S32 j = 0; j < count; ++j) { LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); - if (joint) - { -#define MAT_USE_SSE -#ifdef MAT_USE_SSE - LLMatrix4a bind, world, res; - bind.loadu(skin->mInvBindMatrix[j]); - world.loadu(joint->getWorldMatrix()); - matMul(bind,world,res); - memcpy(mat[j].mMatrix,res.mMatrix,16*sizeof(float)); -#else - mat[j] = skin->mInvBindMatrix[j]; - mat[j] *= joint->getWorldMatrix(); -#endif - } - else - { - mat[j] = skin->mInvBindMatrix[j]; - // This shouldn't happen - in mesh upload, skinned - // rendering should be disabled unless all joints are - // valid. In other cases of skinned rendering, invalid - // joints should already have been removed during scrubInvalidJoints(). - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " rigged to invalid joint name " << skin->mJointNames[j] - << " num " << skin->mJointNums[j] << LL_ENDL; - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " avatar build state: isBuilt() " << avatar->isBuilt() - << " mInitFlags " << avatar->mInitFlags << LL_ENDL; -#if 0 - dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); -#endif - } + if (joint != nullptr){ + bind[j].loadu(skin->mInvBindMatrix[j]); + world[j].loadu(joint->getWorldMatrix()); + matMul(bind[j], world[j], mat[j]); + } + else + { + mat[j].loadu(skin->mInvBindMatrix[j]); + // This shouldn't happen - in mesh upload, skinned + // rendering should be disabled unless all joints are + // valid. In other cases of skinned rendering, invalid + // joints should already have been removed during scrubInvalidJoints(). + // Beq note - Oct 2018 Animesh - Many rigged meshes still fail here. ('mElbowLeeft' typo in the rigging data) + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " rigged to invalid joint name " << skin->mJointNames[j] + << " num " << skin->mJointNums[j] << LL_ENDL; + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " avatar build state: isBuilt() " << avatar->isBuilt() + << " mInitFlags " << avatar->mInitFlags << LL_ENDL; + + } +//LL_DEBUGS("Skinning") << "[" << avatar->getFullname() << "] joint(" << skin->mJointNames[j] << ") matices bind(" << bind << ") world(" << world << ")" << LL_ENDL; } } +// void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) { diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 104743a378..d626655abd 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -38,8 +38,11 @@ namespace LLSkinningUtil U32 getMaxJointCount(); U32 getMeshJointCount(const LLMeshSkinInfo *skin); void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin); - void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); - void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); + // Per frame SkinningMatrix Caching + //void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar* avatar); + void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar* avatar); + // + void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar); diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp index cbd387ef68..518c6c0ee4 100644 --- a/indra/newview/lltoastscripttextbox.cpp +++ b/indra/newview/lltoastscripttextbox.cpp @@ -28,6 +28,7 @@ #include "lltoastscripttextbox.h" +#include "lldbstrings.h" #include "lllslconstants.h" #include "llnotifications.h" #include "llstyle.h" @@ -35,15 +36,15 @@ #include "llviewertexteditor.h" const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 14; -#include "lldbstrings.h" +// *TODO: magic numbers - copied from lltoastnotifypanel.cpp(50) which was copied from llnotify.cpp(250) +const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification) : LLToastPanel(notification) { buildFromFile( "panel_notify_textbox.xml"); - mInfoText = getChild("text_editor_box"); - const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; + mInfoText = getChild("text_editor_box"); mInfoText->setMaxTextLength(MAX_LENGTH); mInfoText->setValue(notification->getMessage()); diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h index 7aee02dd00..a539124ef1 100644 --- a/indra/newview/lltoastscripttextbox.h +++ b/indra/newview/lltoastscripttextbox.h @@ -48,7 +48,7 @@ public: private: - LLTextBox* mInfoText; + LLTextEditor* mInfoText; void onClickSubmit(); void onClickIgnore(); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index fbf424f234..a7edaa8cad 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -930,7 +930,7 @@ void handleRenderFriendsOnlyChanged(const LLSD& newvalue) { LLVOAvatar* avatar = (LLVOAvatar*)*iter; - if (avatar->getID() != gAgentID && !LLAvatarActions::isFriend(avatar->getID())) + if (avatar->getID() != gAgentID && !LLAvatarActions::isFriend(avatar->getID()) && !avatar->isControlAvatar()) { gObjectList.killObject(avatar); if (LLViewerRegion::sVOCacheCullingEnabled && avatar->getRegion()) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a900d8909e..df0f0d0c13 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7406,7 +7406,7 @@ void handle_script_info() { object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID; LL_INFOS() << "Reporting Script Info for object: " << object_id.asString() << LL_ENDL; - FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + object_id.asString()); + FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + object_id.asString() + "|" + (gSavedSettings.getBOOL("FSScriptInfoExtended") ? "1" : "0")); } } @@ -10619,6 +10619,17 @@ class LLEditEnableTakeOff : public view_listener_t } }; +// Xmas present for Ansa, Animesh kill switch +class FSDerenderAnimatedObjects : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + gObjectList.killAnimatedObjects(); + return true; + } +}; + +// class LLEditTakeOff : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -11400,6 +11411,7 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction"); view_listener_t::addMenu(new FSToolsResyncAnimations(), "Tools.ResyncAnimations"); // Resync Animations view_listener_t::addMenu(new FSToolsUndeform(), "Tools.Undeform"); // FIRE-4345: Undeform + view_listener_t::addMenu(new FSDerenderAnimatedObjects(), "Tools.DerenderAnimatedObjects"); // Animesh Kill switch view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie"); view_listener_t::addMenu(new LLToolsEnableSelectNextPart(), "Tools.EnableSelectNextPart"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 763d99b0a3..1ce3e1d0b0 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -299,6 +299,12 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) // This will also trigger an onlinenotification if the user is online std::string url = gAgent.getRegionCapability("AcceptFriendship"); + // This only seems to work for offline FRs if FSUseReadOfflineMsgsCap has been used + if (!gSavedSettings.getBOOL("FSUseReadOfflineMsgsCap")) + { + url = ""; + } + // LL_DEBUGS("Friendship") << "Cap string: " << url << LL_ENDL; if (!url.empty() && payload.has("online") && payload["online"].asBoolean() == false) { @@ -338,6 +344,12 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) // We no longer notify other viewers, but we DO still send // the rejection to the simulator to delete the pending userop. std::string url = gAgent.getRegionCapability("DeclineFriendship"); + // This only seems to work for offline FRs if FSUseReadOfflineMsgsCap has been used + if (!gSavedSettings.getBOOL("FSUseReadOfflineMsgsCap")) + { + url = ""; + } + // LL_DEBUGS("Friendship") << "Cap string: " << url << LL_ENDL; if (!url.empty() && payload.has("online") && payload["online"].asBoolean() == false) { @@ -2011,7 +2023,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& { // This breaks object owner name parsing //log_message = "" + chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString("."); - log_message = chatHistory_string + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString("."); + log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString("."); // LLSD args; args["MESSAGE"] = log_message; @@ -4715,6 +4727,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **) msg->getU64Fast(_PREHASH_SoundData, _PREHASH_Handle, region_handle); msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local); msg->getF32Fast(_PREHASH_SoundData, _PREHASH_Gain, gain); + gain = llclampf(gain); // INT-141: Clamp gain to valid range // adjust sound location to true global coords LLVector3d pos_global = from_region_handle(region_handle); @@ -4861,6 +4874,7 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data) msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain); msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags); + gain = llclampf(gain); // INT-141: Clamp gain to valid range LLViewerObject *objectp = gObjectList.findObject(object_id); if (objectp) @@ -4899,6 +4913,7 @@ void process_attached_sound_gain_change(LLMessageSystem *mesgsys, void **user_da } mesgsys->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain); + gain = llclampf(gain); // INT-141: Clamp gain to valid range objectp->adjustAudioGain(gain); } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 2e04022892..d827d90db6 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -996,12 +996,14 @@ void LLViewerObjectList::update(LLAgent &agent) const F64 frame_time = LLFrameTimer::getElapsedSeconds(); LLViewerObject *objectp = NULL; - + // Make a copy of the list in case something in idleUpdate() messes with it static std::vector idle_list; U32 idle_count = 0; - + // need avatar count for dynamic BB load balancing + mNumAvatars = 0; + // { LL_RECORD_BLOCK_TIME(FTM_IDLE_COPY); @@ -1015,11 +1017,15 @@ void LLViewerObjectList::update(LLAgent &agent) { idle_list.push_back( objectp ); } - else + else { idle_list[idle_count] = objectp; } ++idle_count; +// need avatar count for dynamic BB load balancing + if (objectp->isAvatar()) + mNumAvatars++; +// } else { // There shouldn't be any NULL pointers in the list, but they have caused @@ -1055,7 +1061,7 @@ void LLViewerObjectList::update(LLAgent &agent) objectp = *idle_iter; llassert(objectp->isActive()); objectp->idleUpdate(agent, frame_time); - } + } //update flexible objects LLVolumeImplFlexible::updateClass(); @@ -1497,6 +1503,29 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) return FALSE; } +// Animated Objects kill switch +void LLViewerObjectList::killAnimatedObjects() +{ + LLViewerObject *objectp; + + for (auto iter = mObjects.begin(); iter != mObjects.end(); ++iter) + { + objectp = *iter; + + if (objectp->isAnimatedObject()) + { + killObject(objectp); + if (LLViewerRegion::sVOCacheCullingEnabled && objectp->getRegion()) + { + objectp->getRegion()->killCacheEntry(objectp->getLocalID()); + } + } + } + + cleanDeadObjects(FALSE); +} +// + void LLViewerObjectList::killObjects(LLViewerRegion *regionp) { LLViewerObject *objectp; @@ -1661,9 +1690,9 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) mActiveObjects.push_back(objectp); objectp->setListIndex(mActiveObjects.size()-1); objectp->setOnActiveList(TRUE); - } - else - { + } + else + { llassert(idx < mActiveObjects.size()); llassert(mActiveObjects[idx] == objectp); @@ -1804,6 +1833,7 @@ void LLViewerObjectList::repartitionObjects() for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { LLViewerObject* objectp = *iter; + if (!objectp->isDead()) { LLDrawable* drawable = objectp->mDrawable; diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 597847278a..2a0a99f6bd 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -75,6 +75,7 @@ public: LLViewerObject *replaceObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); // TomY: hack to switch VO instances on the fly BOOL killObject(LLViewerObject *objectp); + void killAnimatedObjects(); void killObjects(LLViewerRegion *regionp); // Kill all objects owned by a particular region. void killAllObjects(); @@ -152,7 +153,6 @@ public: boost::signals2::connection setNewObjectCallback(new_object_callback_t cb); new_object_signal_t mNewObjectSignal; // - //////////////////////////////////////////// // // Only accessed by markDead in LLViewerObject @@ -162,6 +162,10 @@ public: S32 getOrphanParentCount() const { return (S32) mOrphanParents.size(); } S32 getOrphanCount() const { return mNumOrphans; } + // need avatar count for dynamic BB load balancing + S32 getAvatarCount() const { return mNumAvatars; } + // + void orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port); void findOrphans(LLViewerObject* objectp, U32 ip, U32 port); @@ -208,6 +212,9 @@ protected: std::vector mOrphanParents; // LocalID/ip,port of orphaned objects std::vector mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; + // need avatar count for dynamic BB load balancing + S32 mNumAvatars; + // typedef std::vector > vobj_list_t; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 51d845823b..b84e69e017 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -126,9 +126,9 @@ const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of le const F64 log_2 = log(2.0); #if ADDRESS_SIZE == 32 -/*const*/ U32 DESIRED_NORMAL_FETCHED_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2; // Max texture resolution +/*const*/ U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2; // Max texture resolution #else -/*const*/ U32 DESIRED_NORMAL_FETCHED_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT; // Max texture resolution +/*const*/ U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT; // Max texture resolution #endif LLUUID LLViewerTexture::sInvisiprimTexture1 = LLUUID::null; @@ -1705,10 +1705,12 @@ void LLViewerFetchedTexture::processTextureStats() else { U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 + // Keep restriction on "fetched" (seems to be HUD) textures as well if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED) { - desired_size = DESIRED_NORMAL_FETCHED_TEXTURE_SIZE; + desired_size = DESIRED_NORMAL_TEXTURE_SIZE; } + // if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight) { if (mFullWidth > desired_size || mFullHeight > desired_size) @@ -3325,6 +3327,7 @@ void LLViewerLODTexture::processTextureStats() if (mKnownDrawWidth && mKnownDrawHeight) { S32 draw_texels = mKnownDrawWidth * mKnownDrawHeight; + draw_texels = llclamp(draw_texels, MIN_IMAGE_AREA, MAX_IMAGE_AREA); // Use log_4 because we're in square-pixel space, so an image // with twice the width and twice the height will have mTexelsPerImage @@ -3365,7 +3368,7 @@ void LLViewerLODTexture::processTextureStats() U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED) { - desired_size = DESIRED_NORMAL_FETCHED_TEXTURE_SIZE; + desired_size = DESIRED_NORMAL_TEXTURE_SIZE; } if (mFullWidth > desired_size || mFullHeight > desired_size) min_discard = 1.f; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 47451ae472..ba3a35ab43 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -46,7 +46,7 @@ extern S32Megabytes gMaxVideoRam; // // Max texture resolution -extern U32 DESIRED_NORMAL_FETCHED_TEXTURE_SIZE; +extern U32 DESIRED_NORMAL_TEXTURE_SIZE; class LLFace; class LLImageGL ; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ca064a9114..2ebbf9d71b 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1966,12 +1966,12 @@ LLViewerWindow::LLViewerWindow(const Params& p) #if ADDRESS_SIZE == 64 if (gSavedSettings.getBOOL("FSRestrictMaxTextureSize")) { - DESIRED_NORMAL_FETCHED_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2; + DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2; } #else gSavedSettings.setBOOL("FSRestrictMaxTextureSize", TRUE); #endif - LL_INFOS() << "Maximum fetched texture size: " << DESIRED_NORMAL_FETCHED_TEXTURE_SIZE << "px" << LL_ENDL; + LL_INFOS() << "Maximum fetched texture size: " << DESIRED_NORMAL_TEXTURE_SIZE << "px" << LL_ENDL; // // Init the image list. Must happen after GL is initialized and before the images that diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 70fa0bf602..556966bf3d 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -211,6 +211,9 @@ const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f; const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f; const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0; +const F32 LLVOAvatar::VISUAL_COMPLEXITY_UPDATE_SECONDS = 10.0f; +const F32 VISUAL_COMPLEXITY_FRAC_CHANGE_THRESH = 0.05f; // Changes to self will not be displayed unless they exceed this fraction of previous value. +const F32 VISUAL_COMPLEXITY_ABS_CHANGE_THRESH = 1000; // ... and this absolute amount of change. const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024; enum ERenderName @@ -1390,9 +1393,10 @@ static LLTrace::BlockTimerStatHandle FTM_AVATAR_EXTENT_UPDATE("Av Upd Extent"); void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); - - S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); - +// not called as often as it used to be but still no harm in optimising +// S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); + static const LLCachedControl box_detail(gSavedSettings, "AvatarBoundingBoxComplexity"); +// // FIXME the update_min_max function used below assumes there is a // known starting point, but in general there isn't. Ideally the // box update logic should be modified to handle the no-point-yet @@ -2569,7 +2573,21 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) } // Update should be happening max once per frame. - const S32 upd_freq = 4; // force update every upd_freq frames. + // enable dynamic spreading of the BB calculations + //const S32 upd_freq = 4; // force update every upd_freq frames. + static LLCachedControl refreshPeriod(gSavedSettings, "AvatarExtentRefreshPeriodBatch"); + static LLCachedControl refreshMaxPerPeriod(gSavedSettings, "AvatarExtentRefreshMaxPerBatch"); + static S32 upd_freq = refreshPeriod; // initialise to a reasonable defauilt of 1 batch + static S32 lastRecalibrationFrame{ 0 }; + + const S32 thisFrame = LLDrawable::getCurrentFrame(); + if (thisFrame - lastRecalibrationFrame >= upd_freq) + { + // Only update at the start of a cycle. . + upd_freq = (((gObjectList.getAvatarCount() - 1) / refreshMaxPerPeriod) + 1)*refreshPeriod; + lastRecalibrationFrame = thisFrame; + } + // if ((mLastAnimExtents[0]==LLVector3())|| (mLastAnimExtents[1])==LLVector3()) { @@ -2577,7 +2595,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) } else { - mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0); + // enable dynamic spreading of the BB calculations + //mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0]) % upd_freq == 0); + mNeedsExtentUpdate = ((thisFrame + mID.mData[0]) % upd_freq == 0); + // } LLScopedContextString str("avatar_idle_update " + getFullname()); @@ -10661,8 +10682,10 @@ void LLVOAvatar::updateRiggingInfo() //LL_INFOS() << "done update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; //LL_DEBUGS("RigSpammish") << getFullname() << " after update rig tab:" << LL_ENDL; // Performance tweak - S32 joint_count, box_count; - showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + // remove debug only stuff on hot path + //S32 joint_count, box_count; + //showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + // //LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; // Performance tweak } @@ -10899,7 +10922,6 @@ void LLVOAvatar::idleUpdateRenderComplexity() void LLVOAvatar::updateVisualComplexity() { LL_DEBUGS("AvatarRender") << "avatar " << getID() << " appearance changed" << LL_ENDL; - // Set the cache time to in the past so it's updated ASAP mVisualComplexityStale = true; } @@ -11068,8 +11090,15 @@ void LLVOAvatar::calculateUpdateRenderComplexity() // Disable useless diagnostics //static std::set all_textures; - if (mVisualComplexityStale) + // remove the timer based complexity updates + //bool needs_update = mVisualComplexityStale && + // (mVisualComplexity==VISUAL_COMPLEXITY_UNKNOWN || + // mVisualComplexityUpdateTimer.getElapsedTimeF32()>VISUAL_COMPLEXITY_UPDATE_SECONDS); + bool needs_update = mVisualComplexityStale; + + if (needs_update) { + // Show per-item complexity in COF std::map item_complexity; std::map temp_item_complexity; @@ -11185,26 +11214,64 @@ void LLVOAvatar::calculateUpdateRenderComplexity() //} // - if ( cost != mVisualComplexity ) - { - LL_DEBUGS("AvatarRender") << "Avatar "<< getID() - << " complexity updated was " << mVisualComplexity << " now " << cost - << " reported " << mReportedVisualComplexity - << LL_ENDL; - } - else - { - LL_DEBUGS("AvatarRender") << "Avatar "<< getID() - << " complexity updated no change " << mVisualComplexity - << " reported " << mReportedVisualComplexity - << LL_ENDL; - } - mVisualComplexity = cost; + bool cost_changed = false; + if ( mVisualComplexity == VISUAL_COMPLEXITY_UNKNOWN) + { + LL_DEBUGS("AvatarRender") << "Avatar "<< getID() + << " complexity initialized to " << cost + << " reported " << mReportedVisualComplexity + << LL_ENDL; + cost_changed = true; + } + else + { + if ( cost != mVisualComplexity ) + { + // remove the threshold calcs + // F32 top_val = (1.0f+VISUAL_COMPLEXITY_FRAC_CHANGE_THRESH)*mVisualComplexity; + // F32 bottom_val = (1.0f/(1.0f+VISUAL_COMPLEXITY_FRAC_CHANGE_THRESH))*mVisualComplexity; + // top_val = llmax(top_val, mVisualComplexity + VISUAL_COMPLEXITY_ABS_CHANGE_THRESH); + // bottom_val = llmax(0.f, llmin(bottom_val, mVisualComplexity - VISUAL_COMPLEXITY_ABS_CHANGE_THRESH)); + + // if (isSelf() && cost > bottom_val && cost < top_val) + // { + // LL_DEBUGS("AvatarRender") << "Avatar "<< getID() + // << " self complexity change from " << mVisualComplexity << " to " << cost + // << " is within range " + // << "(" << bottom_val << "," << top_val << ")" + // << ", not updated." + // << " reported " << mReportedVisualComplexity + // << LL_ENDL; + // } + // else + // { + // LL_DEBUGS("AvatarRender") << "Avatar "<< getID() + // << " complexity updated was " << mVisualComplexity << " now " << cost + // << " reported " << mReportedVisualComplexity + // << LL_ENDL; + // cost_changed = true; + // } + //} + //else + //{ + // LL_DEBUGS("AvatarRender") << "Avatar "<< getID() + // << " complexity updated no change " << mVisualComplexity + // << " reported " << mReportedVisualComplexity + // << LL_ENDL; + cost_changed = true; + } + } + if (cost_changed) + { + mVisualComplexity = cost; + } mVisualComplexityStale = false; + // Remove the timer for now. + // mVisualComplexityUpdateTimer.reset(); static LLCachedControl show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20); - if (isSelf() && show_my_complexity_changes) + if (isSelf() && cost_changed && show_my_complexity_changes) { // Avatar complexity LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 85f22c6c86..247712efa4 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -306,6 +306,7 @@ public: // void calculateUpdateRenderComplexity(); static const U32 VISUAL_COMPLEXITY_UNKNOWN; + static const F32 VISUAL_COMPLEXITY_UPDATE_SECONDS; void updateVisualComplexity(); U32 getVisualComplexity() { return mVisualComplexity; }; // Numbers calculated here by rendering AV @@ -485,6 +486,7 @@ public: // the isTooComplex method uses these mutable values to avoid recalculating too frequently mutable U32 mVisualComplexity; mutable bool mVisualComplexityStale; + mutable LLFrameTimer mVisualComplexityUpdateTimer; U32 mReportedVisualComplexity; // from other viewers through the simulator bool mCachedInMuteList; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index ed547a28dc..3bc2f78f54 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -3200,7 +3200,6 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch) gAgentAvatarp->mIsEditingAppearance = true; gAgentAvatarp->mUseLocalAppearance = true; - if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) { gAgentCamera.changeCameraToCustomizeAvatar(); diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 4e7c48bf65..3c6f897b4c 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -904,7 +904,7 @@ void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer) void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer) { - if (mVoiceModule) mVoiceModule->removeObserver(observer); + if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); } void LLVoiceClient::addObserver(LLFriendObserver* observer) @@ -914,7 +914,7 @@ void LLVoiceClient::addObserver(LLFriendObserver* observer) void LLVoiceClient::removeObserver(LLFriendObserver* observer) { - if (mVoiceModule) mVoiceModule->removeObserver(observer); + if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); } void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) @@ -924,7 +924,7 @@ void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer) { - if (mVoiceModule) mVoiceModule->removeObserver(observer); + if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); } std::string LLVoiceClient::sipURIFromID(const LLUUID &id) diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index c9a9c772c2..cb83a0ff10 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -124,6 +124,8 @@ public: virtual const LLVoiceVersionInfo& getVersion()=0; + virtual bool singletoneInstanceExists()=0; + ///////////////////// /// @name Tuning //@{ diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 6ea661d6c6..e3ec8bc027 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -4884,6 +4884,11 @@ void LLVivoxVoiceClient::declineInvite(std::string &sessionHandle) } } +bool LLVivoxVoiceClient::singletoneInstanceExists() +{ + return LLVivoxVoiceClient::instanceExists(); +} + void LLVivoxVoiceClient::leaveNonSpatialChannel() { LL_DEBUGS("Voice") << "Request to leave spacial channel." << LL_ENDL; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index ecf48b0ee8..f46ddbf004 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -73,6 +73,8 @@ public: // Returns true if vivox has successfully logged in and is not in error state virtual bool isVoiceWorking() const; + + virtual bool singletoneInstanceExists(); ///////////////////// /// @name Tuning diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c456383ae4..c24e1b538a 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -475,6 +475,11 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { retval |= MEDIA_FLAGS_CHANGED; } + if (result && getRootEdit()->isAttachment() && getAvatarAncestor()==gAgentAvatarp ) + { + LL_INFOS("AvatarRender") << "Volume attached to self av has updated TE properties. ARC may change accordingly. Change flags " + << result << LL_ENDL; + } } else { @@ -615,6 +620,11 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, { retval |= MEDIA_FLAGS_CHANGED; } + if (result && getRootEdit()->isAttachment() && getAvatarAncestor()==gAgentAvatarp ) + { + LL_INFOS("AvatarRender") << "Volume attached to self av has updated TE properties. ARC may change accordingly. Change flags " + << result << LL_ENDL; + } } } } @@ -1641,7 +1651,11 @@ BOOL LLVOVolume::updateLOD() if (lod_changed) { - if (debugLoggingEnabled("AnimatedObjectsLinkset")) + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // { if (isAnimatedObject() && isRiggedMesh()) { @@ -4615,8 +4629,12 @@ const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const void LLVOVolume::markForUpdate(BOOL priority) { - if (debugLoggingEnabled("AnimatedObjectsLinkset")) - { + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // + { if (isAnimatedObject() && isRiggedMesh()) { std::string vobj_name = llformat("Vol%p", this); @@ -4941,6 +4959,7 @@ static LLTrace::BlockTimerStatHandle FTM_RIGGED_OCTREE("Octree"); void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume) { + bool copy = false; if (volume->getNumVolumeFaces() != getNumVolumeFaces()) { @@ -4982,7 +5001,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLMatrix4a mat[kMaxJoints]; U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin); - LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar); + // Skinning Matrix caching + //LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4)mat, maxJoints, skin, avatar); + LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar); + // S32 rigged_vert_count = 0; S32 rigged_face_count = 0; @@ -5594,7 +5616,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) vobj = bridge->mDrawable->getVObj(); vol_obj = dynamic_cast(vobj); } - if (vol_obj) + // option to reduce the number of complexity updates + // if (vol_obj) + static LLCachedControl< bool >aggressiveComplexityUpdates(gSavedSettings, "FSEnableAggressiveComplexityUpdates", false); + if (aggressiveComplexityUpdates && vol_obj) + // { vol_obj->updateVisualComplexity(); } @@ -5672,7 +5698,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } - std::string vobj_name = llformat("Vol%p", vobj); +// Stop doing stupid stuff we don;t need to. +// Moving this inside a debug enabled check +// std::string vobj_name = llformat("Vol%p", vobj); +// if (vobj->isMesh() && ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled())) @@ -5686,26 +5715,37 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) const LLVector3& scale = vobj->getScale(); group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); } - - bool is_mesh = vobj->isMesh(); - F32 est_tris = vobj->getEstTrianglesMax(); +// Stop doing stupid stuff we don;t need on the critical path + //bool is_mesh = vobj->isMesh(); + //F32 est_tris = vobj->getEstTrianglesMax(); vobj->updateControlAvatar(); - - LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment() - << " is_mesh " << is_mesh - << " est_tris " << est_tris - << " is_animated " << vobj->isAnimatedObject() - << " can_animate " << vobj->canBeAnimatedObject() - << " cav " << vobj->getControlAvatar() - << " lod " << vobj->getLOD() - << " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED)) - << " drawable state " << drawablep->getState() - << " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false) - << " frame " << LLFrameTimer::getFrameCount() - << LL_ENDL; + // Also avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // + { + std::string vobj_name = llformat("Vol%p", vobj); + bool is_mesh = vobj->isMesh(); + F32 est_tris = vobj->getEstTrianglesMax(); + + LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment() + << " is_mesh " << is_mesh + << " est_tris " << est_tris + << " is_animated " << vobj->isAnimatedObject() + << " can_animate " << vobj->canBeAnimatedObject() + << " cav " << vobj->getControlAvatar() + << " lod " << vobj->getLOD() + << " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED)) + << " drawable state " << drawablep->getState() + << " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false) + << " frame " << LLFrameTimer::getFrameCount() + << LL_ENDL; + } + // Pointless. We already checked this and have used it. + //llassert_always(vobj); - llassert_always(vobj); // Z's protection auto-derender code if (enableVolumeSAPProtection()) @@ -6245,8 +6285,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { LLVOVolume* vobj = drawablep->getVOVolume(); - if (debugLoggingEnabled("AnimatedObjectsLinkset")) - { + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // + { if (vobj->isAnimatedObject() && vobj->isRiggedMesh()) { std::string vobj_name = llformat("Vol%p", vobj); diff --git a/indra/newview/particleeditor.cpp b/indra/newview/particleeditor.cpp index 8a91d7e0eb..14d0800537 100644 --- a/indra/newview/particleeditor.cpp +++ b/indra/newview/particleeditor.cpp @@ -544,7 +544,7 @@ void ParticleEditor::onInjectButtonClicked() if (categoryID.isNull()) { std::string scriptFolderName = LLFolderType::lookup(LLFolderType::FT_LSL_TEXT); - gInventory.findCategoryByName(scriptFolderName); + categoryID = gInventory.findCategoryByName(scriptFolderName); } // if still no valid folder found bail out and complain diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 2c40c4b1d0..6090c7a8e6 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -151,7 +151,7 @@ bool LLPipeline::RenderDeferredSSAO; F32 LLPipeline::RenderShadowResolutionScale; bool LLPipeline::RenderLocalLights; bool LLPipeline::RenderDelayCreation; -bool LLPipeline::RenderAnimateRes; +//bool LLPipeline::RenderAnimateRes; FIRE-23122 BUG-225920 Remove broken RenderAnimateRes functionality. bool LLPipeline::FreezeTime; S32 LLPipeline::DebugBeaconLineWidth; F32 LLPipeline::RenderHighlightBrightness; @@ -627,7 +627,7 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderShadowResolutionScale"); connectRefreshCachedSettingsSafe("RenderLocalLights"); connectRefreshCachedSettingsSafe("RenderDelayCreation"); - connectRefreshCachedSettingsSafe("RenderAnimateRes"); +// connectRefreshCachedSettingsSafe("RenderAnimateRes"); FIRE-23122 BUG-225920 Remove broken RenderAnimateRes functionality. connectRefreshCachedSettingsSafe("FreezeTime"); connectRefreshCachedSettingsSafe("DebugBeaconLineWidth"); connectRefreshCachedSettingsSafe("RenderHighlightBrightness"); @@ -1209,7 +1209,7 @@ void LLPipeline::refreshCachedSettings() RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale"); RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights"); RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation"); - RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes"); +// RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes"); FIRE-23122 BUG-225920 Remove broken RenderAnimateRes functionality. FreezeTime = gSavedSettings.getBOOL("FreezeTime"); DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth"); RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness"); @@ -2018,14 +2018,15 @@ void LLPipeline::createObject(LLViewerObject* vobj) markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); - if (drawablep->getVOVolume() && RenderAnimateRes) - { - // fun animated res - drawablep->updateXform(TRUE); - drawablep->clearState(LLDrawable::MOVE_UNDAMPED); - drawablep->setScale(LLVector3(0,0,0)); - drawablep->makeActive(); - } + // FIRE-23122 BUG-225920 Remove broken RenderAnimateRes functionality. + //if (drawablep->getVOVolume() && RenderAnimateRes) + //{ + // // fun animated res + // drawablep->updateXform(TRUE); + // drawablep->clearState(LLDrawable::MOVE_UNDAMPED); + // drawablep->setScale(LLVector3(0,0,0)); + // drawablep->makeActive(); + //} } @@ -3483,8 +3484,12 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f { if (drawablep && !drawablep->isDead() && assertInitialized()) { - if (debugLoggingEnabled("AnimatedObjectsLinkset")) - { + // avoid unfortunate sleep during trylock by static check + //if(debugLoggingEnabled("AnimatedObjectsLinkset")) + static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset"); + if (debug_logging_on) + // + { LLVOVolume *vol_obj = drawablep->getVOVolume(); if (vol_obj && vol_obj->isAnimatedObject() && vol_obj->isRiggedMesh()) { @@ -6721,7 +6726,7 @@ void LLPipeline::enableLightsPreview() light->enable(); light->setPosition(light_pos); light->setDiffuse(diffuse0); - light->setAmbient(LLColor4::black); + light->setAmbient(ambient); light->setSpecular(specular0); light->setSpotExponent(0.f); light->setSpotCutoff(180.f); @@ -6732,7 +6737,7 @@ void LLPipeline::enableLightsPreview() light->enable(); light->setPosition(light_pos); light->setDiffuse(diffuse1); - light->setAmbient(LLColor4::black); + light->setAmbient(ambient); light->setSpecular(specular1); light->setSpotExponent(0.f); light->setSpotCutoff(180.f); @@ -6742,7 +6747,7 @@ void LLPipeline::enableLightsPreview() light->enable(); light->setPosition(light_pos); light->setDiffuse(diffuse2); - light->setAmbient(LLColor4::black); + light->setAmbient(ambient); light->setSpecular(specular2); light->setSpotExponent(0.f); light->setSpotCutoff(180.f); @@ -8867,7 +8872,8 @@ void LLPipeline::renderDeferredLighting() } const LLViewerObject *vobj = drawablep->getVObj(); - if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList()) + if(vobj && vobj->getAvatar() + && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList())) { continue; } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 53640dfa95..9e5b48a273 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -902,7 +902,7 @@ public: static F32 RenderShadowResolutionScale; static bool RenderLocalLights; static bool RenderDelayCreation; - static bool RenderAnimateRes; +// static bool RenderAnimateRes; FIRE-23122 BUG-225920 Remove broken RenderAnimateRes functionality. static bool FreezeTime; static S32 DebugBeaconLineWidth; static F32 RenderHighlightBrightness; diff --git a/indra/newview/skins/default/textures/salt_and_pepper.jpg b/indra/newview/skins/default/textures/salt_and_pepper.jpg new file mode 100644 index 0000000000..bf439b9eee Binary files /dev/null and b/indra/newview/skins/default/textures/salt_and_pepper.jpg differ diff --git a/indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml index 7afc499505..fa11e31c29 100644 --- a/indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml +++ b/indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml @@ -23,7 +23,7 @@ Name der Voreinstellung: - Hinweis: Wenn Sie den Namen Ihrer Voreinstellung ändern, entsteht eine neue Voreinstellung; die vorhandene Voreinstellung wird nicht geändert. + Hinweis: Wenn Sie den Namen Ihrer Voreinstellung ändern, erstellen Sie eine neue Voreinstellung. Die vorhandene Voreinstellung wird nicht geändert. @@ -90,7 +90,7 @@ 0:00 - 3:00 + 6:00 12:00 diff --git a/indra/newview/skins/default/xui/de/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/de/floater_edit_water_preset.xml index 20924259ec..7e1cf362f7 100644 --- a/indra/newview/skins/default/xui/de/floater_edit_water_preset.xml +++ b/indra/newview/skins/default/xui/de/floater_edit_water_preset.xml @@ -23,7 +23,7 @@ Name der Voreinstellung: - Hinweis: Wenn Sie den Namen Ihrer Voreinstellung ändern, entsteht eine neue Voreinstellung; die vorhandene Voreinstellung wird nicht geändert. + Hinweis: Wenn Sie den Namen Ihrer Voreinstellung ändern, erstellen Sie eine neue Voreinstellung. Die vorhandene Voreinstellung wird nicht geändert. diff --git a/indra/newview/skins/default/xui/de/floater_model_preview.xml b/indra/newview/skins/default/xui/de/floater_model_preview.xml index e3c4e47fa3..b448215048 100644 --- a/indra/newview/skins/default/xui/de/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/de/floater_model_preview.xml @@ -8,7 +8,7 @@ Fehler: Fehler beim DAE-Parsen – Details siehe Protokoll. - Warnung: Bind-Shape-Matrix ist nicht in Standard-X-Forward-Orientierung. + Warnung: Verbundform-Matrix befindet sich nicht in Standard-X-Vorwärtsrichtung. Fehler: Das Material des Modells ist keine Teilmenge des Referenzmodells. @@ -62,7 +62,19 @@ Detailstufenmaterial ist keine Teilmenge des Referenzmodells. - Einige physische Hüllen überschreiten die Vertexbeschränkungen. + Einige physische Hüllen überschreiten die Vertex-Limits (256). Probieren Sie andere Analyse-Methode. + + + Einige Modelle überschreiten das Hüllen-Limit (256). Probieren Sie Vereinfachen“. + + + Das Physik-Netz ist zu dicht - kleine dünne Dreiecke entfernen (siehe Vorschau) + + + Die OpenSim-Version unterstützt kein Hochladen von Physik in Second Life. Unvorhersehbare Ergebnisse möglich! + + + Ein unbekannter Fehler ist aufgetreten. Alle @@ -74,7 +86,7 @@ Vereinfachung läuft... - noch nicht festgelegt + folgt @@ -193,7 +205,7 @@ - Schritt 1: Detailstufe + Schritt 1: Physik-Modell wählen @@ -219,7 +231,7 @@ - Schritt 2: Analysieren + Schritt 2: Zu Hüllen konvertieren (optional) Methode: @@ -297,6 +309,14 @@ Z-Offset (Avatar anheben oder senken): + + + Hinweis: +Zu viele Objekte nutzen unnötigerweise den Standard-Anhängepunkt (Rechte Hand). + +Bitte ziehen Sie einen anderen Anhängepunkt nahe der Objektposition in Betracht. + + @@ -305,13 +325,13 @@