summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llappearance/llavatarappearance.cpp4
-rw-r--r--indra/llappearance/llpolymesh.cpp8
-rw-r--r--indra/llappearance/llpolymorph.cpp4
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudiodecodemgr.cpp346
-rw-r--r--indra/llaudio/llaudiodecodemgr.h15
-rw-r--r--indra/llaudio/llaudioengine.cpp114
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudioengine.h75
-rw-r--r--indra/llaudio/llaudioengine_fmodstudio.cpp18
-rw-r--r--indra/llaudio/llaudioengine_fmodstudio.h2
-rw-r--r--indra/llaudio/llaudioengine_openal.cpp6
-rw-r--r--indra/llaudio/llaudioengine_openal.h2
-rw-r--r--indra/llaudio/llstreamingaudio_fmodstudio.cpp33
-rw-r--r--indra/llcharacter/llbvhloader.cpp26
-rw-r--r--indra/llcharacter/llkeyframemotion.cpp45
-rw-r--r--indra/llcharacter/llkeyframemotion.h7
-rw-r--r--indra/llcommon/CMakeLists.txt11
-rw-r--r--indra/llcommon/llalignedarray.h10
-rw-r--r--indra/llcommon/llcoros.cpp37
-rw-r--r--indra/llcommon/llcoros.h35
-rw-r--r--indra/llcommon/llmemory.cpp8
-rw-r--r--indra/llcommon/llprocessor.cpp139
-rw-r--r--indra/llcommon/llprocessor.h5
-rw-r--r--indra/llcommon/llsys.cpp90
-rw-r--r--indra/llcommon/llsys.h12
-rw-r--r--indra/llcommon/llsys_objc.h33
-rw-r--r--indra/llcommon/llsys_objc.mm64
-rw-r--r--indra/llcommon/threadpool.cpp1
-rw-r--r--indra/llcommon/threadpool.h4
-rw-r--r--indra/llcommon/workqueue.h8
-rw-r--r--indra/llfilesystem/lldiskcache.cpp69
-rw-r--r--indra/llfilesystem/lldiskcache.h2
-rw-r--r--indra/llinventory/llparcel.cpp3
-rw-r--r--indra/llinventory/llparcel.h4
-rw-r--r--indra/llmath/lloctree.h153
-rw-r--r--indra/llmath/llvolume.cpp99
-rw-r--r--indra/llmath/llvolume.h11
-rw-r--r--indra/llmath/llvolumeoctree.cpp18
-rw-r--r--indra/llmath/llvolumeoctree.h20
-rw-r--r--indra/llmessage/llavatarnamecache.cpp4
-rw-r--r--indra/llmessage/llcoproceduremanager.h3
-rw-r--r--indra/llmessage/lldatapacker.cpp6
-rw-r--r--indra/llmessage/llpartdata.cpp5
-rw-r--r--indra/llmessage/llthrottle.cpp2
-rw-r--r--indra/llmessage/message_prehash.cpp1
-rw-r--r--indra/llmessage/message_prehash.h1
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp1
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp2
-rw-r--r--indra/llprimitive/llmodel.cpp52
-rw-r--r--indra/llprimitive/llmodel.h10
-rw-r--r--indra/llrender/llgl.cpp14
-rw-r--r--indra/llrender/llimagegl.cpp23
-rw-r--r--indra/llrender/llrender.cpp77
-rw-r--r--indra/llrender/llrender.h4
-rw-r--r--indra/llrender/llrendertarget.cpp2
-rw-r--r--indra/llrender/llshadermgr.cpp2
-rw-r--r--indra/llrender/llvertexbuffer.cpp2
-rw-r--r--indra/llrender/llvertexbuffer.h1
-rw-r--r--indra/llui/llfloater.cpp18
-rw-r--r--indra/llui/lllayoutstack.cpp2
-rw-r--r--indra/llui/llmenugl.cpp2
-rw-r--r--indra/llui/llmodaldialog.cpp14
-rw-r--r--indra/llui/llscrolllistctrl.cpp88
-rw-r--r--indra/llui/llscrolllistctrl.h10
-rw-r--r--indra/llui/lltextbase.cpp1
-rw-r--r--indra/llui/lltexteditor.h1
-rw-r--r--indra/llui/lltextutil.cpp16
-rw-r--r--indra/llui/lltextutil.h12
-rw-r--r--indra/llui/llurlaction.cpp9
-rw-r--r--indra/llui/llurlaction.h1
-rw-r--r--indra/llwindow/CMakeLists.txt6
-rw-r--r--indra/llwindow/llkeyboard.cpp16
-rw-r--r--indra/llwindow/llkeyboard.h3
-rw-r--r--indra/llwindow/llopenglview-objc.mm6
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm4
-rw-r--r--indra/llwindow/llwindowmacosx.cpp11
-rw-r--r--indra/llwindow/llwindowwin32.cpp49
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp24
-rw-r--r--indra/media_plugins/libvlc/media_plugin_libvlc.cpp80
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/key_bindings.xml1
-rw-r--r--indra/newview/app_settings/settings.xml57
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl13
-rw-r--r--indra/newview/character/avatar_skeleton.xml214
-rw-r--r--indra/newview/cube.dae103
-rw-r--r--indra/newview/installers/windows/installer_template.nsi36
-rw-r--r--indra/newview/installers/windows/lang_da.nsibin11992 -> 12802 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_de.nsi4
-rw-r--r--indra/newview/installers/windows/lang_en-us.nsibin11666 -> 12480 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_es.nsibin12976 -> 13790 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_fr.nsibin13492 -> 14302 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_it.nsibin12714 -> 13528 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ja.nsibin9880 -> 10698 bytes
-rw-r--r--indra/newview/installers/windows/lang_pl.nsibin12312 -> 13122 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_pt-br.nsibin13136 -> 13970 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ru.nsibin12450 -> 13264 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_tr.nsibin12360 -> 13174 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_zh.nsibin9324 -> 10144 bytes
-rw-r--r--indra/newview/llagent.cpp3
-rw-r--r--indra/newview/llappviewer.cpp100
-rw-r--r--indra/newview/llappviewer.h21
-rw-r--r--indra/newview/llavatarlist.cpp108
-rw-r--r--indra/newview/llavatarlist.h26
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp28
-rw-r--r--indra/newview/llchathistory.cpp57
-rw-r--r--indra/newview/llcolorswatch.cpp18
-rw-r--r--indra/newview/llconversationloglist.cpp3
-rw-r--r--indra/newview/llconversationmodel.cpp1
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp7
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.h1
-rw-r--r--indra/newview/lldrawable.h1
-rw-r--r--indra/newview/lldrawpoolalpha.cpp11
-rw-r--r--indra/newview/lldynamictexture.cpp4
-rw-r--r--indra/newview/llenvironment.cpp2
-rw-r--r--indra/newview/llfasttimerview.cpp14
-rw-r--r--indra/newview/llfavoritesbar.cpp43
-rw-r--r--indra/newview/llfloater360capture.cpp7
-rw-r--r--indra/newview/llfloater360capture.h1
-rw-r--r--indra/newview/llfloateravatarpicker.cpp3
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp10
-rw-r--r--indra/newview/llfloatercolorpicker.cpp24
-rw-r--r--indra/newview/llfloatercolorpicker.h5
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp129
-rw-r--r--indra/newview/llfloatercreatelandmark.h3
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp1
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp1
-rw-r--r--indra/newview/llfloaterhoverheight.cpp13
-rw-r--r--indra/newview/llfloaterimcontainer.cpp19
-rw-r--r--indra/newview/llfloaterland.cpp6
-rw-r--r--indra/newview/llfloaterland.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermap.cpp148
-rw-r--r--indra/newview/llfloatermap.h1
-rw-r--r--indra/newview/llfloatermarketplacelistings.cpp20
-rw-r--r--indra/newview/llfloatermediasettings.cpp12
-rw-r--r--indra/newview/llfloatermediasettings.h1
-rw-r--r--indra/newview/llfloatermodelpreview.cpp35
-rw-r--r--indra/newview/llfloatermodelpreview.h1
-rw-r--r--indra/newview/llfloaterpay.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp14
-rw-r--r--indra/newview/llfloaterregioninfo.cpp13
-rw-r--r--indra/newview/llfloaterreporter.cpp55
-rw-r--r--indra/newview/llfloaterreporter.h6
-rw-r--r--indra/newview/llfloatersearch.cpp61
-rw-r--r--indra/newview/llfloatersearch.h4
-rw-r--r--indra/newview/llfloatertools.cpp843
-rw-r--r--indra/newview/llfloatertools.h20
-rw-r--r--indra/newview/llfloaterurlentry.cpp10
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterworldmap.cpp93
-rw-r--r--indra/newview/llfloaterworldmap.h7
-rw-r--r--indra/newview/llfriendcard.cpp57
-rw-r--r--indra/newview/llfriendcard.h1
-rw-r--r--indra/newview/llgesturemgr.h2
-rw-r--r--indra/newview/llgroupactions.cpp2
-rw-r--r--indra/newview/llhudtext.cpp2
-rw-r--r--indra/newview/llimview.cpp63
-rw-r--r--indra/newview/llimview.h5
-rw-r--r--indra/newview/llinventorybridge.cpp20
-rw-r--r--indra/newview/llinventorymodel.cpp156
-rw-r--r--indra/newview/llinventorymodel.h30
-rw-r--r--indra/newview/lllegacyatmospherics.cpp20
-rw-r--r--indra/newview/lllocationinputctrl.h2
-rw-r--r--indra/newview/llmarketplacefunctions.cpp43
-rw-r--r--indra/newview/llmarketplacefunctions.h3
-rw-r--r--indra/newview/llmediadataclient.cpp3
-rw-r--r--indra/newview/llmeshrepository.cpp42
-rw-r--r--indra/newview/llmeshrepository.h5
-rw-r--r--indra/newview/llmodelpreview.cpp71
-rw-r--r--indra/newview/llmodelpreview.h17
-rw-r--r--indra/newview/llmutelist.cpp2
-rw-r--r--indra/newview/llnamelistctrl.cpp19
-rw-r--r--indra/newview/llnamelistctrl.h1
-rw-r--r--indra/newview/llnavigationbar.cpp11
-rwxr-xr-xindra/newview/llnavigationbar.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llnetmap.cpp602
-rw-r--r--indra/newview/llnetmap.h54
-rw-r--r--indra/newview/llpanelavatar.cpp2
-rw-r--r--indra/newview/llpaneleditwearable.cpp3
-rw-r--r--indra/newview/llpanelface.cpp918
-rw-r--r--indra/newview/llpanelface.h32
-rw-r--r--indra/newview/llpanellandaudio.cpp9
-rw-r--r--indra/newview/llpanellandaudio.h1
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.cpp6
-rw-r--r--indra/newview/llpanelprofile.cpp36
-rw-r--r--indra/newview/llpanelprofile.h1
-rw-r--r--indra/newview/llpanelvolume.cpp7
-rw-r--r--indra/newview/llparticipantlist.cpp170
-rw-r--r--indra/newview/llparticipantlist.h4
-rw-r--r--indra/newview/llpatchvertexarray.cpp2
-rw-r--r--indra/newview/llpersistentnotificationstorage.cpp12
-rw-r--r--indra/newview/llpersistentnotificationstorage.h1
-rw-r--r--indra/newview/llphysicsshapebuilderutil.cpp13
-rw-r--r--indra/newview/llphysicsshapebuilderutil.h1
-rw-r--r--indra/newview/llpresetsmanager.cpp2
-rw-r--r--indra/newview/llpreviewnotecard.cpp5
-rw-r--r--indra/newview/llpreviewscript.cpp5
-rw-r--r--indra/newview/llrecentpeople.cpp37
-rw-r--r--indra/newview/llrecentpeople.h13
-rw-r--r--indra/newview/llsceneview.cpp10
-rw-r--r--indra/newview/llsearchableui.h12
-rw-r--r--indra/newview/llselectmgr.cpp128
-rw-r--r--indra/newview/llselectmgr.h24
-rw-r--r--indra/newview/llspatialpartition.cpp69
-rw-r--r--indra/newview/llspatialpartition.h2
-rw-r--r--indra/newview/llspeakers.cpp2
-rw-r--r--indra/newview/llspeakers.h8
-rw-r--r--indra/newview/llstartup.cpp27
-rw-r--r--indra/newview/lltexturecache.cpp3
-rw-r--r--indra/newview/llviewerassetupload.cpp62
-rw-r--r--indra/newview/llvieweraudio.h2
-rw-r--r--indra/newview/llviewercontrol.cpp327
-rw-r--r--indra/newview/llviewerdisplay.cpp1
-rw-r--r--indra/newview/llviewermedia.cpp22
-rw-r--r--indra/newview/llviewermedia.h1
-rw-r--r--indra/newview/llviewermenu.cpp98
-rw-r--r--indra/newview/llviewermessage.cpp19
-rw-r--r--indra/newview/llviewerobject.cpp17
-rw-r--r--indra/newview/llviewerobjectlist.cpp3
-rw-r--r--indra/newview/llvieweroctree.h17
-rw-r--r--indra/newview/llviewerparcelmgr.cpp19
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparceloverlay.cpp80
-rw-r--r--indra/newview/llviewerparceloverlay.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerregion.cpp111
-rw-r--r--indra/newview/llviewerregion.h16
-rw-r--r--indra/newview/llviewershadermgr.cpp33
-rw-r--r--indra/newview/llviewershadermgr.h6
-rw-r--r--indra/newview/llviewerstats.cpp1
-rw-r--r--indra/newview/llviewertexturelist.cpp5
-rw-r--r--indra/newview/llviewerwindow.cpp19
-rw-r--r--indra/newview/llvoavatar.cpp96
-rw-r--r--indra/newview/llvoavatar.h10
-rw-r--r--indra/newview/llvocache.cpp52
-rw-r--r--indra/newview/llvoicechannel.cpp23
-rw-r--r--indra/newview/llvoiceclient.cpp1
-rw-r--r--indra/newview/llvoiceclient.h1
-rw-r--r--indra/newview/llvoicevivox.cpp56
-rw-r--r--indra/newview/llvoicevivox.h2
-rw-r--r--indra/newview/llvopartgroup.cpp6
-rw-r--r--indra/newview/llvovolume.cpp102
-rw-r--r--indra/newview/llvovolume.h10
-rw-r--r--indra/newview/llworld.cpp5
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapview.cpp277
-rw-r--r--indra/newview/llworldmapview.h43
-rw-r--r--indra/newview/llxmlrpctransaction.cpp10
-rw-r--r--indra/newview/pipeline.cpp8
-rw-r--r--indra/newview/skins/default/colors.xml12
-rw-r--r--indra/newview/skins/default/textures/icons/avaline_default_icon.jpgbin3951 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
-rw-r--r--indra/newview/skins/default/xui/da/panel_region_texture.xml4
-rw-r--r--indra/newview/skins/default/xui/da/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml24
-rw-r--r--indra/newview/skins/default/xui/en/floater_create_landmark.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_map.xml78
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_report_abuse.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_icon.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_conversation.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_im_conversation.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_mini_map.xml120
-rw-r--r--indra/newview/skins/default/xui/en/menu_url_agent.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml22
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml10
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml10
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/pl/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml5
-rw-r--r--indra/newview/skins/default/xui/ru/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml3
-rwxr-xr-xindra/newview/viewer_manifest.py3
-rw-r--r--indra/viewer_components/login/lllogin.cpp28
289 files changed, 5791 insertions, 3591 deletions
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 2d6d2a10d2..f0df3e1474 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -927,6 +927,9 @@ BOOL LLAvatarAppearance::loadAvatar()
return FALSE;
}
+ // initialize mJointAliasMap
+ getJointAliases();
+
// avatar_lad.xml : <skeleton>
if( !loadSkeletonNode() )
{
@@ -1047,7 +1050,6 @@ BOOL LLAvatarAppearance::loadAvatar()
return FALSE;
}
}
-
return TRUE;
}
diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
index 0a7a8d27bb..3892e4ce43 100644
--- a/indra/llappearance/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -612,14 +612,16 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
// we reached the end of the morphs
break;
}
- LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName));
+ std::string morph_name(morphName);
+ LLPolyMorphData* morph_data = new LLPolyMorphData(morph_name);
BOOL result = morph_data->loadBinary(fp, this);
if (!result)
{
- delete morph_data;
- continue;
+ LL_WARNS() << "Failure loading " << morph_name << " from " << fileName << LL_ENDL;
+ delete morph_data;
+ continue;
}
mMorphData.insert(morph_data);
diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
index 16b5f1e204..84dd6156a9 100644
--- a/indra/llappearance/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -156,7 +156,9 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
if (mVertexIndices[v] > 10000)
{
- LL_ERRS() << "Bad morph index: " << mVertexIndices[v] << LL_ENDL;
+ // Bad install? These are usually .llm files from 'character' fodler
+ LL_WARNS() << "Bad morph index " << v << ": " << mVertexIndices[v] << LL_ENDL;
+ return FALSE;
}
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index ff0aa6e76e..38a6b41afe 100644..100755
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -35,6 +35,8 @@
#include "llendianswizzle.h"
#include "llassetstorage.h"
#include "llrefcount.h"
+#include "threadpool.h"
+#include "workqueue.h"
#include "llvorbisencode.h"
@@ -45,15 +47,13 @@
extern LLAudioEngine *gAudiop;
-LLAudioDecodeMgr *gAudioDecodeMgrp = NULL;
-
static const S32 WAV_HEADER_SIZE = 44;
//////////////////////////////////////////////////////////////////////////////
-class LLVorbisDecodeState : public LLRefCount
+class LLVorbisDecodeState : public LLThreadSafeRefCount
{
public:
class WriteResponder : public LLLFSThread::Responder
@@ -532,146 +532,254 @@ void LLVorbisDecodeState::flushBadFile()
class LLAudioDecodeMgr::Impl
{
- friend class LLAudioDecodeMgr;
-public:
- Impl() {};
- ~Impl() {};
+ friend class LLAudioDecodeMgr;
+ Impl();
+ public:
- void processQueue(const F32 num_secs = 0.005);
+ void processQueue();
-protected:
- std::deque<LLUUID> mDecodeQueue;
- LLPointer<LLVorbisDecodeState> mCurrentDecodep;
+ void startMoreDecodes();
+ void enqueueFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState>& decode_state);
+ void checkDecodesFinished();
+
+ protected:
+ std::deque<LLUUID> mDecodeQueue;
+ std::map<LLUUID, LLPointer<LLVorbisDecodeState>> mDecodes;
};
+LLAudioDecodeMgr::Impl::Impl()
+{
+}
+
+// Returns the in-progress decode_state, which may be an empty LLPointer if
+// there was an error and there is no more work to be done.
+LLPointer<LLVorbisDecodeState> beginDecodingAndWritingAudio(const LLUUID &decode_id);
-void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
+// Return true if finished
+bool tryFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState> decode_state);
+
+void LLAudioDecodeMgr::Impl::processQueue()
{
- LLUUID uuid;
+ // First, check if any audio from in-progress decodes are ready to play. If
+ // so, mark them ready for playback (or errored, in case of error).
+ checkDecodesFinished();
- LLTimer decode_timer;
+ // Second, start as many decodes from the queue as permitted
+ startMoreDecodes();
+}
- BOOL done = FALSE;
- while (!done)
- {
- if (mCurrentDecodep)
- {
- BOOL res;
+void LLAudioDecodeMgr::Impl::startMoreDecodes()
+{
+ llassert_always(gAudiop);
+
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak
+ // pointer
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ const LL::ThreadPool::ptr_t general_thread_pool = LL::ThreadPool::getInstance("General");
+ llassert_always(main_queue);
+ llassert_always(general_queue);
+ llassert_always(general_thread_pool);
+ // Set max decodes to double the thread count of the general work queue.
+ // This ensures the general work queue is full, but prevents theoretical
+ // buildup of buffers in memory due to disk writes once the
+ // LLVorbisDecodeState leaves the worker thread (see
+ // LLLFSThread::sLocal->write). This is probably as fast as we can get it
+ // without modifying/removing LLVorbisDecodeState, at which point we should
+ // consider decoding the audio during the asset download process.
+ // -Cosmic,2022-05-11
+ const size_t max_decodes = general_thread_pool->getWidth() * 2;
+
+ while (!mDecodeQueue.empty() && mDecodes.size() < max_decodes)
+ {
+ const LLUUID decode_id = mDecodeQueue.front();
+ mDecodeQueue.pop_front();
+
+ // Don't decode the same file twice
+ if (mDecodes.find(decode_id) != mDecodes.end())
+ {
+ continue;
+ }
+ if (gAudiop->hasDecodedFile(decode_id))
+ {
+ continue;
+ }
+
+ // Kick off a decode
+ mDecodes[decode_id] = LLPointer<LLVorbisDecodeState>(NULL);
+ try
+ {
+ main_queue->postTo(
+ general_queue,
+ [decode_id]() // Work done on general queue
+ {
+ LLPointer<LLVorbisDecodeState> decode_state = beginDecodingAndWritingAudio(decode_id);
+
+ if (!decode_state)
+ {
+ // Audio decode has errored
+ return decode_state;
+ }
+
+ // Disk write of decoded audio is now in progress off-thread
+ return decode_state;
+ },
+ [decode_id, this](LLPointer<LLVorbisDecodeState> decode_state) // Callback to main thread
+ mutable {
+ if (!gAudiop)
+ {
+ // There is no LLAudioEngine anymore. This might happen if
+ // an audio decode is enqueued just before shutdown.
+ return;
+ }
+
+ // At this point, we can be certain that the pointer to "this"
+ // is valid because the lifetime of "this" is dependent upon
+ // the lifetime of gAudiop.
+
+ enqueueFinishAudio(decode_id, decode_state);
+ });
+ }
+ catch (const LLThreadSafeQueueInterrupt&)
+ {
+ // Shutdown
+ // Consider making processQueue() do a cleanup instead
+ // of starting more decodes
+ LL_WARNS() << "Tried to start decoding on shutdown" << LL_ENDL;
+ }
+ }
+}
- // Decode in a loop until we're done or have run out of time.
- while(!(res = mCurrentDecodep->decodeSection()) && (decode_timer.getElapsedTimeF32() < num_secs))
- {
- // decodeSection does all of the work above
- }
+LLPointer<LLVorbisDecodeState> beginDecodingAndWritingAudio(const LLUUID &decode_id)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
+
+ LL_DEBUGS() << "Decoding " << decode_id << " from audio queue!" << LL_ENDL;
+
+ std::string d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, decode_id.asString()) + ".dsf";
+ LLPointer<LLVorbisDecodeState> decode_state = new LLVorbisDecodeState(decode_id, d_path);
+
+ if (!decode_state->initDecode())
+ {
+ return NULL;
+ }
+
+ // Decode in a loop until we're done
+ while (!decode_state->decodeSection())
+ {
+ // decodeSection does all of the work above
+ }
+
+ if (!decode_state->isDone())
+ {
+ // Decode stopped early, or something bad happened to the file
+ // during decoding.
+ LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data or decode has been canceled, aborting decode" << LL_ENDL;
+ decode_state->flushBadFile();
+ return NULL;
+ }
+
+ if (!decode_state->isValid())
+ {
+ // We had an error when decoding, abort.
+ LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data, aborting decode" << LL_ENDL;
+ decode_state->flushBadFile();
+ return NULL;
+ }
+
+ // Kick off the writing of the decoded audio to the disk cache.
+ // The receiving thread can then cheaply call finishDecode() again to check
+ // if writing has finished. Someone has to hold on to the refcounted
+ // decode_state to prevent it from getting destroyed during write.
+ decode_state->finishDecode();
+
+ return decode_state;
+}
- if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid())
- {
- // We had an error when decoding, abort.
- LL_WARNS("AudioEngine") << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << LL_ENDL;
- mCurrentDecodep->flushBadFile();
-
- if (gAudiop)
- {
- LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
- adp->setHasValidData(false);
- adp->setHasCompletedDecode(true);
- }
-
- mCurrentDecodep = NULL;
- done = TRUE;
- }
+void LLAudioDecodeMgr::Impl::enqueueFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState>& decode_state)
+{
+ // Assumed fast
+ if (tryFinishAudio(decode_id, decode_state))
+ {
+ // Done early!
+ auto decode_iter = mDecodes.find(decode_id);
+ llassert(decode_iter != mDecodes.end());
+ mDecodes.erase(decode_iter);
+ return;
+ }
+
+ // Not done yet... enqueue it
+ mDecodes[decode_id] = decode_state;
+}
- if (!res)
- {
- // We've used up out time slice, bail...
- done = TRUE;
- }
- else if (mCurrentDecodep)
- {
- if (gAudiop && mCurrentDecodep->finishDecode())
- {
- // We finished!
- LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
- if (!adp)
- {
- LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << LL_ENDL;
- }
- else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
- {
- adp->setHasCompletedDecode(true);
- adp->setHasDecodedData(true);
- adp->setHasValidData(true);
-
- // At this point, we could see if anyone needs this sound immediately, but
- // I'm not sure that there's a reason to - we need to poll all of the playing
- // sounds anyway.
- //LL_INFOS("AudioEngine") << "Finished the vorbis decode, now what?" << LL_ENDL;
- }
- else
- {
- adp->setHasCompletedDecode(true);
- LL_INFOS("AudioEngine") << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << LL_ENDL;
- }
- mCurrentDecodep = NULL;
- }
- done = TRUE; // done for now
- }
- }
+void LLAudioDecodeMgr::Impl::checkDecodesFinished()
+{
+ auto decode_iter = mDecodes.begin();
+ while (decode_iter != mDecodes.end())
+ {
+ const LLUUID& decode_id = decode_iter->first;
+ const LLPointer<LLVorbisDecodeState>& decode_state = decode_iter->second;
+ if (tryFinishAudio(decode_id, decode_state))
+ {
+ decode_iter = mDecodes.erase(decode_iter);
+ }
+ else
+ {
+ ++decode_iter;
+ }
+ }
+}
- if (!done)
- {
- if (mDecodeQueue.empty())
- {
- // Nothing else on the queue.
- done = TRUE;
- }
- else
- {
- LLUUID uuid;
- uuid = mDecodeQueue.front();
- mDecodeQueue.pop_front();
- if (!gAudiop || gAudiop->hasDecodedFile(uuid))
- {
- // This file has already been decoded, don't decode it again.
- continue;
- }
-
- LL_DEBUGS() << "Decoding " << uuid << " from audio queue!" << LL_ENDL;
-
- std::string uuid_str;
- std::string d_path;
-
- LLTimer timer;
- timer.reset();
-
- uuid.toString(uuid_str);
- d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf";
-
- mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path);
- if (!mCurrentDecodep->initDecode())
- {
- mCurrentDecodep = NULL;
- }
- }
- }
- }
+bool tryFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState> decode_state)
+{
+ // decode_state is a file write in progress unless finished is true
+ bool finished = decode_state && decode_state->finishDecode();
+ if (!finished)
+ {
+ return false;
+ }
+
+ llassert_always(gAudiop);
+
+ LLAudioData *adp = gAudiop->getAudioData(decode_id);
+ if (!adp)
+ {
+ LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << decode_id << LL_ENDL;
+ return true;
+ }
+
+ bool valid = decode_state && decode_state->isValid();
+ // Mark current decode finished regardless of success or failure
+ adp->setHasCompletedDecode(true);
+ // Flip flags for decoded data
+ adp->setHasDecodeFailed(!valid);
+ adp->setHasDecodedData(valid);
+ // When finished decoding, there will also be a decoded wav file cached on
+ // disk with the .dsf extension
+ if (valid)
+ {
+ adp->setHasWAVLoadFailed(false);
+ }
+
+ return true;
}
//////////////////////////////////////////////////////////////////////////////
LLAudioDecodeMgr::LLAudioDecodeMgr()
{
- mImpl = new Impl;
+ mImpl = new Impl();
}
LLAudioDecodeMgr::~LLAudioDecodeMgr()
{
- delete mImpl;
+ delete mImpl;
+ mImpl = nullptr;
}
-void LLAudioDecodeMgr::processQueue(const F32 num_secs)
+void LLAudioDecodeMgr::processQueue()
{
- mImpl->processQueue(num_secs);
+ mImpl->processQueue();
}
BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
@@ -687,7 +795,7 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
{
// Just put it on the decode queue.
LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL;
- mImpl->mDecodeQueue.push_back(uuid);
+ mImpl->mDecodeQueue.push_back(uuid);
return TRUE;
}
diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h
index ceaff3f2d8..4c17b46156 100644
--- a/indra/llaudio/llaudiodecodemgr.h
+++ b/indra/llaudio/llaudiodecodemgr.h
@@ -32,24 +32,23 @@
#include "llassettype.h"
#include "llframetimer.h"
+#include "llsingleton.h"
+template<class T> class LLPointer;
class LLVorbisDecodeState;
-class LLAudioDecodeMgr
+class LLAudioDecodeMgr : public LLSingleton<LLAudioDecodeMgr>
{
+ LLSINGLETON(LLAudioDecodeMgr);
+ ~LLAudioDecodeMgr();
public:
- LLAudioDecodeMgr();
- ~LLAudioDecodeMgr();
-
- void processQueue(const F32 num_secs = 0.005);
+ void processQueue();
BOOL addDecodeRequest(const LLUUID &uuid);
void addAudioRequest(const LLUUID &uuid);
protected:
class Impl;
- Impl* mImpl;
+ Impl* mImpl;
};
-extern LLAudioDecodeMgr *gAudioDecodeMgrp;
-
#endif
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index e0ebbb76bd..008e1827c5 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -83,18 +83,10 @@ void LLAudioEngine::setDefaults()
mLastStatus = 0;
- mNumChannels = 0;
mEnableWind = false;
- S32 i;
- for (i = 0; i < MAX_CHANNELS; i++)
- {
- mChannels[i] = NULL;
- }
- for (i = 0; i < MAX_BUFFERS; i++)
- {
- mBuffers[i] = NULL;
- }
+ mChannels.fill(nullptr);
+ mBuffers.fill(nullptr);
mMasterGain = 1.f;
// Setting mInternalGain to an out of range value fixes the issue reported in STORM-830.
@@ -111,18 +103,14 @@ void LLAudioEngine::setDefaults()
}
-bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title)
+bool LLAudioEngine::init(void* userdata, const std::string &app_title)
{
setDefaults();
- mNumChannels = num_channels;
mUserData = userdata;
allocateListener();
- // Initialize the decode manager
- gAudioDecodeMgrp = new LLAudioDecodeMgr;
-
LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL;
return true;
@@ -131,10 +119,6 @@ bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::stri
void LLAudioEngine::shutdown()
{
- // Clean up decode manager
- delete gAudioDecodeMgrp;
- gAudioDecodeMgrp = NULL;
-
// Clean up wind source
cleanupWind();
@@ -156,14 +140,14 @@ void LLAudioEngine::shutdown()
// Clean up channels
S32 i;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
delete mChannels[i];
mChannels[i] = NULL;
}
// Clean up buffers
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
delete mBuffers[i];
mBuffers[i] = NULL;
@@ -229,7 +213,7 @@ std::string LLAudioEngine::getInternetStreamURL()
void LLAudioEngine::updateChannels()
{
S32 i;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (mChannels[i])
{
@@ -240,20 +224,14 @@ void LLAudioEngine::updateChannels()
}
}
-static const F32 default_max_decode_time = .002f; // 2 ms
-void LLAudioEngine::idle(F32 max_decode_time)
+void LLAudioEngine::idle()
{
- if (max_decode_time <= 0.f)
- {
- max_decode_time = default_max_decode_time;
- }
-
// "Update" all of our audio sources, clean up dead ones.
// Primarily does position updating, cleanup of unused audio sources.
// Also does regeneration of the current priority of each audio source.
S32 i;
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (mBuffers[i])
{
@@ -276,7 +254,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
{
// The source is done playing, clean it up.
delete sourcep;
- mAllSources.erase(iter++);
+ iter = mAllSources.erase(iter);
continue;
}
@@ -473,7 +451,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
commitDeferredChanges();
// Flush unused buffers that are stale enough
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (mBuffers[i])
{
@@ -489,7 +467,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
// Clear all of the looped flags for the channels
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (mChannels[i])
{
@@ -498,7 +476,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
}
// Decode audio files
- gAudioDecodeMgrp->processQueue(max_decode_time);
+ LLAudioDecodeMgr::getInstance()->processQueue();
// Call this every frame, just in case we somehow
// missed picking it up in all the places that can add
@@ -532,7 +510,7 @@ bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uu
{
if (audio_uuid.notNull())
{
- gAudioDecodeMgrp->addDecodeRequest(audio_uuid);
+ LLAudioDecodeMgr::getInstance()->addDecodeRequest(audio_uuid);
}
}
else
@@ -561,7 +539,7 @@ void LLAudioEngine::enableWind(bool enable)
LLAudioBuffer * LLAudioEngine::getFreeBuffer()
{
S32 i;
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (!mBuffers[i])
{
@@ -574,7 +552,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer()
// Grab the oldest unused buffer
F32 max_age = -1.f;
S32 buffer_id = -1;
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (mBuffers[i])
{
@@ -605,7 +583,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer()
LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
{
S32 i;
- for (i = 0; i < mNumChannels; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (!mChannels[i])
{
@@ -633,7 +611,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
F32 min_priority = 10000.f;
LLAudioChannel *min_channelp = NULL;
- for (i = 0; i < mNumChannels; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
LLAudioChannel *channelp = mChannels[i];
LLAudioSource *sourcep = channelp->getSource();
@@ -660,7 +638,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp)
{
S32 i;
- for (i = 0; i < MAX_BUFFERS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
{
if (mBuffers[i] == bufferp)
{
@@ -678,7 +656,7 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid)
getAudioData(uuid); // We don't care about the return value, this is just to make sure
// that we have an entry, which will mean that the audio engine knows about this
- if (gAudioDecodeMgrp->addDecodeRequest(uuid))
+ if (LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid))
{
// This means that we do have a local copy, and we're working on decoding it.
return true;
@@ -827,7 +805,8 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
addAudioSource(asp);
if (pos_global.isExactlyZero())
{
- asp->setAmbient(true);
+ // For sound preview and UI
+ asp->setForcedPriority(true);
}
else
{
@@ -953,6 +932,7 @@ LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id)
LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
data_map::iterator iter;
iter = mAllData.find(audio_uuid);
if (iter == mAllData.end())
@@ -1039,7 +1019,7 @@ void LLAudioEngine::startNextTransfer()
// Check all channels for currently playing sounds.
F32 max_pri = -1.f;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (!mChannels[i])
{
@@ -1067,7 +1047,7 @@ void LLAudioEngine::startNextTransfer()
continue;
}
- if (!adp->hasLocalData() && adp->hasValidData())
+ if (!adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1078,7 +1058,7 @@ void LLAudioEngine::startNextTransfer()
if (asset_id.isNull())
{
max_pri = -1.f;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (!mChannels[i])
{
@@ -1103,7 +1083,7 @@ void LLAudioEngine::startNextTransfer()
continue;
}
- if (!adp->hasLocalData() && adp->hasValidData())
+ if (!adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1115,7 +1095,7 @@ void LLAudioEngine::startNextTransfer()
if (asset_id.isNull())
{
max_pri = -1.f;
- for (i = 0; i < MAX_CHANNELS; i++)
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
{
if (!mChannels[i])
{
@@ -1143,7 +1123,7 @@ void LLAudioEngine::startNextTransfer()
continue;
}
- if (!adp->hasLocalData() && adp->hasValidData())
+ if (!adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1171,7 +1151,7 @@ void LLAudioEngine::startNextTransfer()
}
adp = asp->getCurrentData();
- if (adp && !adp->hasLocalData() && adp->hasValidData())
+ if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1179,7 +1159,7 @@ void LLAudioEngine::startNextTransfer()
}
adp = asp->getQueuedData();
- if (adp && !adp->hasLocalData() && adp->hasValidData())
+ if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1194,7 +1174,7 @@ void LLAudioEngine::startNextTransfer()
continue;
}
- if (!adp->hasLocalData() && adp->hasValidData())
+ if (!adp->hasLocalData() && !adp->hasDecodeFailed())
{
asset_id = adp->getID();
max_pri = asp->getPriority();
@@ -1235,7 +1215,7 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v
LLAudioData *adp = gAudiop->getAudioData(uuid);
if (adp)
{ // Make sure everything is cleared
- adp->setHasValidData(false);
+ adp->setHasDecodeFailed(true);
adp->setHasLocalData(false);
adp->setHasDecodedData(false);
adp->setHasCompletedDecode(true);
@@ -1252,9 +1232,9 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v
else
{
// LL_INFOS() << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL;
- adp->setHasValidData(true);
+ adp->setHasDecodeFailed(false);
adp->setHasLocalData(true);
- gAudioDecodeMgrp->addDecodeRequest(uuid);
+ LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid);
}
}
gAudiop->mCurrentTransfer = LLUUID::null;
@@ -1273,7 +1253,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
mPriority(0.f),
mGain(gain),
mSourceMuted(false),
- mAmbient(false),
+ mForcedPriority(false),
mLoop(false),
mSyncMaster(false),
mSyncSlave(false),
@@ -1324,11 +1304,15 @@ void LLAudioSource::update()
{
// Hack - try and load the sound. Will do this as a callback
// on decode later.
- if (adp->load() && adp->getBuffer())
+ if (adp->getBuffer())
{
play(adp->getID());
}
- else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done
+ else if (adp->hasDecodedData() && !adp->hasWAVLoadFailed())
+ {
+ adp->load();
+ }
+ else if (adp->hasCompletedDecode() && adp->hasDecodeFailed()) // Only mark corrupted after decode is done
{
LL_WARNS() << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL;
mCorrupted = true ;
@@ -1339,7 +1323,7 @@ void LLAudioSource::update()
void LLAudioSource::updatePriority()
{
- if (isAmbient())
+ if (isForcedPriority())
{
mPriority = 1.f;
}
@@ -1624,12 +1608,12 @@ bool LLAudioSource::hasPendingPreloads() const
{
LLAudioData *adp = iter->second;
// note: a bad UUID will forever be !hasDecodedData()
- // but also !hasValidData(), hence the check for hasValidData()
+ // but also hasDecodeFailed(), hence the check for hasDecodeFailed()
if (!adp)
{
continue;
}
- if (!adp->hasDecodedData() && adp->hasValidData())
+ if (!adp->hasDecodedData() && !adp->hasDecodeFailed())
{
// This source is still waiting for a preload
return true;
@@ -1786,7 +1770,8 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
mHasLocalData(false),
mHasDecodedData(false),
mHasCompletedDecode(false),
- mHasValidData(true)
+ mHasDecodeFailed(false),
+ mHasWAVLoadFailed(false)
{
if (uuid.isNull())
{
@@ -1821,12 +1806,14 @@ bool LLAudioData::load()
{
// We already have this sound in a buffer, don't do anything.
LL_INFOS() << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL;
+ mHasWAVLoadFailed = false;
return true;
}
if (!gAudiop)
{
LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ mHasWAVLoadFailed = true;
return false;
}
@@ -1835,6 +1822,8 @@ bool LLAudioData::load()
{
// No free buffers, abort.
LL_INFOS() << "Not able to allocate a new audio buffer, aborting." << LL_ENDL;
+ // *TODO: Mark this failure differently so the audio engine could retry loading this buffer in the future
+ mHasWAVLoadFailed = true;
return true;
}
@@ -1843,7 +1832,8 @@ bool LLAudioData::load()
mID.toString(uuid_str);
wav_path= gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf";
- if (!mBufferp->loadWAV(wav_path))
+ mHasWAVLoadFailed = !mBufferp->loadWAV(wav_path);
+ if (mHasWAVLoadFailed)
{
// Hrm. Right now, let's unset the buffer, since it's empty.
gAudiop->cleanupBuffer(mBufferp);
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index b5fd4c27a1..0fe8b3d756 100644..100755
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -47,8 +47,8 @@ const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f;
const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f;
const F32 DEFAULT_MIN_DISTANCE = 2.0f;
-#define MAX_CHANNELS 30
-#define MAX_BUFFERS 40 // Some extra for preloading, maybe?
+#define LL_MAX_AUDIO_CHANNELS 30
+#define LL_MAX_AUDIO_BUFFERS 40 // Some extra for preloading, maybe?
class LLAudioSource;
class LLAudioData;
@@ -88,7 +88,7 @@ public:
virtual ~LLAudioEngine();
// initialization/startup/shutdown
- virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title);
+ virtual bool init(void *userdata, const std::string &app_title);
virtual std::string getDriverName(bool verbose) = 0;
virtual void shutdown();
@@ -96,7 +96,7 @@ public:
//virtual void processQueue(const LLUUID &sound_guid);
virtual void setListener(LLVector3 pos,LLVector3 vel,LLVector3 up,LLVector3 at);
virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0;
- virtual void idle(F32 max_decode_time = 0.f);
+ virtual void idle();
virtual void updateChannels();
//
@@ -209,7 +209,6 @@ protected:
S32 mLastStatus;
- S32 mNumChannels;
bool mEnableWind;
LLUUID mCurrentTransfer; // Audio file currently being transferred by the system
@@ -224,11 +223,11 @@ protected:
source_map mAllSources;
data_map mAllData;
- LLAudioChannel *mChannels[MAX_CHANNELS];
+ std::array<LLAudioChannel*, LL_MAX_AUDIO_CHANNELS> mChannels;
// Buffers needs to change into a different data structure, as the number of buffers
// that we have active should be limited by RAM usage, not count.
- LLAudioBuffer *mBuffers[MAX_BUFFERS];
+ std::array<LLAudioBuffer*, LL_MAX_AUDIO_BUFFERS> mBuffers;
F32 mMasterGain;
F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true.
@@ -266,8 +265,8 @@ public:
void addAudioData(LLAudioData *adp, bool set_current = TRUE);
- void setAmbient(const bool ambient) { mAmbient = ambient; }
- bool isAmbient() const { return mAmbient; }
+ void setForcedPriority(const bool ambient) { mForcedPriority = ambient; }
+ bool isForcedPriority() const { return mForcedPriority; }
void setLoop(const bool loop) { mLoop = loop; }
bool isLoop() const { return mLoop; }
@@ -326,7 +325,7 @@ protected:
F32 mPriority;
F32 mGain;
bool mSourceMuted;
- bool mAmbient;
+ bool mForcedPriority; // ignore mute, set high priority, researved for sound preview and UI
bool mLoop;
bool mSyncMaster;
bool mSyncSlave;
@@ -360,32 +359,36 @@ protected:
class LLAudioData
{
-public:
- LLAudioData(const LLUUID &uuid);
- bool load();
-
- LLUUID getID() const { return mID; }
- LLAudioBuffer *getBuffer() const { return mBufferp; }
-
- bool hasLocalData() const { return mHasLocalData; }
- bool hasDecodedData() const { return mHasDecodedData; }
- bool hasCompletedDecode() const { return mHasCompletedDecode; }
- bool hasValidData() const { return mHasValidData; }
-
- void setHasLocalData(const bool hld) { mHasLocalData = hld; }
- void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
- void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; }
- void setHasValidData(const bool hvd) { mHasValidData = hvd; }
-
- friend class LLAudioEngine; // Severe laziness, bad.
-
-protected:
- LLUUID mID;
- LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
- bool mHasLocalData; // Set true if the sound asset file is available locally
- bool mHasDecodedData; // Set true if the sound file has been decoded
- bool mHasCompletedDecode; // Set true when the sound is decoded
- bool mHasValidData; // Set false if decoding failed, meaning the sound asset is bad
+ public:
+ LLAudioData(const LLUUID &uuid);
+ bool load();
+
+ LLUUID getID() const { return mID; }
+ LLAudioBuffer *getBuffer() const { return mBufferp; }
+
+ bool hasLocalData() const { return mHasLocalData; }
+ bool hasDecodedData() const { return mHasDecodedData; }
+ bool hasCompletedDecode() const { return mHasCompletedDecode; }
+ bool hasDecodeFailed() const { return mHasDecodeFailed; }
+ bool hasWAVLoadFailed() const { return mHasWAVLoadFailed; }
+
+ void setHasLocalData(const bool hld) { mHasLocalData = hld; }
+ void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
+ void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; }
+ void setHasDecodeFailed(const bool hdf) { mHasDecodeFailed = hdf; }
+ void setHasWAVLoadFailed(const bool hwlf) { mHasWAVLoadFailed = hwlf; }
+
+ friend class LLAudioEngine; // Severe laziness, bad.
+
+ protected:
+ LLUUID mID;
+ LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
+ bool mHasLocalData; // Set true if the encoded sound asset file is available locally
+ bool mHasDecodedData; // Set true if the decoded sound file is available on disk
+ bool mHasCompletedDecode; // Set true when the sound is decoded
+ bool mHasDecodeFailed; // Set true if decoding failed, meaning the sound asset is bad
+ bool mHasWAVLoadFailed; // Set true if loading the decoded WAV file failed, meaning the sound asset should be decoded instead if
+ // possible
};
diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp
index b0c87b0208..ba743020b5 100644
--- a/indra/llaudio/llaudioengine_fmodstudio.cpp
+++ b/indra/llaudio/llaudioengine_fmodstudio.cpp
@@ -74,7 +74,7 @@ static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
return true;
}
-bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, const std::string &app_title)
+bool LLAudioEngine_FMODSTUDIO::init(void* userdata, const std::string &app_title)
{
U32 version;
FMOD_RESULT result;
@@ -86,7 +86,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
return false;
//will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer.
- LLAudioEngine::init(num_channels, userdata, app_title);
+ LLAudioEngine::init(userdata, app_title);
result = mSystem->getVersion(&version);
Check_FMOD_Error(result, "FMOD::System::getVersion");
@@ -98,7 +98,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
}
// In this case, all sounds, PLUS wind and stream will be software.
- result = mSystem->setSoftwareChannels(num_channels + 2);
+ result = mSystem->setSoftwareChannels(LL_MAX_AUDIO_CHANNELS + 2);
Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels");
FMOD_ADVANCEDSETTINGS settings;
@@ -127,7 +127,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
{
LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
if (mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
- (result = mSystem->init(num_channels + 2, fmod_flags, const_cast<char*>(app_title.c_str()))) == FMOD_OK)
+ (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, const_cast<char*>(app_title.c_str()))) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
audio_ok = true;
@@ -149,7 +149,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
{
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
if (mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
- (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
+ (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
audio_ok = true;
@@ -190,7 +190,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
// initialize the FMOD engine
// number of channel in this case looks to be identiacal to number of max simultaneously
// playing objects and we can set practically any number
- result = mSystem->init(num_channels + 2, fmod_flags, 0);
+ result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0);
if (Check_FMOD_Error(result, "Error initializing FMOD Studio with default settins, retrying with other format"))
{
result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0/*- ignore*/);
@@ -198,7 +198,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons
{
return false;
}
- result = mSystem->init(num_channels + 2, fmod_flags, 0);
+ result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0);
}
if (Check_FMOD_Error(result, "Error initializing FMOD Studio"))
{
@@ -519,9 +519,9 @@ void LLAudioChannelFMODSTUDIO::update3DPosition()
return;
}
- if (mCurrentSourcep->isAmbient())
+ if (mCurrentSourcep->isForcedPriority())
{
- // Ambient sound, don't need to do any positional updates.
+ // Prioritized UI and preview sounds don't need to do any positional updates.
set3DMode(false);
}
else
diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h
index f2361df1b6..d3d6d69685 100644
--- a/indra/llaudio/llaudioengine_fmodstudio.h
+++ b/indra/llaudio/llaudioengine_fmodstudio.h
@@ -51,7 +51,7 @@ public:
virtual ~LLAudioEngine_FMODSTUDIO();
// initialization/startup/shutdown
- virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title);
+ virtual bool init(void *user_data, const std::string &app_title);
virtual std::string getDriverName(bool verbose);
virtual void allocateListener();
diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp
index 3bdd0302ee..0a79614424 100644
--- a/indra/llaudio/llaudioengine_openal.cpp
+++ b/indra/llaudio/llaudioengine_openal.cpp
@@ -52,10 +52,10 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
}
// virtual
-bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title)
+bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title)
{
mWindGen = NULL;
- LLAudioEngine::init(num_channels, userdata, app_title);
+ LLAudioEngine::init(userdata, app_title);
if(!alutInit(NULL, NULL))
{
@@ -297,7 +297,7 @@ void LLAudioChannelOpenAL::update3DPosition()
{
return;
}
- if (mCurrentSourcep->isAmbient())
+ if (mCurrentSourcep->isForcedPriority())
{
alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h
index 366f9259e3..a3cab97cd2 100644
--- a/indra/llaudio/llaudioengine_openal.h
+++ b/indra/llaudio/llaudioengine_openal.h
@@ -40,7 +40,7 @@ class LLAudioEngine_OpenAL : public LLAudioEngine
LLAudioEngine_OpenAL();
virtual ~LLAudioEngine_OpenAL();
- virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title);
+ virtual bool init(void *user_data, const std::string &app_title);
virtual std::string getDriverName(bool verbose);
virtual void allocateListener();
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
index 1ad29a3f59..85577992a6 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
@@ -70,7 +70,11 @@ mRetryCount(0)
// Must be larger than the usual Second Life frame stutter time.
const U32 buffer_seconds = 10; //sec
const U32 estimated_bitrate = 128; //kbit/sec
- mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
+ FMOD_RESULT result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
+ }
// Here's where we set the size of the network buffer and some buffering
// parameters. In this case we want a network buffer of 16k, we want it
@@ -134,7 +138,7 @@ void LLStreamingAudio_FMODSTUDIO::killDeadStreams()
{
LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL;
delete streamp;
- mDeadStreams.erase(iter++);
+ iter = mDeadStreams.erase(iter);
}
else
{
@@ -404,7 +408,11 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
if (mStreamChannel)
return mStreamChannel; //Already have a channel for this stream.
- mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
+ FMOD_RESULT result = mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL;
+ }
return mStreamChannel;
}
@@ -445,16 +453,29 @@ bool LLAudioStreamManagerFMODSTUDIO::stopStream()
FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
{
FMOD_OPENSTATE state;
- mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
+ FMOD_RESULT result = mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL;
+ }
return state;
}
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
- mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
+ FMOD_RESULT result = mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
+ return;
+ }
FMOD_ADVANCEDSETTINGS settings;
memset(&settings, 0, sizeof(settings));
settings.cbSize = sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
- mSystem->setAdvancedSettings(&settings);
+ result = mSystem->setAdvancedSettings(&settings);
+ if (result != FMOD_OK)
+ {
+ LL_WARNS("FMOD") << "setAdvancedSettings error: " << FMOD_ErrorString(result) << LL_ENDL;
+ }
}
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index e906d81ce1..c38614b0b4 100644
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -44,6 +44,14 @@ using namespace std;
#define INCHES_TO_METERS 0.02540005f
+/// The .bvh does not have a formal spec, and different readers interpret things in their own way.
+/// In OUR usage, frame 0 is used in optimization and is not considered to be part of the animation.
+const S32 NUMBER_OF_IGNORED_FRAMES_AT_START = 1;
+/// In our usage, the last frame is used only to indicate what the penultimate frame should be interpolated towards.
+/// I.e., the animation only plays up to the start of the last frame. There is no hold or exptrapolation past that point..
+/// Thus there are two frame of the total that do not contribute to the total running time of the animation.
+const S32 NUMBER_OF_UNPLAYED_FRAMES = NUMBER_OF_IGNORED_FRAMES_AT_START + 1;
+
const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f;
const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f;
@@ -865,7 +873,10 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &
return E_ST_NO_FRAME_TIME;
}
- mDuration = (F32)mNumFrames * mFrameTime;
+ // If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime.
+ // If the user supples exactly one total frame, it isn't clear if that is a pose or reference frame, and the
+ // behavior is not defined. In this case, retain historical undefined behavior.
+ mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime;
if (!mLoop)
{
mLoopOutPoint = mDuration;
@@ -1355,12 +1366,13 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );
S32 outcount = 0;
- S32 frame = 1;
+ S32 frame = 0;
for ( ki = joint->mKeys.begin();
ki != joint->mKeys.end();
++ki )
{
- if ((frame == 1) && joint->mRelativeRotationKey)
+
+ if ((frame == 0) && joint->mRelativeRotationKey)
{
first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
@@ -1373,7 +1385,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
continue;
}
- time = (F32)frame * mFrameTime;
+ time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts.
if (mergeParent)
{
@@ -1433,12 +1445,12 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
LLVector3 relPos = joint->mRelativePosition;
LLVector3 relKey;
- frame = 1;
+ frame = 0;
for ( ki = joint->mKeys.begin();
ki != joint->mKeys.end();
++ki )
{
- if ((frame == 1) && joint->mRelativePositionKey)
+ if ((frame == 0) && joint->mRelativePositionKey)
{
relKey.setVec(ki->mPos);
}
@@ -1449,7 +1461,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
continue;
}
- time = (F32)frame * mFrameTime;
+ time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts.
LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot;
LLVector3 outPos = inPos * frameRot * offsetRot;
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index a25ff16786..ebf7454a61 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -1222,8 +1222,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
//-----------------------------------------------------------------------------
// deserialize()
+//
+// allow_invalid_joints should be true when handling existing content, to avoid breakage.
+// During upload, we should be more restrictive and reject such animations.
//-----------------------------------------------------------------------------
-BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
+BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints)
{
BOOL old_version = FALSE;
mJointMotionList = new LLKeyframeMotion::JointMotionList;
@@ -1344,6 +1347,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
return FALSE;
}
+ //SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside
+ LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e");
+ LLUUID const formal_female_land_anim("6a9a173b-61fa-3ad5-01fa-a851cfc5f66a");
+ if (female_land_anim == asset_id || formal_female_land_anim == asset_id)
+ {
+ LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL;
+ mJointMotionList->mLoop = FALSE;
+ }
+
//-------------------------------------------------------------------------
// get easeIn and easeOut
//-------------------------------------------------------------------------
@@ -1443,6 +1455,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
if (joint)
{
S32 joint_num = joint->getJointNum();
+ joint_name = joint->getName(); // canonical name in case this is an alias.
// LL_INFOS() << " joint: " << joint_name << LL_ENDL;
if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0))
{
@@ -1457,7 +1470,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
{
LL_WARNS() << "invalid joint name: " << joint_name
<< " for animation " << asset_id << LL_ENDL;
- //return FALSE;
+ if (!allow_invalid_joints)
+ {
+ return FALSE;
+ }
}
joint_motion->mJointName = joint_name;
@@ -2096,8 +2112,9 @@ U32 LLKeyframeMotion::getFileSize()
//-----------------------------------------------------------------------------
// dumpToFile()
//-----------------------------------------------------------------------------
-void LLKeyframeMotion::dumpToFile(const std::string& name)
+bool LLKeyframeMotion::dumpToFile(const std::string& name)
{
+ bool succ = false;
if (isLoaded())
{
std::string outfile_base;
@@ -2114,10 +2131,24 @@ void LLKeyframeMotion::dumpToFile(const std::string& name)
const LLUUID& id = getID();
outfile_base = id.asString();
}
- std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim");
+
+ if (gDirUtilp->getExtension(outfile_base).empty())
+ {
+ outfile_base += ".anim";
+ }
+ std::string outfilename;
+ if (gDirUtilp->getDirName(outfile_base).empty())
+ {
+ outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base);
+ }
+ else
+ {
+ outfilename = outfile_base;
+ }
if (LLFile::isfile(outfilename))
{
- return;
+ LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL;
+ return false;
}
S32 file_size = getFileSize();
@@ -2131,11 +2162,13 @@ void LLKeyframeMotion::dumpToFile(const std::string& name)
outfile.open(outfilename, LL_APR_WPB);
if (outfile.getFileHandle())
{
- outfile.write(buffer, file_size);
+ S32 wrote_bytes = outfile.write(buffer, file_size);
+ succ = (wrote_bytes == file_size);
}
}
delete [] buffer;
}
+ return succ;
}
//-----------------------------------------------------------------------------
diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h
index 9a927ede9a..96746f57c9 100644
--- a/indra/llcharacter/llkeyframemotion.h
+++ b/indra/llcharacter/llkeyframemotion.h
@@ -156,9 +156,9 @@ public:
public:
U32 getFileSize();
BOOL serialize(LLDataPacker& dp) const;
- BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id);
+ BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true);
BOOL isLoaded() { return mJointMotionList != NULL; }
- void dumpToFile(const std::string& name);
+ bool dumpToFile(const std::string& name);
// setters for modifying a keyframe animation
@@ -432,6 +432,9 @@ protected:
F32 mLastUpdateTime;
F32 mLastLoopedTime;
AssetStatus mAssetStatus;
+
+public:
+ void setCharacter(LLCharacter* character) { mCharacter = character; }
};
class LLKeyframeDataCache
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 59aa731af2..df65828d02 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -266,6 +266,11 @@ set(llcommon_HEADER_FILES
workqueue.h
StackWalker.h
)
+
+if (DARWIN)
+ list(APPEND llcommon_HEADER_FILES llsys_objc.h)
+ list(APPEND llcommon_SOURCE_FILES llsys_objc.mm)
+endif (DARWIN)
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
@@ -313,12 +318,6 @@ target_link_libraries(
${TRACY_LIBRARY}
)
-if (DARWIN)
- include(CMakeFindFrameworks)
- find_library(CARBON_LIBRARY Carbon)
- target_link_libraries(llcommon ${CARBON_LIBRARY})
-endif (DARWIN)
-
add_dependencies(llcommon stage_third_party_libs)
if (LL_TESTS)
diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h
index b68e9e0f82..da9d98c16c 100644
--- a/indra/llcommon/llalignedarray.h
+++ b/indra/llcommon/llalignedarray.h
@@ -116,14 +116,20 @@ void LLAlignedArray<T, alignment>::resize(U32 size)
template <class T, U32 alignment>
T& LLAlignedArray<T, alignment>::operator[](int idx)
{
- llassert(idx < mElementCount);
+ if(idx >= mElementCount || idx < 0)
+ {
+ LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL;
+ }
return mArray[idx];
}
template <class T, U32 alignment>
const T& LLAlignedArray<T, alignment>::operator[](int idx) const
{
- llassert(idx < mElementCount);
+ if (idx >= mElementCount || idx < 0)
+ {
+ LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL;
+ }
return mArray[idx];
}
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index c2d353b0fc..14bfb98629 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -35,6 +35,7 @@
// STL headers
// std headers
#include <atomic>
+#include <stdexcept>
// external library headers
#include <boost/bind.hpp>
#include <boost/fiber/fiber.hpp>
@@ -214,6 +215,22 @@ std::string LLCoros::logname()
return data.mName.empty()? data.getKey() : data.mName;
}
+void LLCoros::saveException(const std::string& name, std::exception_ptr exc)
+{
+ mExceptionQueue.emplace(name, exc);
+}
+
+void LLCoros::rethrow()
+{
+ if (! mExceptionQueue.empty())
+ {
+ ExceptionData front = mExceptionQueue.front();
+ mExceptionQueue.pop();
+ LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL;
+ std::rethrow_exception(front.exception);
+ }
+}
+
void LLCoros::setStackSize(S32 stacksize)
{
LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL;
@@ -302,11 +319,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop,
}
}
-void LLCoros::winlevel(const std::string& name, const callable_t& callable)
+void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable)
{
__try
{
- toplevelTryWrapper(name, callable);
+ LLCoros::toplevelTryWrapper(name, callable);
}
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
{
@@ -321,7 +338,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable)
throw std::exception(integer_string);
}
}
-
#endif
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
@@ -350,11 +366,19 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
}
catch (...)
{
+#if LL_WINDOWS
// Any OTHER kind of uncaught exception will cause the viewer to
- // crash, hopefully informatively.
+ // crash, SEH handling should catch it and report to bugsplat.
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
+#else
+ // Stash any OTHER kind of uncaught exception in the rethrow() queue
+ // to be rethrown by the main fiber.
+ LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine "
+ << name << LL_ENDL;
+ LLCoros::instance().saveException(name, std::current_exception());
+#endif
}
}
@@ -364,8 +388,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
- // Can not use __try in functions that require unwinding, so use one more wrapper
- winlevel(name, callable);
+ // Because SEH can's have unwinding, need to call a wrapper
+ // 'try' is inside SEH handling to not catch LLContinue
+ sehHandle(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index a94cfca19f..dbff921f16 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -38,6 +38,8 @@
#include "llinstancetracker.h"
#include <boost/function.hpp>
#include <string>
+#include <exception>
+#include <queue>
// e.g. #include LLCOROS_MUTEX_HEADER
#define LLCOROS_MUTEX_HEADER <boost/fiber/mutex.hpp>
@@ -156,6 +158,19 @@ public:
* LLCoros::launch()).
*/
static std::string getName();
+
+ /**
+ * rethrow() is called by the thread's main fiber to propagate an
+ * exception from any coroutine into the main fiber, where it can engage
+ * the normal unhandled-exception machinery, up to and including crash
+ * reporting.
+ *
+ * LLCoros maintains a queue of otherwise-uncaught exceptions from
+ * terminated coroutines. Each call to rethrow() pops the first of those
+ * and rethrows it. When the queue is empty (normal case), rethrow() is a
+ * no-op.
+ */
+ void rethrow();
/**
* This variation returns a name suitable for log messages: the explicit
@@ -292,13 +307,27 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
+ void toplevelTryWrapper(const std::string& name, const callable_t& callable);
#if LL_WINDOWS
- void winlevel(const std::string& name, const callable_t& callable);
+ void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper
#endif
- void toplevelTryWrapper(const std::string& name, const callable_t& callable);
- void toplevel(std::string name, callable_t callable);
+ void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper
struct CoroData;
static CoroData& get_CoroData(const std::string& caller);
+ void saveException(const std::string& name, std::exception_ptr exc);
+
+ struct ExceptionData
+ {
+ ExceptionData(const std::string& nm, std::exception_ptr exc):
+ name(nm),
+ exception(exc)
+ {}
+ // name of coroutine that originally threw this exception
+ std::string name;
+ // the thrown exception
+ std::exception_ptr exception;
+ };
+ std::queue<ExceptionData> mExceptionQueue;
S32 mStackSize;
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 849867586a..d6ae1284d3 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -212,11 +212,9 @@ U64 LLMemory::getCurrentRSS()
mach_msg_type_number_t basicInfoCount = MACH_TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
{
-// residentSize = basicInfo.resident_size;
- // Although this method is defined to return the "resident set size,"
- // in fact what callers want from it is the total virtual memory
- // consumed by the application.
- residentSize = basicInfo.virtual_size;
+ residentSize = basicInfo.resident_size;
+ // 64-bit macos apps allocate 32 GB or more at startup, and this is reflected in virtual_size.
+ // basicInfo.virtual_size is not what we want.
}
else
{
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 818df07bb2..4a1a81f083 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -118,7 +118,11 @@ namespace
eMONTIOR_MWAIT=33,
eCPLDebugStore=34,
eThermalMonitor2=35,
- eAltivec=36
+ eAltivec=36,
+ eSSE3S_Features = 37,
+ eSSE4_1_Features = 38,
+ eSSE4_2_Features = 39,
+ eSSE4a_Features = 40,
};
const char* cpu_feature_names[] =
@@ -161,7 +165,11 @@ namespace
"CPL Qualified Debug Store",
"Thermal Monitor 2",
- "Altivec"
+ "Altivec",
+ "SSE3S Instructions",
+ "SSE4.1 Instructions",
+ "SSE4.2 Instructions",
+ "SSE4a Instructions",
};
std::string intel_CPUFamilyName(int composed_family)
@@ -250,6 +258,31 @@ public:
return hasExtension(cpu_feature_names[eSSE2_Ext]);
}
+ bool hasSSE3() const
+ {
+ return hasExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ bool hasSSE3S() const
+ {
+ return hasExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ bool hasSSE41() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ bool hasSSE42() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ bool hasSSE4a() const
+ {
+ return hasExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+
bool hasAltivec() const
{
return hasExtension("Altivec");
@@ -473,6 +506,12 @@ private:
*((int*)(cpu_vendor+4)) = cpu_info[3];
*((int*)(cpu_vendor+8)) = cpu_info[2];
setInfo(eVendor, cpu_vendor);
+ std::string cmp_vendor(cpu_vendor);
+ bool is_amd = false;
+ if (cmp_vendor == "AuthenticAMD")
+ {
+ is_amd = true;
+ }
// Get the information associated with each valid Id
for(unsigned int i=0; i<=ids; ++i)
@@ -504,6 +543,7 @@ private:
if(cpu_info[2] & 0x8)
{
+ // intel specific SSE3 suplements
setExtension(cpu_feature_names[eMONTIOR_MWAIT]);
}
@@ -516,7 +556,22 @@ private:
{
setExtension(cpu_feature_names[eThermalMonitor2]);
}
-
+
+ if (cpu_info[2] & 0x200)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (cpu_info[2] & 0x80000)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (cpu_info[2] & 0x100000)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
unsigned int feature_info = (unsigned int) cpu_info[3];
for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)
{
@@ -543,8 +598,17 @@ private:
__cpuid(cpu_info, i);
// Interpret CPU brand string and cache information.
- if (i == 0x80000002)
- memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+ if (i == 0x80000001)
+ {
+ if (is_amd)
+ {
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+ }
+ else if (i == 0x80000002)
+ {
+ memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info));
+ }
else if (i == 0x80000003)
memcpy(cpu_brand_string + 16, cpu_info, sizeof(cpu_info));
else if (i == 0x80000004)
@@ -690,6 +754,41 @@ private:
uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits");
S32 *ext_feature_infos = (S32*)(&ext_feature_info);
setConfig(eExtFeatureBits, ext_feature_infos[0]);
+
+
+ char cpu_features[1024];
+ len = sizeof(cpu_features);
+ memset(cpu_features, 0, len);
+ sysctlbyname("machdep.cpu.features", (void*)cpu_features, &len, NULL, 0);
+
+ std::string cpu_features_str(cpu_features);
+ cpu_features_str = " " + cpu_features_str + " ";
+
+ if (cpu_features_str.find(" SSE3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ if (cpu_features_str.find(" SSSE3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4.1 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4.2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ if (cpu_features_str.find(" SSE4A ") != std::string::npos)
+ {
+ // Not supposed to happen?
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
}
};
@@ -800,6 +899,31 @@ private:
{
setExtension(cpu_feature_names[eSSE2_Ext]);
}
+
+ if (flags.find(" pni ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3_Features]);
+ }
+
+ if (flags.find(" ssse3 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+ }
+
+ if (flags.find(" sse4_1 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+ }
+
+ if (flags.find(" sse4_2 ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+ }
+
+ if (flags.find(" sse4a ") != std::string::npos)
+ {
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
# endif // LL_X86
}
@@ -860,6 +984,11 @@ LLProcessorInfo::~LLProcessorInfo() {}
F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
+bool LLProcessorInfo::hasSSE3() const { return mImpl->hasSSE3(); }
+bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); }
+bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); }
+bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); }
+bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); }
std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index b77eb22c3a..1a473ddc97 100644
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -54,6 +54,11 @@ public:
F64MegahertzImplicit getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
+ bool hasSSE3() const;
+ bool hasSSE3S() const;
+ bool hasSSE41() const;
+ bool hasSSE42() const;
+ bool hasSSE4a() const;
bool hasAltivec() const;
std::string getCPUFamilyName() const;
std::string getCPUBrandName() const;
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 9b6bb3826c..a8b5c7b3a8 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -64,6 +64,7 @@ using namespace llsd;
# include <psapi.h> // GetPerformanceInfo() et al.
# include <VersionHelpers.h>
#elif LL_DARWIN
+# include "llsys_objc.h"
# include <errno.h>
# include <sys/sysctl.h>
# include <sys/utsname.h>
@@ -74,12 +75,6 @@ using namespace llsd;
# include <mach/mach_host.h>
# include <mach/task.h>
# include <mach/task_info.h>
-
-// disable warnings about Gestalt calls being deprecated
-// until Apple get's on the ball and provides an alternative
-//
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
#elif LL_LINUX
# include <errno.h>
# include <sys/utsname.h>
@@ -278,12 +273,9 @@ LLOSInfo::LLOSInfo() :
{
const char * DARWIN_PRODUCT_NAME = "Mac OS X";
- SInt32 major_version, minor_version, bugfix_version;
- OSErr r1 = Gestalt(gestaltSystemVersionMajor, &major_version);
- OSErr r2 = Gestalt(gestaltSystemVersionMinor, &minor_version);
- OSErr r3 = Gestalt(gestaltSystemVersionBugFix, &bugfix_version);
+ S32 major_version, minor_version, bugfix_version = 0;
- if((r1 == noErr) && (r2 == noErr) && (r3 == noErr))
+ if (LLGetDarwinOSInfo(major_version, minor_version, bugfix_version))
{
mMajorVer = major_version;
mMinorVer = minor_version;
@@ -597,6 +589,11 @@ LLCPUInfo::LLCPUInfo()
// proc.WriteInfoTextFile("procInfo.txt");
mHasSSE = proc.hasSSE();
mHasSSE2 = proc.hasSSE2();
+ mHasSSE3 = proc.hasSSE3();
+ mHasSSE3S = proc.hasSSE3S();
+ mHasSSE41 = proc.hasSSE41();
+ mHasSSE42 = proc.hasSSE42();
+ mHasSSE4a = proc.hasSSE4a();
mHasAltivec = proc.hasAltivec();
mCPUMHz = (F64)proc.getCPUFrequency();
mFamily = proc.getCPUFamilyName();
@@ -609,6 +606,35 @@ LLCPUInfo::LLCPUInfo()
}
mCPUString = out.str();
LLStringUtil::trim(mCPUString);
+
+ if (mHasSSE)
+ {
+ mSSEVersions.append("1");
+ }
+ if (mHasSSE2)
+ {
+ mSSEVersions.append("2");
+ }
+ if (mHasSSE3)
+ {
+ mSSEVersions.append("3");
+ }
+ if (mHasSSE3S)
+ {
+ mSSEVersions.append("3S");
+ }
+ if (mHasSSE41)
+ {
+ mSSEVersions.append("4.1");
+ }
+ if (mHasSSE42)
+ {
+ mSSEVersions.append("4.2");
+ }
+ if (mHasSSE4a)
+ {
+ mSSEVersions.append("4a");
+ }
}
bool LLCPUInfo::hasAltivec() const
@@ -626,6 +652,31 @@ bool LLCPUInfo::hasSSE2() const
return mHasSSE2;
}
+bool LLCPUInfo::hasSSE3() const
+{
+ return mHasSSE3;
+}
+
+bool LLCPUInfo::hasSSE3S() const
+{
+ return mHasSSE3S;
+}
+
+bool LLCPUInfo::hasSSE41() const
+{
+ return mHasSSE41;
+}
+
+bool LLCPUInfo::hasSSE42() const
+{
+ return mHasSSE42;
+}
+
+bool LLCPUInfo::hasSSE4a() const
+{
+ return mHasSSE4a;
+}
+
F64 LLCPUInfo::getMHz() const
{
return mCPUMHz;
@@ -636,6 +687,11 @@ std::string LLCPUInfo::getCPUString() const
return mCPUString;
}
+const LLSD& LLCPUInfo::getSSEVersions() const
+{
+ return mSSEVersions;
+}
+
void LLCPUInfo::stream(std::ostream& s) const
{
// gather machine information.
@@ -645,6 +701,11 @@ void LLCPUInfo::stream(std::ostream& s) const
// CPU's attributes regardless of platform
s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl;
+ s << "->mHasSSE3: " << (U32)mHasSSE3 << std::endl;
+ s << "->mHasSSE3S: " << (U32)mHasSSE3S << std::endl;
+ s << "->mHasSSE41: " << (U32)mHasSSE41 << std::endl;
+ s << "->mHasSSE42: " << (U32)mHasSSE42 << std::endl;
+ s << "->mHasSSE4a: " << (U32)mHasSSE4a << std::endl;
s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl;
s << "->mCPUMHz: " << mCPUMHz << std::endl;
s << "->mCPUString: " << mCPUString << std::endl;
@@ -1341,10 +1402,3 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
if (dst != NULL) gzclose(dst);
return retval;
}
-
-#if LL_DARWIN
-// disable warnings about Gestalt calls being deprecated
-// until Apple get's on the ball and provides an alternative
-//
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index cb92cb0ac6..5ffbf5a732 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -80,10 +80,16 @@ public:
void stream(std::ostream& s) const;
std::string getCPUString() const;
+ const LLSD& getSSEVersions() const;
bool hasAltivec() const;
bool hasSSE() const;
bool hasSSE2() const;
+ bool hasSSE3() const;
+ bool hasSSE3S() const;
+ bool hasSSE41() const;
+ bool hasSSE42() const;
+ bool hasSSE4a() const;
F64 getMHz() const;
// Family is "AMD Duron" or "Intel Pentium Pro"
@@ -92,10 +98,16 @@ public:
private:
bool mHasSSE;
bool mHasSSE2;
+ bool mHasSSE3;
+ bool mHasSSE3S;
+ bool mHasSSE41;
+ bool mHasSSE42;
+ bool mHasSSE4a;
bool mHasAltivec;
F64 mCPUMHz;
std::string mFamily;
std::string mCPUString;
+ LLSD mSSEVersions;
};
//=============================================================================
diff --git a/indra/llcommon/llsys_objc.h b/indra/llcommon/llsys_objc.h
new file mode 100644
index 0000000000..35599a574b
--- /dev/null
+++ b/indra/llcommon/llsys_objc.h
@@ -0,0 +1,33 @@
+/**
+ * @file llsys_objc.h
+ * @brief Header file for llsys_objc.mm
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSYS_OBJC_H
+#define LL_LLSYS_OBJC_H
+
+bool LLGetDarwinOSInfo(int &major, int &minor, int &patch);
+
+
+#endif // LL_LLSYS_OBJC_H
diff --git a/indra/llcommon/llsys_objc.mm b/indra/llcommon/llsys_objc.mm
new file mode 100644
index 0000000000..cdb1e320d5
--- /dev/null
+++ b/indra/llcommon/llsys_objc.mm
@@ -0,0 +1,64 @@
+/**
+ * @file llsys_objc.mm
+ * @brief obj-c implementation of the system information functions
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#import "llsys_objc.h"
+#import <AppKit/AppKit.h>
+
+static int intAtStringIndex(NSArray *array, int index)
+{
+ return [(NSString *)[array objectAtIndex:index] integerValue];
+}
+
+bool LLGetDarwinOSInfo(int &major, int &minor, int &patch)
+{
+ if (NSAppKitVersionNumber > NSAppKitVersionNumber10_8)
+ {
+ NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
+ major = osVersion.majorVersion;
+ minor = osVersion.minorVersion;
+ patch = osVersion.patchVersion;
+ }
+ else
+ {
+ NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile:
+ @"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"];
+ NSArray* versions = [versionString componentsSeparatedByString:@"."];
+ NSUInteger count = [versions count];
+ if (count > 0)
+ {
+ major = intAtStringIndex(versions, 0);
+ if (count > 1)
+ {
+ minor = intAtStringIndex(versions, 1);
+ if (count > 2)
+ {
+ patch = intAtStringIndex(versions, 2);
+ }
+ }
+ }
+ }
+ return true;
+}
diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp
index ba914035e2..d5adf11264 100644
--- a/indra/llcommon/threadpool.cpp
+++ b/indra/llcommon/threadpool.cpp
@@ -22,6 +22,7 @@
#include "stringize.h"
LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity):
+ super(name),
mQueue(name, capacity),
mName("ThreadPool:" + name),
mThreadCount(threads)
diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h
index b79c9b9090..f8eec3b457 100644
--- a/indra/llcommon/threadpool.h
+++ b/indra/llcommon/threadpool.h
@@ -22,8 +22,10 @@
namespace LL
{
- class ThreadPool
+ class ThreadPool: public LLInstanceTracker<ThreadPool, std::string>
{
+ private:
+ using super = LLInstanceTracker<ThreadPool, std::string>;
public:
/**
* Pass ThreadPool a string name. This can be used to look up the
diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h
index 96574a18b9..70fd65bd0c 100644
--- a/indra/llcommon/workqueue.h
+++ b/indra/llcommon/workqueue.h
@@ -403,7 +403,7 @@ namespace LL
[result = std::forward<CALLABLE>(callable)(),
callback = std::move(callback)]
()
- { callback(std::move(result)); };
+ mutable { callback(std::move(result)); };
}
};
@@ -449,7 +449,7 @@ namespace LL
callable = std::move(callable),
callback = std::move(callback)]
()
- {
+ mutable {
// Use postMaybe() below in case this originating WorkQueue
// has been closed or destroyed. Remember, the outer lambda is
// now running on a thread servicing the target WorkQueue, and
@@ -513,7 +513,7 @@ namespace LL
// We dare to bind a reference to Promise because it's
// specifically designed for cross-thread communication.
[&promise, callable = std::move(callable)]()
- {
+ mutable {
try
{
// call the caller's callable and trigger promise with result
@@ -542,7 +542,7 @@ namespace LL
time,
// &promise is designed for cross-thread access
[&promise, callable = std::move(callable)]()
- {
+ mutable {
try
{
callable();
diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index ee43a599f7..6de99dfbff 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -131,28 +131,44 @@ void LLDiskCache::purge()
LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL;
+ std::vector<bool> file_removed;
+ if (mEnableCacheDebugInfo)
+ {
+ file_removed.reserve(file_info.size());
+ }
uintmax_t file_size_total = 0;
for (file_info_t& entry : file_info)
{
file_size_total += entry.second.first;
- std::string action = "";
- if (file_size_total > mMaxSizeBytes)
+ bool should_remove = file_size_total > mMaxSizeBytes;
+ if (mEnableCacheDebugInfo)
+ {
+ file_removed.push_back(should_remove);
+ }
+ if (should_remove)
{
- action = "DELETE:";
boost::filesystem::remove(entry.second.second, ec);
if (ec.failed())
{
LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL;
}
}
- else
- {
- action = " KEEP:";
- }
+ }
- if (mEnableCacheDebugInfo)
+ if (mEnableCacheDebugInfo)
+ {
+ auto end_time = std::chrono::high_resolution_clock::now();
+ auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
+
+ // Log afterward so it doesn't affect the time measurement
+ // Logging thousands of file results can take hundreds of milliseconds
+ for (size_t i = 0; i < file_info.size(); ++i)
{
+ const file_info_t& entry = file_info[i];
+ const bool removed = file_removed[i];
+ const std::string action = removed ? "DELETE:" : "KEEP:";
+
// have to do this because of LL_INFO/LL_END weirdness
std::ostringstream line;
@@ -163,12 +179,7 @@ void LLDiskCache::purge()
line << " (" << file_size_total << "/" << mMaxSizeBytes << ")";
LL_INFOS() << line.str() << LL_ENDL;
}
- }
- if (mEnableCacheDebugInfo)
- {
- auto end_time = std::chrono::high_resolution_clock::now();
- auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
LL_INFOS() << "Total dir size after purge is " << dirFileSize(mCacheDir) << LL_ENDL;
LL_INFOS() << "Cache purge took " << execute_time << " ms to execute for " << file_info.size() << " files" << LL_ENDL;
}
@@ -354,6 +365,38 @@ void LLDiskCache::clearCache()
}
}
+void LLDiskCache::removeOldVFSFiles()
+{
+ //VFS files won't be created, so consider removing this code later
+ static const char CACHE_FORMAT[] = "inv.llsd";
+ static const char DB_FORMAT[] = "db2.x";
+
+ boost::system::error_code ec;
+#if LL_WINDOWS
+ std::wstring cache_path(utf8str_to_utf16str(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "")));
+#else
+ std::string cache_path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""));
+#endif
+ if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
+ {
+ for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
+ {
+ if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
+ {
+ if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) ||
+ (entry.path().string().find(DB_FORMAT) != std::string::npos))
+ {
+ boost::filesystem::remove(entry, ec);
+ if (ec.failed())
+ {
+ LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
+ }
+ }
+ }
+ }
+ }
+}
+
uintmax_t LLDiskCache::dirFileSize(const std::string dir)
{
uintmax_t total_file_size = 0;
diff --git a/indra/llfilesystem/lldiskcache.h b/indra/llfilesystem/lldiskcache.h
index 1cbd2c58aa..b60e74f8c9 100644
--- a/indra/llfilesystem/lldiskcache.h
+++ b/indra/llfilesystem/lldiskcache.h
@@ -140,6 +140,8 @@ class LLDiskCache :
*/
const std::string getCacheInfo();
+ void removeOldVFSFiles();
+
private:
/**
* Utility function to gather the total size the files in a given
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index e25dae8a90..134e783053 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -234,6 +234,8 @@ void LLParcel::init(const LLUUID &owner_id,
setRegionAllowEnvironmentOverride(FALSE);
setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION);
+
+ setObscureMOAP(false);
}
void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned)
@@ -540,6 +542,7 @@ void LLParcel::packMessage(LLSD& msg)
msg["see_avs"] = (LLSD::Boolean) getSeeAVs();
msg["group_av_sounds"] = (LLSD::Boolean) getAllowGroupAVSounds();
msg["any_av_sounds"] = (LLSD::Boolean) getAllowAnyAVSounds();
+ msg["obscure_moap"] = (LLSD::Boolean) getObscureMOAP();
}
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 5d08c1f4c6..f5ee1241ab 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -306,6 +306,7 @@ public:
void setRestrictPushObject(BOOL b) { setParcelFlag(PF_RESTRICT_PUSHOBJECT, b); }
void setAllowGroupAVSounds(BOOL b) { mAllowGroupAVSounds = b; }
void setAllowAnyAVSounds(BOOL b) { mAllowAnyAVSounds = b; }
+ void setObscureMOAP(bool b) { mObscureMOAP = b; }
void setDrawDistance(F32 dist) { mDrawDistance = dist; }
void setSalePrice(S32 price) { mSalePrice = price; }
@@ -517,6 +518,8 @@ public:
BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; }
BOOL getAllowAnyAVSounds() const { return mAllowAnyAVSounds; }
+
+ bool getObscureMOAP() const { return mObscureMOAP; }
F32 getDrawDistance() const { return mDrawDistance; }
S32 getSalePrice() const { return mSalePrice; }
@@ -670,6 +673,7 @@ protected:
BOOL mRegionAllowEnvironmentOverride;
BOOL mAllowGroupAVSounds;
BOOL mAllowAnyAVSounds;
+ bool mObscureMOAP;
S32 mCurrentEnvironmentVersion;
bool mIsDefaultDayCycle;
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index a9a54a8113..318ee65cc0 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -48,52 +48,59 @@ extern float gOctreeMinSize;
#define LL_OCTREE_MAX_CAPACITY 128
#endif*/
-template <class T> class LLOctreeNode;
-
-template <class T>
+// T is the type of the element referenced by the octree node.
+// T_PTR determines how pointers to elements are stored internally.
+// LLOctreeNode<T, LLPointer<T>> assumes ownership of inserted elements and
+// deletes elements removed from the tree.
+// LLOctreeNode<T, T*> doesn't take ownership of inserted elements, so the API
+// user is responsible for managing the storage lifecycle of elements added to
+// the tree.
+template <class T, typename T_PTR> class LLOctreeNode;
+
+template <class T, typename T_PTR>
class LLOctreeListener: public LLTreeListener<T>
{
public:
typedef LLTreeListener<T> BaseType;
- typedef LLOctreeNode<T> oct_node;
+ typedef LLOctreeNode<T, T_PTR> oct_node;
virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0;
virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0;
};
-template <class T>
+template <class T, typename T_PTR>
class LLOctreeTraveler
{
public:
- virtual void traverse(const LLOctreeNode<T>* node);
- virtual void visit(const LLOctreeNode<T>* branch) = 0;
+ virtual void traverse(const LLOctreeNode<T, T_PTR>* node);
+ virtual void visit(const LLOctreeNode<T, T_PTR>* branch) = 0;
};
-template <class T>
-class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T>
+template <class T, typename T_PTR>
+class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T, T_PTR>
{
public:
- virtual void traverse(const LLOctreeNode<T>* node) override;
+ virtual void traverse(const LLOctreeNode<T, T_PTR>* node) override;
};
-template <class T>
+template <class T, typename T_PTR>
class alignas(16) LLOctreeNode : public LLTreeNode<T>
{
LL_ALIGN_NEW
public:
- typedef LLOctreeTraveler<T> oct_traveler;
- typedef LLTreeTraveler<T> tree_traveler;
- typedef std::vector< LLPointer<T> > element_list; // note: don't remove the whitespace between "> >"
- typedef LLPointer<T>* element_iter;
- typedef const LLPointer<T>* const_element_iter;
+ typedef LLOctreeTraveler<T, T_PTR> oct_traveler;
+ typedef LLTreeTraveler<T> tree_traveler;
+ typedef std::vector<T_PTR> element_list;
+ typedef typename element_list::iterator element_iter;
+ typedef typename element_list::const_iterator const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
- typedef LLOctreeNode<T>** child_list;
- typedef LLOctreeNode<T>** child_iter;
+ typedef LLOctreeNode<T, T_PTR>** child_list;
+ typedef LLOctreeNode<T, T_PTR>** child_iter;
- typedef LLTreeNode<T> BaseType;
- typedef LLOctreeNode<T> oct_node;
- typedef LLOctreeListener<T> oct_listener;
+ typedef LLTreeNode<T> BaseType;
+ typedef LLOctreeNode<T, T_PTR> oct_node;
+ typedef LLOctreeListener<T, T_PTR> oct_listener;
enum
{
@@ -108,9 +115,6 @@ public:
mOctant(octant)
{
llassert(size[0] >= gOctreeMinSize*0.5f);
- //always keep a NULL terminated list to avoid out of bounds exceptions in debug builds
- mData.push_back(NULL);
- mDataEnd = &mData[0];
mCenter = center;
mSize = size;
@@ -121,8 +125,6 @@ public:
mOctant = ((oct_node*) mParent)->getOctant(mCenter);
}
- mElementCount = 0;
-
clearChildren();
}
@@ -130,15 +132,14 @@ public:
{
BaseType::destroyListeners();
- for (U32 i = 0; i < mElementCount; ++i)
+ const U32 element_count = getElementCount();
+ for (U32 i = 0; i < element_count; ++i)
{
mData[i]->setBinIndex(-1);
mData[i] = NULL;
}
mData.clear();
- mData.push_back(NULL);
- mDataEnd = &mData[0];
for (U32 i = 0; i < getChildCount(); i++)
{
@@ -238,14 +239,12 @@ public:
void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChildCount == 0; }
- U32 getElementCount() const { return mElementCount; }
- bool isEmpty() const { return mElementCount == 0; }
- element_list& getData() { return mData; }
- const element_list& getData() const { return mData; }
- element_iter getDataBegin() { return &mData[0]; }
- element_iter getDataEnd() { return mDataEnd; }
- const_element_iter getDataBegin() const { return &mData[0]; }
- const_element_iter getDataEnd() const { return mDataEnd; }
+ U32 getElementCount() const { return (U32)mData.size(); }
+ bool isEmpty() const { return mData.empty(); }
+ element_iter getDataBegin() { return mData.begin(); }
+ element_iter getDataEnd() { return mData.end(); }
+ const_element_iter getDataBegin() const { return mData.cbegin(); }
+ const_element_iter getDataEnd() const { return mData.cend(); }
U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; }
@@ -263,7 +262,7 @@ public:
U8 idx = mChildMap[i];
if (idx != NO_CHILD_NODES)
{
- LLOctreeNode<T>* child = mChild[idx];
+ oct_node* child = mChild[idx];
if (child->getOctant() != i)
{
@@ -281,7 +280,7 @@ public:
oct_node* getNodeAt(const LLVector4a& pos, const F32& rad)
{
- LLOctreeNode<T>* node = this;
+ oct_node* node = this;
if (node->isInside(pos, rad))
{
@@ -303,7 +302,7 @@ public:
}
else if (!node->contains(rad) && node->getParent())
{ //if we got here, data does not exist in this node
- return ((LLOctreeNode<T>*) node->getParent())->getNodeAt(pos, rad);
+ return ((oct_node*) node->getParent())->getNodeAt(pos, rad);
}
return node;
@@ -318,7 +317,7 @@ public:
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL;
return false;
}
- LLOctreeNode<T>* parent = getOctParent();
+ oct_node* parent = getOctParent();
//is it here?
if (isInside(data->getPositionGroup()))
@@ -326,11 +325,8 @@ public:
if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
- mData.push_back(NULL);
- mData[mElementCount] = data;
- mElementCount++;
- mDataEnd = &mData[mElementCount];
- data->setBinIndex(mElementCount-1);
+ mData.push_back(data);
+ data->setBinIndex(getElementCount() - 1);
BaseType::insert(data);
return true;
}
@@ -354,7 +350,7 @@ public:
size.mul(0.5f);
//push center in direction of data
- LLOctreeNode<T>::pushCenter(center, size, data);
+ oct_node::pushCenter(center, size, data);
// handle case where floating point number gets too small
LLVector4a val;
@@ -366,11 +362,8 @@ public:
if( lt == 0x7 )
{
- mData.push_back(NULL);
- mData[mElementCount] = data;
- mElementCount++;
- mDataEnd = &mData[mElementCount];
- data->setBinIndex(mElementCount-1);
+ mData.push_back(data);
+ data->setBinIndex(getElementCount() - 1);
BaseType::insert(data);
return true;
}
@@ -396,7 +389,7 @@ public:
llassert(size[0] >= gOctreeMinSize*0.5f);
//make the new kid
- child = new LLOctreeNode<T>(center, size, this);
+ child = new oct_node(center, size, this);
addChild(child);
child->insert(data);
@@ -429,28 +422,25 @@ public:
}
void _remove(T* data, S32 i)
- { //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
+ { //precondition -- getElementCount() > 0, idx is in range [0, getElementCount())
- mElementCount--;
data->setBinIndex(-1);
- if (mElementCount > 0)
+ const U32 new_element_count = getElementCount() - 1;
+ if (new_element_count > 0)
{
- if (mElementCount != i)
+ if (new_element_count != i)
{
- mData[i] = mData[mElementCount]; //might unref data, do not access data after this point
+ mData[i] = mData[new_element_count]; //might unref data, do not access data after this point
mData[i]->setBinIndex(i);
}
- mData[mElementCount] = NULL;
+ mData[new_element_count] = NULL;
mData.pop_back();
- mDataEnd = &mData[mElementCount];
}
else
{
mData.clear();
- mData.push_back(NULL);
- mDataEnd = &mData[0];
}
this->notifyRemoval(data);
@@ -463,7 +453,7 @@ public:
S32 i = data->getBinIndex();
- if (i >= 0 && i < mElementCount)
+ if (i >= 0 && i < getElementCount())
{
if (mData[i] == data)
{ //found it
@@ -506,7 +496,8 @@ public:
void removeByAddress(T* data)
{
- for (U32 i = 0; i < mElementCount; ++i)
+ const U32 element_count = getElementCount();
+ for (U32 i = 0; i < element_count; ++i)
{
if (mData[i] == data)
{ //we have data
@@ -518,7 +509,7 @@ public:
for (U32 i = 0; i < getChildCount(); i++)
{ //we don't contain data, so pass this guy down
- LLOctreeNode<T>* child = (LLOctreeNode<T>*) getChild(i);
+ oct_node* child = (oct_node*) getChild(i);
child->removeByAddress(data);
}
}
@@ -672,22 +663,20 @@ protected:
oct_node* mParent;
U8 mOctant;
- LLOctreeNode<T>* mChild[8];
+ oct_node* mChild[8];
U8 mChildMap[8];
U32 mChildCount;
element_list mData;
- element_iter mDataEnd;
- U32 mElementCount;
};
//just like a regular node, except it might expand on insert and compress on balance
-template <class T>
-class LLOctreeRoot : public LLOctreeNode<T>
+template <class T, typename T_PTR>
+class LLOctreeRoot : public LLOctreeNode<T, T_PTR>
{
public:
- typedef LLOctreeNode<T> BaseType;
- typedef LLOctreeNode<T> oct_node;
+ typedef LLOctreeNode<T, T_PTR> BaseType;
+ typedef LLOctreeNode<T, T_PTR> oct_node;
LLOctreeRoot(const LLVector4a& center,
const LLVector4a& size,
@@ -768,7 +757,7 @@ public:
oct_node* node = this->getNodeAt(data);
if (node == this)
{
- LLOctreeNode<T>::insert(data);
+ oct_node::insert(data);
}
else if (node->isInside(data->getPositionGroup()))
{
@@ -788,13 +777,13 @@ public:
LLVector4a center, size;
center = this->getCenter();
size = this->getSize();
- LLOctreeNode<T>::pushCenter(center, size, data);
+ oct_node::pushCenter(center, size, data);
this->setCenter(center);
size.mul(2.f);
this->setSize(size);
this->updateMinMax();
}
- LLOctreeNode<T>::insert(data);
+ oct_node::insert(data);
}
else
{
@@ -806,7 +795,7 @@ public:
//expand this node
LLVector4a newcenter(center);
- LLOctreeNode<T>::pushCenter(newcenter, size, data);
+ oct_node::pushCenter(newcenter, size, data);
this->setCenter(newcenter);
LLVector4a size2 = size;
size2.mul(2.f);
@@ -816,11 +805,11 @@ public:
llassert(size[0] >= gOctreeMinSize);
//copy our children to a new branch
- LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this);
+ oct_node* newnode = new oct_node(center, size, this);
for (U32 i = 0; i < this->getChildCount(); i++)
{
- LLOctreeNode<T>* child = this->getChild(i);
+ oct_node* child = this->getChild(i);
newnode->addChild(child);
}
@@ -846,8 +835,8 @@ public:
//========================
// LLOctreeTraveler
//========================
-template <class T>
-void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
+template <class T, typename T_PTR>
+void LLOctreeTraveler<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)
{
node->accept(this);
for (U32 i = 0; i < node->getChildCount(); i++)
@@ -856,8 +845,8 @@ void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
}
}
-template <class T>
-void LLOctreeTravelerDepthFirst<T>::traverse(const LLOctreeNode<T>* node)
+template <class T, typename T_PTR>
+void LLOctreeTravelerDepthFirst<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)
{
for (U32 i = 0; i < node->getChildCount(); i++)
{
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 4a069b0f63..f43d07ce5e 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -371,7 +371,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons
}
}
-class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle>
+class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>
{
public:
const LLVolumeFace* mFace;
@@ -381,7 +381,7 @@ public:
mFace = face;
}
- virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+ virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{ //this is a depth first traversal, so it's safe to assum all children have complete
//bounding data
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
@@ -399,8 +399,7 @@ public:
min = *(tri->mV[0]);
max = *(tri->mV[0]);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
- branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
+ for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
{ //for each triangle in node
//stretch by triangles in node
@@ -684,7 +683,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
- static LLAlignedArray<LLVector4a,64> pt;
+ static thread_local LLAlignedArray<LLVector4a,64> pt;
pt.resize(mTotal) ;
for (S32 i=mTotalOut;i<mTotal;i++)
@@ -1625,9 +1624,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
//genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
genNGon(params, llfloor(MIN_DETAIL_FACES * detail));
- F32 t = 0.f;
- F32 tStep = 1.0f / mPath.size();
-
F32 toggle = 0.5f;
for (S32 i=0;i<(S32)mPath.size();i++)
{
@@ -1636,7 +1632,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
toggle = -0.5f;
else
toggle = 0.5f;
- t += tStep;
}
}
@@ -2427,6 +2422,13 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
//copy out indices
S32 num_indices = idx.size() / 2;
+ const S32 indices_to_discard = num_indices % 3;
+ if (indices_to_discard > 0)
+ {
+ // Invalid number of triangle indices
+ LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL;
+ num_indices -= indices_to_discard;
+ }
face.resizeIndices(num_indices);
if (num_indices > 2 && !face.mIndices)
@@ -2442,8 +2444,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
U16* indices = (U16*) &(idx[0]);
- U32 count = idx.size()/2;
- for (U32 j = 0; j < count; ++j)
+ for (U32 j = 0; j < num_indices; ++j)
{
face.mIndices[j] = indices[j];
}
@@ -3835,8 +3836,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
#if DEBUG_SILHOUETTE_EDGE_MAP
//for each triangle
- U32 count = face.mNumIndices;
- for (U32 j = 0; j < count/3; j++) {
+ U32 tri_count = face.mNumIndices / 3;
+ for (U32 j = 0; j < tri_count; j++) {
//get vertices
S32 v1 = face.mIndices[j*3+0];
S32 v2 = face.mIndices[j*3+1];
@@ -3854,7 +3855,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
continue;
}
- if (nIndex >= (S32) count/3) {
+ if (nIndex >= (S32)tri_count) {
continue;
}
//get neighbor vertices
@@ -4146,13 +4147,13 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
}
else
{
- if (!face.mOctree)
+ if (!face.getOctree())
{
face.createOctree();
}
LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
- intersect.traverse(face.mOctree);
+ intersect.traverse(face.getOctree());
if (intersect.mHitFace)
{
hit_face = i;
@@ -4707,6 +4708,7 @@ LLVolumeFace::LLVolumeFace() :
#endif
mWeightsScrubbed(FALSE),
mOctree(NULL),
+ mOctreeTriangles(NULL),
mOptimized(FALSE)
{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
@@ -4736,8 +4738,9 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mJointIndices(NULL),
#endif
mWeightsScrubbed(FALSE),
- mOctree(NULL)
-{
+ mOctree(NULL),
+ mOctreeTriangles(NULL)
+{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
mCenter = mExtents+2;
*this = src;
@@ -4877,8 +4880,7 @@ void LLVolumeFace::freeData()
mJustWeights = NULL;
#endif
- delete mOctree;
- mOctree = NULL;
+ destroyOctree();
}
BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
@@ -4886,8 +4888,7 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
//tree for this face is no longer valid
- delete mOctree;
- mOctree = NULL;
+ destroyOctree();
LL_CHECK_MEMORY
BOOL ret = FALSE ;
@@ -5600,21 +5601,27 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
- if (mOctree)
+ if (getOctree())
{
return;
}
- mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL);
+ llassert(mNumIndices % 3 == 0);
+
+ mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(center, size, NULL);
new LLVolumeOctreeListener(mOctree);
+ const U32 num_triangles = mNumIndices / 3;
+ // Initialize all the triangles we need
+ mOctreeTriangles = new LLVolumeTriangle[num_triangles];
- for (U32 i = 0; i < mNumIndices; i+= 3)
+ for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index)
{ //for each triangle
- LLPointer<LLVolumeTriangle> tri = new LLVolumeTriangle();
+ const U32 index = triangle_index * 3;
+ LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index];
- const LLVector4a& v0 = mPositions[mIndices[i]];
- const LLVector4a& v1 = mPositions[mIndices[i+1]];
- const LLVector4a& v2 = mPositions[mIndices[i+2]];
+ const LLVector4a& v0 = mPositions[mIndices[index]];
+ const LLVector4a& v1 = mPositions[mIndices[index + 1]];
+ const LLVector4a& v2 = mPositions[mIndices[index + 2]];
//store pointers to vertex data
tri->mV[0] = &v0;
@@ -5622,9 +5629,9 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
tri->mV[2] = &v2;
//store indices
- tri->mIndex[0] = mIndices[i];
- tri->mIndex[1] = mIndices[i+1];
- tri->mIndex[2] = mIndices[i+2];
+ tri->mIndex[0] = mIndices[index];
+ tri->mIndex[1] = mIndices[index + 1];
+ tri->mIndex[2] = mIndices[index + 2];
//get minimum point
LLVector4a min = v0;
@@ -5667,6 +5674,19 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
}
}
+void LLVolumeFace::destroyOctree()
+{
+ delete mOctree;
+ mOctree = NULL;
+ delete[] mOctreeTriangles;
+ mOctreeTriangles = NULL;
+}
+
+const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree() const
+{
+ return mOctree;
+}
+
void LLVolumeFace::swapData(LLVolumeFace& rhs)
{
@@ -6538,6 +6558,7 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts)
void LLVolumeFace::resizeIndices(S32 num_indices)
{
ll_aligned_free_16(mIndices);
+ llassert(num_indices % 3 == 0);
if (num_indices)
{
@@ -6674,13 +6695,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
else
{
// Get s value for tex-coord.
- if (!flat)
+ S32 index = mBeginS + s;
+ if (index >= profile.size())
+ {
+ // edge?
+ ss = flat ? 1.f - begin_stex : 1.f;
+ }
+ else if (!flat)
{
- ss = profile[mBeginS + s][2];
+ ss = profile[index][2];
}
else
{
- ss = profile[mBeginS + s][2] - begin_stex;
+ ss = profile[index][2] - begin_stex;
}
}
@@ -6866,7 +6893,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LLVector4a* norm = mNormals;
- static LLAlignedArray<LLVector4a, 64> triangle_normals;
+ static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals;
try
{
triangle_normals.resize(count);
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 9697952f5b..3ccaed47f1 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -35,7 +35,8 @@ class LLVolumeParams;
class LLProfile;
class LLPath;
-template <class T> class LLOctreeNode;
+template<class T> class LLPointer;
+template <class T, typename T_PTR> class LLOctreeNode;
class LLVolumeFace;
class LLVolume;
@@ -910,6 +911,9 @@ public:
bool cacheOptimize();
void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f));
+ void destroyOctree();
+ // Get a reference to the octree, which may be null
+ const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* getOctree() const;
enum
{
@@ -977,13 +981,14 @@ public:
// Which joints are rigged to, and the bounding box of any rigged
// vertices per joint.
LLJointRiggingInfoTab mJointRiggingInfoTab;
-
- LLOctreeNode<LLVolumeTriangle>* mOctree;
//whether or not face has been cache optimized
BOOL mOptimized;
private:
+ LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* mOctree;
+ LLVolumeTriangle* mOctreeTriangles;
+
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE);
diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp
index fb232d5f6c..6894d04d3c 100644
--- a/indra/llmath/llvolumeoctree.cpp
+++ b/indra/llmath/llvolumeoctree.cpp
@@ -75,7 +75,7 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c
}
-LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node)
+LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
node->addListener(this);
}
@@ -85,13 +85,12 @@ LLVolumeOctreeListener::~LLVolumeOctreeListener()
}
-void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
- LLOctreeNode<LLVolumeTriangle>* child)
+void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent,
+ LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child)
{
new LLVolumeOctreeListener(child);
}
-
LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
const LLVolumeFace* face, F32* closest_t,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
@@ -108,7 +107,7 @@ LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& sta
mEnd.setAdd(mStart, mDir);
}
-void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>* node)
+void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
@@ -122,9 +121,9 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
}
}
-void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node)
+void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
+ for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter =
node->getDataBegin(); iter != node->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
@@ -219,7 +218,7 @@ const F32& LLVolumeTriangle::getBinRadius() const
//TEST CODE
-void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{
LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
@@ -256,7 +255,7 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
//children fit, check data
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
iter != branch->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
@@ -273,4 +272,3 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
}
-
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index b2bc440368..d65bca5e52 100644
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -77,11 +77,11 @@ public:
};
-class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
+class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle, LLVolumeTriangle*>
{
LL_ALIGN_NEW
public:
- LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node);
+ LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
~LLVolumeOctreeListener();
LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs)
@@ -96,11 +96,9 @@ public:
}
//LISTENER FUNCTIONS
- virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
- LLOctreeNode<LLVolumeTriangle>* child);
+ virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child);
virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { }
- virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent,
- const LLOctreeNode<LLVolumeTriangle>* child) { }
+ virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child) { }
virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { }
@@ -111,7 +109,7 @@ public:
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
};
-class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle>
+class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
{
public:
const LLVolumeFace* mFace;
@@ -129,14 +127,14 @@ public:
const LLVolumeFace* face, F32* closest_t,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
- void traverse(const LLOctreeNode<LLVolumeTriangle>* node);
+ void traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
- virtual void visit(const LLOctreeNode<LLVolumeTriangle>* node);
+ virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
};
-class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle>
+class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
{
- virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch);
+ virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch);
};
#endif
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index c67f59bc0c..846549b368 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -196,6 +196,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
}
}
+ catch (const LLCoros::Stop&)
+ {
+ LL_DEBUGS("AvNameCache") << "Received a shutdown exception" << LL_ENDL;
+ }
catch (...)
{
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName()
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index 2d460826ff..c5bc37dd0e 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -32,7 +32,6 @@
#include "llcoros.h"
#include "llcorehttputil.h"
#include "lluuid.h"
-#include <boost/smart_ptr/shared_ptr.hpp>
class LLCoprocedurePool;
@@ -84,7 +83,7 @@ public:
private:
- typedef boost::shared_ptr<LLCoprocedurePool> poolPtr_t;
+ typedef std::shared_ptr<LLCoprocedurePool> poolPtr_t;
typedef std::map<std::string, poolPtr_t> poolMap_t;
poolMap_t mPoolMap;
diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp
index 96c1297e0d..b6adc102d2 100644
--- a/indra/llmessage/lldatapacker.cpp
+++ b/indra/llmessage/lldatapacker.cpp
@@ -127,13 +127,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,
total_bits++;
}
- S32 min_val;
U32 max_val;
- if (is_signed)
- {
- min_val = 1 << int_bits;
- min_val *= -1;
- }
max_val = 1 << int_bits;
F32 fixed_val;
diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp
index 53aa35c0f9..6664eb02dc 100644
--- a/indra/llmessage/llpartdata.cpp
+++ b/indra/llmessage/llpartdata.cpp
@@ -311,8 +311,9 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp)
std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
{
s << "Flags: " << std::hex << data.mFlags;
- s << " Pattern: " << std::hex << (U32) data.mPattern << "\n";
- s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
+ s << "Pattern: " << std::hex << (U32) data.mPattern << "\n";
+ s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
+ s << "Particle Age: " << data.mPartData.mMaxAge << "\n";
s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n";
s << "Burst Rate: " << data.mBurstRate << "\n";
s << "Burst Radius: " << data.mBurstRadius << "\n";
diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp
index 7605da4d3f..935af2aa5a 100644
--- a/indra/llmessage/llthrottle.cpp
+++ b/indra/llmessage/llthrottle.cpp
@@ -374,7 +374,6 @@ BOOL LLThrottleGroup::dynamicAdjust()
}
mDynamicAdjustTime = mt_sec;
- S32 total = 0;
// Update historical information
for (i = 0; i < TC_EOF; i++)
{
@@ -391,7 +390,6 @@ BOOL LLThrottleGroup::dynamicAdjust()
}
mBitsSentThisPeriod[i] = 0;
- total += ll_round(mBitsSentHistory[i]);
}
// Look for busy channels
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 219b1855d2..35dcbe3836 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -1386,6 +1386,7 @@ char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getIns
char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
char const* const _PREHASH_ParcelEnvironmentBlock = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentBlock");
char const* const _PREHASH_ParcelEnvironmentVersion = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentVersion");
+char const* const _PREHASH_ParcelExtendedFlags = LLMessageStringTable::getInstance()->getString("ParcelExtendedFlags");
char const* const _PREHASH_RegionAllowEnvironmentOverride = LLMessageStringTable::getInstance()->getString("RegionAllowEnvironmentOverride");
char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 8f6ee5a327..3015f438b5 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -1386,6 +1386,7 @@ extern char const* const _PREHASH_RegionAllowAccessBlock;
extern char const* const _PREHASH_RegionAllowAccessOverride;
extern char const* const _PREHASH_ParcelEnvironmentBlock;
extern char const* const _PREHASH_ParcelEnvironmentVersion;
+extern char const* const _PREHASH_ParcelExtendedFlags;
extern char const* const _PREHASH_RegionAllowEnvironmentOverride;
extern char const* const _PREHASH_UCoord;
extern char const* const _PREHASH_VCoord;
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 6f88232c1d..3e72710366 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -1549,6 +1549,7 @@ void LLPluginClassMedia::seek(float time)
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
message.setValueReal("time", time);
+ mCurrentTime = time; // assume that it worked and we will receive an update later
sendMessage(message);
}
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index eef22156bc..1fbbad06d4 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -999,7 +999,7 @@ void LLPluginProcessParent::poll(F64 timeout)
while (itClean != sInstances.end())
{
if ((*itClean).second->isDone())
- sInstances.erase(itClean++);
+ itClean = sInstances.erase(itClean);
else
++itClean;
}
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 285c5f656b..805af55299 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -379,6 +379,8 @@ void LLModel::setVolumeFaceData(
U32 num_verts,
U32 num_indices)
{
+ llassert(num_indices % 3 == 0);
+
LLVolumeFace& face = mVolumeFaces[f];
face.resizeVertices(num_verts);
@@ -843,7 +845,7 @@ LLSD LLModel::writeModel(
{
LLVector3 pos(face.mPositions[j].getF32ptr());
- weight_list& weights = high->getJointInfluences(pos);
+ weight_list& weights = model[idx]->getJointInfluences(pos);
S32 count = 0;
for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter)
@@ -889,8 +891,6 @@ LLSD LLModel::writeModel(
LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm)
{
- U32 bytes = 0;
-
std::string::size_type cur_offset = 0;
LLSD header;
@@ -912,7 +912,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header["skin"]["offset"] = (LLSD::Integer) cur_offset;
header["skin"]["size"] = (LLSD::Integer) size;
cur_offset += size;
- bytes += size;
}
}
@@ -928,7 +927,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset;
header["physics_convex"]["size"] = (LLSD::Integer) size;
cur_offset += size;
- bytes += size;
}
}
@@ -950,7 +948,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset;
header[model_names[i]]["size"] = (LLSD::Integer) size;
cur_offset += size;
- bytes += size;
}
}
@@ -1553,6 +1550,25 @@ void LLMeshSkinInfo::updateHash()
mHash = digest[0];
}
+U32 LLMeshSkinInfo::sizeBytes() const
+{
+ U32 res = sizeof(LLUUID); // mMeshID
+
+ res += sizeof(std::vector<std::string>) + sizeof(std::string) * mJointNames.size();
+ for (U32 i = 0; i < mJointNames.size(); ++i)
+ {
+ res += mJointNames[i].size(); // actual size, not capacity
+ }
+
+ res += sizeof(std::vector<S32>) + sizeof(S32) * mJointNums.size();
+ res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mInvBindMatrix.size();
+ res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mAlternateBindMatrix.size();
+ res += 16 * sizeof(float); //mBindShapeMatrix
+ res += sizeof(float) + 3 * sizeof(bool);
+
+ return res;
+}
+
LLModel::Decomposition::Decomposition(LLSD& data)
{
fromLLSD(data);
@@ -1659,6 +1675,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
}
}
+U32 LLModel::Decomposition::sizeBytes() const
+{
+ U32 res = sizeof(LLUUID); // mMeshID
+
+ res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector<LLVector3>) * mHull.size();
+ for (U32 i = 0; i < mHull.size(); ++i)
+ {
+ res += mHull[i].size() * sizeof(LLVector3);
+ }
+
+ res += sizeof(LLModel::hull) + sizeof(LLVector3) * mBaseHull.size();
+
+ res += sizeof(std::vector<LLModel::PhysicsMesh>) + sizeof(std::vector<LLModel::PhysicsMesh>) * mMesh.size();
+ for (U32 i = 0; i < mMesh.size(); ++i)
+ {
+ res += mMesh[i].sizeBytes();
+ }
+
+ res += sizeof(std::vector<LLModel::PhysicsMesh>) * 2;
+ res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes();
+
+ return res;
+}
+
bool LLModel::Decomposition::hasHullList() const
{
return !mHull.empty() ;
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 354ceb26b7..a6ab96ab18 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -50,6 +50,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
void updateHash();
+ U32 sizeBytes() const;
LLUUID mMeshID;
std::vector<std::string> mJointNames;
@@ -112,6 +113,14 @@ public:
{
return mPositions.empty();
}
+
+ U32 sizeBytes() const
+ {
+ U32 res = sizeof(std::vector<LLVector3>) * 2;
+ res += sizeof(LLVector3) * mPositions.size();
+ res += sizeof(LLVector3) * mNormals.size();
+ return res;
+ }
};
class Decomposition
@@ -122,6 +131,7 @@ public:
void fromLLSD(LLSD& data);
LLSD asLLSD() const;
bool hasHullList() const;
+ U32 sizeBytes() const;
void merge(const Decomposition* rhs);
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 2b7ce155f6..193cfa64b8 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -743,6 +743,14 @@ bool LLGLManager::initGL()
LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL;
return false;
}
+
+ if (!mHasFramebufferObject)
+ {
+ mHasRequirements = FALSE;
+
+ LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_framebuffer_object" << LL_ENDL;
+ return false;
+ }
stop_glerror();
@@ -758,12 +766,6 @@ bool LLGLManager::initGL()
//HACK always disable texture multisample, use FXAA instead
mHasTextureMultisample = FALSE;
-#if LL_WINDOWS
- if (mIsIntel && mGLVersion <= 3.f)
- { //never try to use framebuffer objects on older intel drivers (crashy)
- mHasFramebufferObject = FALSE;
- }
-#endif
if (mHasFramebufferObject)
{
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 9bd3a0a6b0..9dc140b5b9 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1248,7 +1248,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@@ -1268,7 +1273,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@@ -1291,7 +1301,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
if (pixels != nullptr)
{
use_scratch = true;
- scratch = new U32[width * height];
+ scratch = new(std::nothrow) U32[width * height];
+ if (!scratch)
+ {
+ LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
+ << " bytes for a manual image W" << width << " H" << height << LL_ENDL;
+ }
U32 pixel_count = (U32)(width * height);
for (U32 i = 0; i < pixel_count; i++)
@@ -2432,7 +2447,7 @@ void LLImageGLThread::run()
// We must perform setup on this thread before actually servicing our
// WorkQueue, likewise cleanup afterwards.
mWindow->makeContextCurrent(mContext);
- gGL.init();
+ gGL.init(false);
ThreadPool::run();
gGL.shutdown();
mWindow->destroySharedContext(mContext);
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index a03a27cf94..72cca1f2a2 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -869,7 +869,7 @@ LLRender::~LLRender()
shutdown();
}
-void LLRender::init()
+void LLRender::init(bool needs_vertex_buffer)
{
#if LL_WINDOWS
if (gGLManager.mHasDebugOutput && gDebugGL)
@@ -897,15 +897,27 @@ void LLRender::init()
#endif
}
+ if (needs_vertex_buffer)
+ {
+ initVertexBuffer();
+ }
+}
- llassert_always(mBuffer.isNull()) ;
- stop_glerror();
- mBuffer = new LLVertexBuffer(immediate_mask, 0);
- mBuffer->allocateBuffer(4096, 0, TRUE);
- mBuffer->getVertexStrider(mVerticesp);
- mBuffer->getTexCoord0Strider(mTexcoordsp);
- mBuffer->getColorStrider(mColorsp);
- stop_glerror();
+void LLRender::initVertexBuffer()
+{
+ llassert_always(mBuffer.isNull());
+ stop_glerror();
+ mBuffer = new LLVertexBuffer(immediate_mask, 0);
+ mBuffer->allocateBuffer(4096, 0, TRUE);
+ mBuffer->getVertexStrider(mVerticesp);
+ mBuffer->getTexCoord0Strider(mTexcoordsp);
+ mBuffer->getColorStrider(mColorsp);
+ stop_glerror();
+}
+
+void LLRender::resetVertexBuffer()
+{
+ mBuffer = NULL;
}
void LLRender::shutdown()
@@ -923,7 +935,7 @@ void LLRender::shutdown()
delete mLightState[i];
}
mLightState.clear();
- mBuffer = NULL ;
+ resetVertexBuffer();
}
void LLRender::refreshState(void)
@@ -1625,25 +1637,34 @@ void LLRender::flush()
mCount = 0;
- if (mBuffer->useVBOs() && !mBuffer->isLocked())
- { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
- mBuffer->getVertexStrider(mVerticesp, 0, count);
- mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
- mBuffer->getColorStrider(mColorsp, 0, count);
- }
-
- mBuffer->flush();
- mBuffer->setBuffer(immediate_mask);
+ if (mBuffer)
+ {
+ if (mBuffer->useVBOs() && !mBuffer->isLocked())
+ { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
+ mBuffer->getVertexStrider(mVerticesp, 0, count);
+ mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
+ mBuffer->getColorStrider(mColorsp, 0, count);
+ }
+
+ mBuffer->flush();
+ mBuffer->setBuffer(immediate_mask);
+
+ if (mMode == LLRender::QUADS && sGLCoreProfile)
+ {
+ mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
+ mQuadCycle = 1;
+ }
+ else
+ {
+ mBuffer->drawArrays(mMode, 0, count);
+ }
+ }
+ else
+ {
+ // mBuffer is present in main thread and not present in an image thread
+ LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;
+ }
- if (mMode == LLRender::QUADS && sGLCoreProfile)
- {
- mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
- mQuadCycle = 1;
- }
- else
- {
- mBuffer->drawArrays(mMode, 0, count);
- }
mVerticesp[0] = mVerticesp[count];
mTexcoordsp[0] = mTexcoordsp[count];
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index e2489876e4..9c36c230fb 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -354,7 +354,9 @@ public:
LLRender();
~LLRender();
- void init() ;
+ void init(bool needs_vertex_buffer);
+ void initVertexBuffer();
+ void resetVertexBuffer();
void shutdown();
// Refreshes renderer state to the cached values
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 0408010513..fffc15efc3 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -133,7 +133,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
mUsage = usage;
mUseDepth = depth;
- if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
+ if (sUseFBO || use_fbo)
{
if (depth)
{
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index c100c182dd..c64f46f38a 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -665,7 +665,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (file == NULL)
{
- LL_SHADER_LOADING_WARNS() << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
+ LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
return 0;
}
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 6338cab96a..be3e6ddff0 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1055,7 +1055,7 @@ void LLVertexBuffer::releaseIndices()
bool LLVertexBuffer::createGLBuffer(U32 size)
{
- if (mGLBuffer)
+ if (mGLBuffer || mMappedData)
{
destroyGLBuffer();
}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index baf8407fc6..3b3fe44984 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -265,7 +265,6 @@ public:
bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
- bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index c6a3ada777..d413fab270 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -762,17 +762,13 @@ void LLFloater::closeFloater(bool app_quitting)
for(handle_set_iter_t dependent_it = mDependents.begin();
dependent_it != mDependents.end(); )
{
-
LLFloater* floaterp = dependent_it->get();
- if (floaterp)
- {
- ++dependent_it;
- floaterp->closeFloater(app_quitting);
- }
- else
- {
- mDependents.erase(dependent_it++);
- }
+ dependent_it = mDependents.erase(dependent_it);
+ if (floaterp)
+ {
+ floaterp->mDependeeHandle = LLHandle<LLFloater>();
+ floaterp->closeFloater(app_quitting);
+ }
}
cleanupHandles();
@@ -1443,7 +1439,7 @@ void LLFloater::cleanupHandles()
LLFloater* floaterp = dependent_it->get();
if (!floaterp)
{
- mDependents.erase(dependent_it++);
+ dependent_it = mDependents.erase(dependent_it);
}
else
{
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index aac28e04b9..77938edf27 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -395,7 +395,6 @@ void LLLayoutStack::updateLayout()
space_to_distribute += panelp ? ll_round((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0;
S32 remaining_space = space_to_distribute;
- F32 fraction_distributed = 0.f;
if (space_to_distribute > 0 && total_visible_fraction > 0.f)
{ // give space proportionally to visible auto resize panels
BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
@@ -404,7 +403,6 @@ void LLLayoutStack::updateLayout()
{
F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction);
S32 delta = ll_round((F32)space_to_distribute * fraction_to_distribute);
- fraction_distributed += fraction_to_distribute;
panelp->mTargetDim += delta;
remaining_space -= delta;
}
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 8f00d1274e..4264028338 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3960,8 +3960,8 @@ void LLTearOffMenu::draw()
{
// animate towards target height
reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
- mMenu->needsArrange();
}
+ mMenu->needsArrange();
LLFloater::draw();
}
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 5cfa8ea973..3e5978eb59 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -100,7 +100,10 @@ void LLModalDialog::onOpen(const LLSD& key)
if (!sModalStack.empty())
{
LLModalDialog* front = sModalStack.front();
- front->setVisible(FALSE);
+ if (front != this)
+ {
+ front->setVisible(FALSE);
+ }
}
// This is a modal dialog. It sucks up all mouse and keyboard operations.
@@ -108,7 +111,14 @@ void LLModalDialog::onOpen(const LLSD& key)
LLUI::getInstance()->addPopup(this);
setFocus(TRUE);
- sModalStack.push_front( this );
+ std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
+ if (iter != sModalStack.end())
+ {
+ // if already present, we want to move it to front.
+ sModalStack.erase(iter);
+ }
+
+ sModalStack.push_front(this);
}
}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 11b0eb9f80..65c7b420ce 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1388,6 +1388,84 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
return found;
}
+U32 LLScrollListCtrl::searchItems(const std::string& substring, bool case_sensitive, bool focus)
+{
+ return searchItems(utf8str_to_wstring(substring), case_sensitive, focus);
+}
+
+U32 LLScrollListCtrl::searchItems(const LLWString& substring, bool case_sensitive, bool focus)
+{
+ U32 found = 0;
+
+ LLWString substring_trimmed(substring);
+ S32 len = substring_trimmed.size();
+
+ if (0 == len)
+ {
+ // at the moment search for empty element is not supported
+ return 0;
+ }
+ else
+ {
+ deselectAllItems(TRUE);
+ if (!case_sensitive)
+ {
+ // do comparisons in lower case
+ LLWStringUtil::toLower(substring_trimmed);
+ }
+
+ for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ {
+ LLScrollListItem* item = *iter;
+ // Only select enabled items with matching names
+ if (!item->getEnabled())
+ {
+ continue;
+ }
+ LLScrollListCell* cellp = item->getColumn(getSearchColumn());
+ if (!cellp)
+ {
+ continue;
+ }
+ LLWString item_label = utf8str_to_wstring(cellp->getValue().asString());
+ if (!case_sensitive)
+ {
+ LLWStringUtil::toLower(item_label);
+ }
+ // remove extraneous whitespace from searchable label
+ LLWStringUtil::trim(item_label);
+
+ size_t found_iter = item_label.find(substring_trimmed);
+
+ if (found_iter != std::string::npos)
+ {
+ // find offset of matching text
+ cellp->highlightText(found_iter, substring_trimmed.size());
+ selectItem(item, -1, FALSE);
+
+ found++;
+
+ if (!mAllowMultipleSelection)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if (focus && found != 0)
+ {
+ mNeedsScroll = true;
+ }
+
+ if (mCommitOnSelectionChange)
+ {
+ commitIfChanged();
+ }
+
+ return found;
+}
+
const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const
{
LLScrollListItem* item;
@@ -1912,6 +1990,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id));
+ registrar.add("Url.ReportAbuse", boost::bind(&LLScrollListCtrl::reportAbuse, id, is_group));
registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1975,6 +2054,15 @@ void LLScrollListCtrl::removeFriend(std::string id)
LLUrlAction::removeFriend(slurl);
}
+void LLScrollListCtrl::reportAbuse(std::string id, bool is_group)
+{
+ if (!is_group)
+ {
+ std::string slurl = "secondlife:///app/agent/" + id + "/about";
+ LLUrlAction::reportAbuse(slurl);
+ }
+}
+
void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
{
// open the resident's details or the group details
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 08134bbfc8..77d10fdec7 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -267,6 +267,14 @@ public:
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
+ // If multi select is on, select all element that include substring,
+ // otherwise select first match only.
+ // If focus is true will scroll to selection.
+ // Returns number of results.
+ // Note: at the moment search happens in one go and is expensive
+ U32 searchItems(const std::string& substring, bool case_sensitive = false, bool focus = true);
+ U32 searchItems(const LLWString& substring, bool case_sensitive = false, bool focus = true);
+
// DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue().
// "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
// has an associated, unique UUID, and only one of which can be selected at a time.
@@ -325,6 +333,7 @@ public:
// support right-click context menus for avatar/group lists
enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP };
void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; }
+ ContextMenuType getContextMenuType() { return mContextMenuType; }
// Overridden from LLView
/*virtual*/ void draw();
@@ -460,6 +469,7 @@ private:
static void sendIM(std::string id);
static void addFriend(std::string id);
static void removeFriend(std::string id);
+ static void reportAbuse(std::string id, bool is_group);
static void showNameDetails(std::string id, bool is_group);
static void copyNameToClipboard(std::string id, bool is_group);
static void copySLURLToClipboard(std::string id, bool is_group);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c4a529e4ad..7e4aaa53bf 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2049,6 +2049,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
+ registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));
registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 26702b2412..1a10d2fd1e 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -196,6 +196,7 @@ public:
const LLUUID& getSourceID() const { return mSourceID; }
const LLTextSegmentPtr getPreviousSegment() const;
+ const LLTextSegmentPtr getLastSegment() const;
void getSelectedSegments(segment_vec_t& segments) const;
void setShowContextMenu(bool show) { mShowContextMenu = show; }
diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp
index 538508b856..78049319bc 100644
--- a/indra/llui/lltextutil.cpp
+++ b/indra/llui/lltextutil.cpp
@@ -76,22 +76,6 @@ void LLTextUtil::textboxSetGreyedVal(LLTextBox *txtbox, const LLStyle::Params& n
txtbox->appendText(text.substr(greyed_begin + greyed_len), false, normal_style);
}
-const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str)
-{
- static const std::string PHONE_SEPARATOR = LLUI::getInstance()->mSettingGroups["config"]->getString("AvalinePhoneSeparator");
- static const S32 PHONE_PART_LEN = 2;
-
- static std::string formatted_phone_str;
- formatted_phone_str = phone_str;
- S32 separator_pos = (S32)(formatted_phone_str.size()) - PHONE_PART_LEN;
- for (; separator_pos >= PHONE_PART_LEN; separator_pos -= PHONE_PART_LEN)
- {
- formatted_phone_str.insert(separator_pos, PHONE_SEPARATOR);
- }
-
- return formatted_phone_str;
-}
-
bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted)
{
if (match == 0 || text_base == 0)
diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h
index a9c143e445..1adc3516f7 100644
--- a/indra/llui/lltextutil.h
+++ b/indra/llui/lltextutil.h
@@ -59,18 +59,6 @@ namespace LLTextUtil
const std::string& greyed);
/**
- * Formats passed phone number to be more human readable.
- *
- * It just divides the number on parts by two digits from right to left. The first left part
- * can have 2 or 3 digits, i.e. +44-33-33-44-55-66 or 12-34-56-78-90. Separator is set in
- * application settings (AvalinePhoneSeparator)
- *
- * @param[in] phone_str string with original phone number
- * @return reference to string with formatted phone number
- */
- const std::string& formatPhoneNumber(const std::string& phone_str);
-
- /**
* Adds icon before url if need.
*
* @param[in] match an object with results of matching
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 84ea770a8d..8216046174 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -222,6 +222,15 @@ void LLUrlAction::removeFriend(std::string url)
}
}
+void LLUrlAction::reportAbuse(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/reportAbuse");
+ }
+}
+
void LLUrlAction::blockObject(std::string url)
{
std::string object_id = getObjectId(url);
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index 2d2a8dfef1..c2c576254d 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -82,6 +82,7 @@ public:
static void sendIM(std::string url);
static void addFriend(std::string url);
static void removeFriend(std::string url);
+ static void reportAbuse(std::string url);
static void blockObject(std::string url);
static void unblockObject(std::string url);
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 70eb99c86c..55befaef51 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -197,4 +197,10 @@ if (SDL_FOUND)
endif (SDL_FOUND)
target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
+
+if (DARWIN)
+ include(CMakeFindFrameworks)
+ find_library(CARBON_LIBRARY Carbon)
+ target_link_libraries(llwindow ${CARBON_LIBRARY})
+endif (DARWIN)
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index 5404ac50e5..e65cc7563e 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -148,6 +148,22 @@ void LLKeyboard::addKeyName(KEY key, const std::string& name)
sNamesToKeys[nameuc] = key;
}
+void LLKeyboard::resetKeyDownAndHandle()
+{
+ MASK mask = currentMask(FALSE);
+ for (S32 i = 0; i < KEY_COUNT; i++)
+ {
+ if (mKeyLevel[i])
+ {
+ mKeyDown[i] = FALSE;
+ mKeyLevel[i] = FALSE;
+ mKeyUp[i] = TRUE;
+ mCurTranslatedKey = (KEY)i;
+ mCallbacks->handleTranslatedKeyUp(i, mask);
+ }
+ }
+}
+
// BUG this has to be called when an OS dialog is shown, otherwise modifier key state
// is wrong because the keyup event is never received by the main window. JC
void LLKeyboard::resetKeys()
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index 36bd8bcbed..fb1ae10f50 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -58,7 +58,8 @@ public:
LLKeyboard();
virtual ~LLKeyboard();
- void resetKeys();
+ void resetKeyDownAndHandle();
+ void resetKeys();
F32 getCurKeyElapsedTime() { return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; }
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index fd20f2ad15..049226db65 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -495,14 +495,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
// e.g. OS Window for upload something or Input Window...
// mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit)
mModifiers = [theEvent modifierFlags];
+ unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
+ bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch);
- bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, [[theEvent characters] characterAtIndex:0]);
- unichar ch;
if (acceptsText &&
!mMarkedTextAllowed &&
!(mModifiers & (NSControlKeyMask | NSCommandKeyMask)) && // commands don't invoke InputWindow
![(LLAppDelegate*)[NSApp delegate] romanScript] &&
- (ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]) > ' ' &&
+ ch > ' ' &&
ch != NSDeleteCharacter &&
(ch < 0xF700 || ch > 0xF8FF)) // 0xF700-0xF8FF: reserved for function keys on the keyboard(from NSEvent.h)
{
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index f895c17643..5ec9b017cf 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -100,13 +100,13 @@ const unsigned short *copyFromPBoard()
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
NSCursor *cursor =
[[[NSCursor alloc]
initWithImage:
[[[NSImage alloc] initWithContentsOfFile:
- [NSString stringWithFormat:@"%s", fullpath]
+ [NSString stringWithUTF8String:fullpath]
]autorelease]
hotSpot:NSMakePoint(hotspotX, hotspotY)
]retain];
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index bc4f07941b..c29131d60b 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -621,8 +621,6 @@ void LLWindowMacOSX::getMouseDeltas(float* delta)
BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync)
{
- BOOL glNeedsInit = FALSE;
-
mFullscreen = fullscreen;
if (mWindow == NULL)
@@ -637,9 +635,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync);
mContext = getCGLContextObj(mGLView);
- // Since we just created the context, it needs to be set up.
- glNeedsInit = TRUE;
-
gGLManager.mVRAM = getVramSize(mGLView);
}
@@ -1666,7 +1661,7 @@ void LLWindowMacOSX::hideCursor()
void LLWindowMacOSX::showCursor()
{
- if(mCursorHidden)
+ if(mCursorHidden || !isCGCursorVisible())
{
// LL_INFOS() << "showCursor: showing" << LL_ENDL;
mCursorHidden = FALSE;
@@ -1721,9 +1716,7 @@ void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
{
if(mWindow != NULL)
{
- CFStringRef string = NULL;
-
- string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
+ CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
}
}
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 4c3aeb4695..c487877caf 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -874,21 +874,20 @@ void LLWindowWin32::close()
// Restore gamma to the system values.
restoreGamma();
- if (mhDC)
- {
- if (!ReleaseDC(mWindowHandle, mhDC))
- {
- LL_WARNS("Window") << "Release of ghDC failed" << LL_ENDL;
- }
- mhDC = NULL;
- }
-
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
mWindowThread->post([=]()
{
if (IsWindow(mWindowHandle))
{
+ if (mhDC)
+ {
+ if (!ReleaseDC(mWindowHandle, mhDC))
+ {
+ LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL;
+ }
+ }
+
// Make sure we don't leave a blank toolbar button.
ShowWindow(mWindowHandle, SW_HIDE);
@@ -914,6 +913,7 @@ void LLWindowWin32::close()
// Even though the above lambda might not yet have run, we've already
// bound mWindowHandle into it by value, which should suffice for the
// operations we're asking. That's the last time WE should touch it.
+ mhDC = NULL;
mWindowHandle = NULL;
mWindowThread->close();
}
@@ -1506,12 +1506,10 @@ const S32 max_format = (S32)num_formats - 1;
{
wglDeleteContext (mhRC); // Release The Rendering Context
mhRC = 0; // Zero The Rendering Context
-
}
- ReleaseDC (mWindowHandle, mhDC); // Release The Device Context
- mhDC = 0; // Zero The Device Context
}
+ // will release and recreate mhDC, mWindowHandle
recreateWindow(window_rect, dw_ex_style, dw_style);
RECT rect;
@@ -1661,7 +1659,8 @@ const S32 max_format = (S32)num_formats - 1;
void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style)
{
- auto oldHandle = mWindowHandle;
+ auto oldWindowHandle = mWindowHandle;
+ auto oldDCHandle = mhDC;
// zero out mWindowHandle and mhDC before destroying window so window
// thread falls back to peekmessage
@@ -1673,7 +1672,8 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
auto window_work =
[this,
self=mWindowThread,
- oldHandle,
+ oldWindowHandle,
+ oldDCHandle,
// bind CreateWindowEx() parameters by value instead of
// back-referencing LLWindowWin32 members
windowClassName=mWindowClassName,
@@ -1689,11 +1689,20 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
self->mWindowHandle = 0;
self->mhDC = 0;
- // important to call DestroyWindow() from the window thread
- if (oldHandle && !destroy_window_handler(oldHandle))
+ if (oldWindowHandle)
{
- LL_WARNS("Window") << "Failed to properly close window before recreating it!"
- << LL_ENDL;
+ if (oldDCHandle && !ReleaseDC(oldWindowHandle, oldDCHandle))
+ {
+ LL_WARNS("Window") << "Failed to ReleaseDC" << LL_ENDL;
+ }
+
+ // important to call DestroyWindow() from the window thread
+ if (!destroy_window_handler(oldWindowHandle))
+ {
+
+ LL_WARNS("Window") << "Failed to properly close window before recreating it!"
+ << LL_ENDL;
+ }
}
auto handle = CreateWindowEx(dw_ex_style,
@@ -1731,7 +1740,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
};
// But how we pass window_work to the window thread depends on whether we
// already have a window handle.
- if (! oldHandle)
+ if (!oldWindowHandle)
{
// Pass window_work using the WorkQueue: without an existing window
// handle, the window thread can't call GetMessage().
@@ -1744,7 +1753,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
// PostMessage(oldHandle) because oldHandle won't be destroyed until
// the window thread has retrieved and executed window_work.
LL_DEBUGS("Window") << "posting window_work to message queue" << LL_ENDL;
- mWindowThread->Post(oldHandle, window_work);
+ mWindowThread->Post(oldWindowHandle, window_work);
}
auto future = promise.get_future();
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index ea70e21414..43d3a32e64 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -34,6 +34,7 @@
#include "llplugininstance.h"
#include "llpluginmessage.h"
#include "llpluginmessageclasses.h"
+#include "llstring.h"
#include "volume_catcher.h"
#include "media_plugin_base.h"
@@ -55,7 +56,7 @@ private:
bool init();
void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height);
- void onCustomSchemeURLCallback(std::string url);
+ void onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect);
void onConsoleMessageCallback(std::string message, std::string source, int line);
void onStatusMessageCallback(std::string value);
void onTitleChangeCallback(std::string title);
@@ -299,11 +300,18 @@ void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target)
////////////////////////////////////////////////////////////////////////////////
//
-void MediaPluginCEF::onCustomSchemeURLCallback(std::string url)
+void MediaPluginCEF::onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
- message.setValue("uri", url);
- message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to
+ message.setValue("uri", url);
+
+ // indicate if this interaction was from a user click (okay on a SLAPP) or
+ // via a navigation (e.g. a data URL - see SL-18151) (not okay on a SLAPP)
+ const std::string nav_type = user_gesture ? "clicked" : "navigated";
+
+ message.setValue("nav_type", nav_type);
+ message.setValueBoolean("is_redirect", is_redirect);
+
sendMessage(message);
}
@@ -592,7 +600,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
// event callbacks from Dullahan
mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
- mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
+ mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
@@ -616,9 +624,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
// dir as the executable that loaded it (SLPlugin.exe). The code in
// Dullahan that tried to figure out the location automatically uses
// the location of the exe which isn't helpful so we tell it explicitly.
- char cur_dir_str[MAX_PATH];
- GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
- settings.host_process_path = std::string(cur_dir_str);
+ std::vector<wchar_t> buffer(MAX_PATH + 1);
+ GetCurrentDirectoryW(MAX_PATH, &buffer[0]);
+ settings.host_process_path = ll_convert_wide_to_string(&buffer[0]);
#endif
settings.accept_language_list = mHostLanguage;
diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
index 1afe25e9a1..89144922cc 100644
--- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
+++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
@@ -73,6 +73,7 @@ private:
static void display(void* data, void* id);
/*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */;
+ void setDurationDirty();
static void eventCallbacks(const libvlc_event_t* event, void* ptr);
@@ -93,8 +94,8 @@ private:
bool mIsLooping;
- float mCurTime;
- float mDuration;
+ F64 mCurTime;
+ F64 mDuration;
EStatus mVlcStatus;
};
@@ -214,6 +215,19 @@ void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom)
}
////////////////////////////////////////////////////////////////////////////////
+// *virtual*
+void MediaPluginLibVLC::setDurationDirty()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
+
+ message.setValueReal("current_time", mCurTime);
+ message.setValueReal("duration", mDuration);
+ message.setValueReal("current_rate", 1.0f);
+
+ sendMessage(message);
+}
+
+////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
{
@@ -233,6 +247,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f;
parent->mVlcStatus = STATUS_PLAYING;
parent->setVolumeVLC();
+ parent->setDurationDirty();
break;
case libvlc_MediaPlayerPaused:
@@ -245,6 +260,8 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerEndReached:
parent->mVlcStatus = STATUS_DONE;
+ parent->mCurTime = parent->mDuration;
+ parent->setDurationDirty();
break;
case libvlc_MediaPlayerEncounteredError:
@@ -253,6 +270,11 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerTimeChanged:
parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f;
+ if (parent->mVlcStatus == STATUS_DONE && libvlc_media_player_is_playing(parent->mLibVLCMediaPlayer))
+ {
+ parent->mVlcStatus = STATUS_PLAYING;
+ }
+ parent->setDurationDirty();
break;
case libvlc_MediaPlayerPositionChanged:
@@ -260,6 +282,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
case libvlc_MediaPlayerLengthChanged:
parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f;
+ parent->setDurationDirty();
break;
case libvlc_MediaPlayerTitleChanged:
@@ -562,7 +585,24 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
mTextureWidth = texture_width;
mTextureHeight = texture_height;
+ libvlc_time_t time = 1000.0 * mCurTime;
+
playMedia();
+
+ if (mLibVLCMediaPlayer)
+ {
+ libvlc_media_player_set_time(mLibVLCMediaPlayer, time);
+ time = libvlc_media_player_get_time(mLibVLCMediaPlayer);
+ if (time < 0)
+ {
+ // -1 if there is no media
+ mCurTime = 0;
+ }
+ else
+ {
+ mCurTime = (F64)time / 1000.0;
+ }
+ }
};
};
@@ -594,6 +634,13 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
{
if (mLibVLCMediaPlayer)
{
+ if (mVlcStatus == STATUS_DONE && !libvlc_media_player_is_playing(mLibVLCMediaPlayer))
+ {
+ // stop or vlc will ignore 'play', it will just
+ // make an MediaPlayerEndReached event even if
+ // seek was used
+ libvlc_media_player_stop(mLibVLCMediaPlayer);
+ }
libvlc_media_player_play(mLibVLCMediaPlayer);
}
}
@@ -606,15 +653,32 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
}
else if (message_name == "seek")
{
- if (mDuration > 0)
- {
- F64 normalized_offset = message_in.getValueReal("time") / mDuration;
- libvlc_media_player_set_position(mLibVLCMediaPlayer, normalized_offset);
- }
+ if (mLibVLCMediaPlayer)
+ {
+ libvlc_time_t time = 1000.0 * message_in.getValueReal("time");
+ libvlc_media_player_set_time(mLibVLCMediaPlayer, time);
+ time = libvlc_media_player_get_time(mLibVLCMediaPlayer);
+ if (time < 0)
+ {
+ // -1 if there is no media
+ mCurTime = 0;
+ }
+ else
+ {
+ mCurTime = (F64)time / 1000.0;
+ }
+
+ if (!libvlc_media_player_is_playing(mLibVLCMediaPlayer))
+ {
+ // if paused, won't trigger update, update now
+ setDurationDirty();
+ }
+ }
}
else if (message_name == "set_loop")
{
- mIsLooping = true;
+ bool loop = message_in.getValueBoolean("loop");
+ mIsLooping = loop;
}
else if (message_name == "set_volume")
{
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index b22e754ac6..5dbe61b99e 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.4
+6.6.5
diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml
index 55babc88bc..8d5349550f 100644
--- a/indra/newview/app_settings/key_bindings.xml
+++ b/indra/newview/app_settings/key_bindings.xml
@@ -85,7 +85,6 @@
<binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
- <binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
<binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
</third_person>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 16d8cd9f06..6861153d43 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -544,17 +544,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AvalinePhoneSeparator</key>
- <map>
- <key>Comment</key>
- <string>Separator of phone parts to have Avaline numbers human readable in Voice Control Panel</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>-</string>
- </map>
<key>AvatarAxisDeadZone0</key>
<map>
<key>Comment</key>
@@ -1371,7 +1360,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>20.0</real>
+ <real>40.0</real>
</map>
<key>DiskCacheDirName</key>
<map>
@@ -4758,7 +4747,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
+ <string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>GuidebookURL</key>
<map>
@@ -5806,6 +5795,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DiskCacheVersion</key>
+ <map>
+ <key>Comment</key>
+ <string>Version number of disk cache</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>LocalFileSystemBrowsingEnabled</key>
<map>
<key>Comment</key>
@@ -6808,6 +6808,9 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
+ <!-- *HACK: On first run, set this to 0 for new users,
+ otherwise the default is 1 to maintain consistent experience
+ for existing users. Hardcoded in llnetmap.cpp -->
<integer>1</integer>
</map>
<key>MiniMapScale</key>
@@ -6821,6 +6824,17 @@
<key>Value</key>
<real>128.0</real>
</map>
+ <key>MiniMapShowPropertyLines</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to show parcel borders on the MiniMap.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
<key>MouseSensitivity</key>
<map>
<key>Comment</key>
@@ -7099,13 +7113,13 @@
<key>NonvisibleObjectsInMemoryTime</key>
<map>
<key>Comment</key>
- <string>Number of frames non-visible objects stay in memory before being removed. 0 means never to remove.</string>
+ <string>Number of frames non-visible objects stay in memory before being removed. 0 means max.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>300</integer>
+ <integer>64</integer>
</map>
<key>NoPreload</key>
<map>
@@ -11022,7 +11036,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>1024</integer>
+ <integer>2048</integer>
</map>
<key>SceneLoadLowMemoryBound</key>
<map>
@@ -15737,6 +15751,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>AllowSelectAvatar</key>
+ <map>
+ <key>Comment</key>
+ <string>Allows user to select and move avatars, move is viewer sided, does not propagate to server, also supresses avatar position updates while avatars are selected</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>WebProfileFloaterRect</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 02d83925ea..b26194f278 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -202,7 +202,7 @@ VARYING vec2 vary_texcoord2;
uniform float env_intensity;
uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+#ifdef HAS_ALPHA_MASK
uniform float minimum_alpha;
#endif
@@ -227,11 +227,12 @@ void main()
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
diffcol.rgb *= vertex_color.rgb;
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-
- // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
- float bias = 0.001953125; // 1/512, or half an 8-bit quantization
- if (diffcol.a < minimum_alpha-bias)
+#ifdef HAS_ALPHA_MASK
+#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND
+ if (diffcol.a*vertex_color.a < minimum_alpha)
+#else
+ if (diffcol.a < minimum_alpha)
+#endif
{
discard;
}
diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml
index 2241a12545..6cfc0b0be2 100644
--- a/indra/newview/character/avatar_skeleton.xml
+++ b/indra/newview/character/avatar_skeleton.xml
@@ -2,15 +2,15 @@
<bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/>
- <bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine1" connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine2" connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
<collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
- <bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine3" connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine4" connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/>
<collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/>
@@ -23,58 +23,58 @@
<bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
- <bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceRoot" connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEyeAltRight" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeAltLeft" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadLeft" connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadRight" connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowOuterLeft" connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowCenterLeft" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowInnerLeft" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowOuterRight" connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowCenterRight" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowInnerRight" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidUpperLeft" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidLowerLeft" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidUpperRight" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidLowerRight" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEar1Left" connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEar2Left" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEar1Right" connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEar2Right" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseLeft" connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseCenter" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseRight" connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekLowerLeft" connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekUpperLeft" connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekLowerRight" connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekUpperRight" connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceJaw" connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceChin" connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTeethLower" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceLipLowerLeft" connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipLowerRight" connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipLowerCenter" connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTongueBase" connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceTongueTip" connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceJawShaper" connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadCenter" connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseBase" connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTeethUpper" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceLipUpperLeft" connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipUpperRight" connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipCornerLeft" connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipCornerRight" connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipUpperCenter" connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyecornerInnerLeft" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyecornerInnerRight" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseBridge" connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -86,29 +86,29 @@
<collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/>
- <bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandMiddle1Left" connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle2Left" connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle3Left" connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandIndex1Left" connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex2Left" connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex3Left" connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandRing1Left" connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing2Left" connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing3Left" connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandPinky1Left" connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky2Left" connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky3Left" connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandThumb1Left" connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb2Left" connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb3Left" connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -123,49 +123,49 @@
<collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/>
- <bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandMiddle1Right" connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle2Right" connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle3Right" connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandIndex1Right" connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex2Right" connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex3Right" connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandRing1Right" connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing2Right" connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing3Right" connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandPinky1Right" connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky2Right" connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky3Right" connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandThumb1Right" connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb2Right" connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb3Right" connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWingsRoot" connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing1Left" connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing2Left" connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing3Left" connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing4Left" connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing4FanLeft" connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing1Right" connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing2Right" connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing3Right" connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing4Right" connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing4FanRight" connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -200,30 +200,30 @@
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mTail1" connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail2" connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail3" connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail4" connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail5" connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail6" connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
- <bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mGroin" connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHindLimbsRoot" connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb1Left" connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb2Left" connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb3Left" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb4Left" connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHindLimb1Right" connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb2Right" connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb3Right" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb4Right" connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae
new file mode 100644
index 0000000000..085b2c7309
--- /dev/null
+++ b/indra/newview/cube.dae
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+ <asset>
+ <contributor>
+ modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26
+ </contributor>
+ <created>2018-10-25T16:29:03Z</created>
+ <modified>2022-02-18T00:00:00Z</modified>
+ <unit meter="1.000000"/>
+ <up_axis>Y_UP</up_axis>
+ </asset>
+
+ <library_materials>
+ <material id="Blue" name="Blue">
+ <instance_effect url="#effect_Blue"/>
+ </material>
+ </library_materials>
+
+
+ <library_effects>
+ <effect id="effect_Blue">
+ <profile_COMMON>
+ <technique sid="common">
+ <phong>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <color>0.137255 0.403922 0.870588 1</color>
+ </diffuse>
+ <specular>
+ <color>0.5 0.5 0.5 1</color>
+ </specular>
+ <shininess>
+ <float>16</float>
+ </shininess>
+ <transparent opaque="A_ONE">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ <index_of_refraction>
+ <float>1</float>
+ </index_of_refraction>
+ </phong>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ </library_effects>
+
+
+ <library_geometries>
+ <geometry id="F1" name="default_physics_shape">
+ <mesh>
+
+ <source id="cube-vertex-positions">
+ <float_array id="ID2-array" count="72">-0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 </float_array>
+ <technique_common>
+ <accessor source="#ID2-array" count="24" stride="3">
+ <param name="X" type="float"/>
+ <param name="Y" type="float"/>
+ <param name="Z" type="float"/>
+ </accessor>
+ </technique_common>
+ </source>
+
+ <vertices id="cube-vertices">
+ <input semantic="POSITION" source="#cube-vertex-positions"/>
+ </vertices>
+
+ <triangles count="12" material="geometryElement5">
+ <input semantic="VERTEX" offset="0" source="#cube-vertices"/>
+ <p>0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23 </p>
+ </triangles>
+
+ </mesh>
+ </geometry>
+ </library_geometries>
+ <library_visual_scenes>
+
+
+ <visual_scene id="reportScene">
+ <!-- No Spaces allowed in Name -->
+ <node id="F1" name="Face1">
+ <instance_geometry url="#F1">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="geometryElement5" target="#Blue"/>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ </node>
+ </visual_scene>
+ </library_visual_scenes>
+
+
+ <scene>
+ <instance_visual_scene url="#reportScene"/>
+ </scene>
+
+
+</COLLADA>
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 7513908cb4..60e26274cb 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -351,11 +351,29 @@ DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp"
DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage"
ClearErrors
+INSTALL_FILES_START:
+
Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer
# This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
%%INSTALL_FILES%%
+IfErrors 0 INSTALL_FILES_DONE
+ StrCmp $SKIP_DIALOGS "true" INSTALL_FILES_DONE
+ MessageBox MB_ABORTRETRYIGNORE $(ErrorSecondLifeInstallRetry) IDABORT INSTALL_FILES_CANCEL IDRETRY INSTALL_FILES_START
+ # MB_ABORTRETRYIGNORE does not accept IDIGNORE
+ Goto INSTALL_FILES_DONE
+
+INSTALL_FILES_CANCEL:
+ # We are quiting, cleanup.
+ # Silence warnings from RemoveProgFilesOnInst.
+ StrCpy $SKIP_DIALOGS "true"
+ Call RemoveProgFilesOnInst
+ MessageBox MB_OK $(ErrorSecondLifeInstallSupport)
+ Quit
+
+INSTALL_FILES_DONE:
+
# Pass the installer's language to the client to use as a default
StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)"
@@ -622,7 +640,9 @@ Function RemoveProgFilesOnInst
Push $0
StrCpy $0 0
-PREINSTALLREMOVE:
+ClearErrors
+
+PREINSTALL_REMOVE:
# Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575
Delete "$INSTDIR\$INSTEXE"
@@ -642,17 +662,17 @@ RMDir /r "$INSTDIR\llplugin"
IntOp $0 $0 + 1
-IfErrors 0 PREINSTALLDONE
- IntCmp $0 1 PREINSTALLREMOVE #try again once
- StrCmp $SKIP_DIALOGS "true" PREINSTALLDONE
- MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALLFAIL IDRETRY PREINSTALLREMOVE
+IfErrors 0 PREINSTALL_DONE
+ IntCmp $0 1 PREINSTALL_REMOVE #try again once
+ StrCmp $SKIP_DIALOGS "true" PREINSTALL_DONE
+ MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALL_FAIL IDRETRY PREINSTALL_REMOVE
# MB_ABORTRETRYIGNORE does not accept IDIGNORE
- Goto PREINSTALLDONE
+ Goto PREINSTALL_DONE
-PREINSTALLFAIL:
+PREINSTALL_FAIL:
Quit
-PREINSTALLDONE:
+PREINSTALL_DONE:
# We are no longer including release notes with the viewer, so remove them.
Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk"
diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index 648ddbfb85..73f23086be 100644
--- a/indra/newview/installers/windows/lang_da.nsi
+++ b/indra/newview/installers/windows/lang_da.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 188c30197a..7cc70e4c76 100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
@@ -73,6 +73,10 @@ LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Second Life kann nicht entfer
; CheckNetworkConnection
LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..."
+; error during installation
+LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life konnte nicht korrekt installiert werden, einige Dateien wurden eventuell nicht korrekt von der Installationroutine kopiert."
+LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Bitte laden Sie den Viewer erneut von https://secondlife.com/support/downloads/ und versuchen Sie die Installation erneut. Sollte das Problem weiterhin bestehen, dann kontaktieren Sie unseren Support unter https://support.secondlife.com."
+
; ask to remove user's data files
LangString RemoveDataFilesMB ${LANG_GERMAN} "Möchten Sie alle anderen zu Second Life gehörigen Dateien ebenfalls ENTFERNEN?$\n$\nWir empfehlen, die Einstellungen und Cache-Dateien zu behalten, wenn Sie andere Versionen von Second Life installiert haben oder eine Deinstallation durchführen, um Second Life auf eine neuere Version zu aktualisieren."
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 0639d51e10..2eaf97d023 100644
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index ee30651a38..364cc9f67e 100755
--- a/indra/newview/installers/windows/lang_es.nsi
+++ b/indra/newview/installers/windows/lang_es.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 7cd90ec314..2f34c0c87a 100755
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index 194062da9a..51214d3a9c 100755
--- a/indra/newview/installers/windows/lang_it.nsi
+++ b/indra/newview/installers/windows/lang_it.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index a54005ba14..296703d1a3 100755
--- a/indra/newview/installers/windows/lang_ja.nsi
+++ b/indra/newview/installers/windows/lang_ja.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 355d806866..299645bbb7 100644
--- a/indra/newview/installers/windows/lang_pl.nsi
+++ b/indra/newview/installers/windows/lang_pl.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index 97f5d2b44a..542c8654b5 100755
--- a/indra/newview/installers/windows/lang_pt-br.nsi
+++ b/indra/newview/installers/windows/lang_pt-br.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index 65a9f4846d..4e53a4957d 100755
--- a/indra/newview/installers/windows/lang_ru.nsi
+++ b/indra/newview/installers/windows/lang_ru.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index e71886cc66..bae5029ad1 100755
--- a/indra/newview/installers/windows/lang_tr.nsi
+++ b/indra/newview/installers/windows/lang_tr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index f5f0c6cbdf..7922d9df52 100755
--- a/indra/newview/installers/windows/lang_zh.nsi
+++ b/indra/newview/installers/windows/lang_zh.nsi
Binary files differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3b3eadada7..5250369813 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -719,6 +719,9 @@ void LLAgent::moveYaw(F32 mag, bool reset_view)
U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
if ((getControlFlags() & mask) == mask)
{
+ // Rotation into both directions should cancel out
+ // But keep sending controls to simulator,
+ // it's needed for script based controls
gAgentCamera.setYawKey(0);
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 60797c87d9..4f3e0b08e4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -557,7 +557,7 @@ static void settings_to_globals()
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
- LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
+ LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
#if LL_DARWIN
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
@@ -1450,6 +1450,8 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
+ // if one of our coroutines threw an uncaught exception, rethrow it now
+ LLCoros::instance().rethrow();
}
if (!LLApp::isExiting())
@@ -2490,10 +2492,24 @@ bool LLAppViewer::initConfiguration()
//Load settings files list
std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
LLXMLNodePtr root;
- BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
+ BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
if (!success)
{
- LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ if (gDirUtilp->fileExists(settings_file_list))
+ {
+ LL_ERRS() << "Cannot load default configuration file settings_files.xml. "
+ << "Please reinstall viewer from https://secondlife.com/support/downloads/ "
+ << "and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_ERRS() << "Default configuration file settings_files.xml not found. "
+ << "Please reinstall viewer from https://secondlife.com/support/downloads/ "
+ << "and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
}
mSettingsLocationList = new SettingsFiles();
@@ -3291,9 +3307,18 @@ LLSD LLAppViewer::getViewerInfo() const
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined";
if(LLVoiceClient::getInstance()->voiceEnabled())
{
- LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ const std::string build_version = version.mBuildVersion;
std::ostringstream version_string;
- version_string << version.serverType << " " << version.serverVersion << std::endl;
+ if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(),
+ version.serverVersion.begin()))
+ { // Normal case: Show type and build version.
+ version_string << version.serverType << " " << build_version << std::endl;
+ }
+ else
+ { // Mismatch: Show both versions.
+ version_string << version.serverVersion << "/" << build_version << std::endl;
+ }
info["VOICE_VERSION"] = version_string.str();
}
else
@@ -3486,7 +3511,7 @@ void LLAppViewer::cleanupSavedSettings()
}
}
- gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale );
+ gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting());
// Some things are cached in LLAgent.
if (gAgent.isInitialized())
@@ -4257,6 +4282,15 @@ U32 LLAppViewer::getTextureCacheVersion()
}
//static
+U32 LLAppViewer::getDiskCacheVersion()
+{
+ // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes.
+ const U32 DISK_CACHE_VERSION = 1;
+
+ return DISK_CACHE_VERSION ;
+}
+
+//static
U32 LLAppViewer::getObjectCacheVersion()
{
// Viewer object cache version, change if object update
@@ -4276,21 +4310,30 @@ bool LLAppViewer::initCache()
// initialize the new disk cache using saved settings
const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");
+ const U32 MB = 1024 * 1024;
+ const uintmax_t MIN_CACHE_SIZE = 256 * MB;
+ const uintmax_t MAX_CACHE_SIZE = 9984ll * MB;
+ const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB;
+ const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
+ const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
+ const F64 texture_cache_percent = 100.0 - disk_cache_percent;
+
// note that the maximum size of this cache is defined as a percentage of the
// total cache size - the 'CacheSize' pref - for all caches.
- const unsigned int cache_total_size_mb = gSavedSettings.getU32("CacheSize");
- const double disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
- const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100;
- const uintmax_t disk_cache_bytes = disk_cache_mb * 1024 * 1024;
+ const uintmax_t disk_cache_size = uintmax_t(cache_total_size * disk_cache_percent / 100);
const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
bool texture_cache_mismatch = false;
+ bool remove_vfs_files = false;
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
texture_cache_mismatch = true;
if(!read_only)
{
gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
+
+ //texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed
+ remove_vfs_files = true;
}
}
@@ -4332,11 +4375,23 @@ bool LLAppViewer::initCache()
}
const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
- LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info);
+ LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info);
if (!read_only)
{
- if (mPurgeCache)
+ if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion())
+ {
+ LLDiskCache::getInstance()->clearCache();
+ remove_vfs_files = true;
+ gSavedSettings.setS32("DiskCacheVersion", LLAppViewer::getDiskCacheVersion());
+ }
+
+ if (remove_vfs_files)
+ {
+ LLDiskCache::getInstance()->removeOldVFSFiles();
+ }
+
+ if (mPurgeCache)
{
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
@@ -4355,22 +4410,14 @@ bool LLAppViewer::initCache()
LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
// Init the texture cache
- // Allocate 80% of the cache size for textures
- const S32 MB = 1024 * 1024;
- const S64 MIN_CACHE_SIZE = 256 * MB;
- const S64 MAX_CACHE_SIZE = 9984ll * MB;
+ // Allocate the remaining percent which is not allocated to the disk cache
+ const S64 texture_cache_size = S64(cache_total_size * texture_cache_percent / 100);
- S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
- cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
-
- S64 texture_cache_size = cache_size;
-
- S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
- texture_cache_size -= extra;
+ LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
- return true;
+ return true;
}
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
@@ -5056,8 +5103,7 @@ void LLAppViewer::idle()
audio_update_wind(false);
// this line actually commits the changes we've made to source positions, etc.
- const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
- gAudiop->idle(max_audio_decode_time);
+ gAudiop->idle();
}
}
@@ -5418,7 +5464,7 @@ void LLAppViewer::disconnectViewer()
gFloaterView->restoreAll();
}
- if (LLSelectMgr::getInstance())
+ if (LLSelectMgr::instanceExists())
{
LLSelectMgr::getInstance()->deselectAll();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 7ab21f35cd..f28a90c703 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -130,6 +130,7 @@ public:
static U32 getTextureCacheVersion() ;
static U32 getObjectCacheVersion() ;
+ static U32 getDiskCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
@@ -153,16 +154,16 @@ public:
void removeMarkerFiles();
void removeDumpDir();
- // LLAppViewer testing helpers.
- // *NOTE: These will potentially crash the viewer. Only for debugging.
- virtual void forceErrorLLError();
- virtual void forceErrorBreakpoint();
- virtual void forceErrorBadMemoryAccess();
- virtual void forceErrorInfiniteLoop();
- virtual void forceErrorSoftwareException();
- virtual void forceErrorDriverCrash();
- virtual void forceErrorCoroutineCrash();
- virtual void forceErrorThreadCrash();
+ // LLAppViewer testing helpers.
+ // *NOTE: These will potentially crash the viewer. Only for debugging.
+ virtual void forceErrorLLError();
+ virtual void forceErrorBreakpoint();
+ virtual void forceErrorBadMemoryAccess();
+ virtual void forceErrorInfiniteLoop();
+ virtual void forceErrorSoftwareException();
+ virtual void forceErrorDriverCrash();
+ virtual void forceErrorCoroutineCrash();
+ virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index b0715a3afd..c0990d9d11 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -241,21 +241,6 @@ void LLAvatarList::setDirty(bool val /*= true*/, bool force_refresh /*= false*/)
}
}
-void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name)
-{
- LL_DEBUGS("Avaline") << "Adding avaline item into the list: " << item_name << "|" << item_id << ", session: " << session_id << LL_ENDL;
- LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false);
- item->setAvatarId(item_id, session_id, true, false);
- item->setName(item_name);
- item->showLastInteractionTime(mShowLastInteractionTime);
- item->showSpeakingIndicator(mShowSpeakingIndicator);
- item->setOnline(false);
-
- addItem(item, item_id);
- mIDs.push_back(item_id);
- sort();
-}
-
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
@@ -296,18 +281,10 @@ void LLAvatarList::refresh()
{
// *NOTE: If you change the UI to show a different string,
// be sure to change the filter code below.
- if (LLRecentPeople::instance().isAvalineCaller(buddy_id))
- {
- const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id);
- addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString());
- }
- else
- {
- std::string display_name = getAvatarName(av_name);
- addNewItem(buddy_id,
- display_name.empty() ? waiting_str : display_name,
- LLAvatarTracker::instance().isBuddyOnline(buddy_id));
- }
+ std::string display_name = getAvatarName(av_name);
+ addNewItem(buddy_id,
+ display_name.empty() ? waiting_str : display_name,
+ LLAvatarTracker::instance().isBuddyOnline(buddy_id));
modified = true;
nadded++;
@@ -463,7 +440,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- if ( mContextMenu && !isAvalineItemSelected())
+ if ( mContextMenu)
{
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
@@ -523,21 +500,6 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
-bool LLAvatarList::isAvalineItemSelected()
-{
- std::vector<LLPanel*> selected_items;
- getSelectedItems(selected_items);
- std::vector<LLPanel*>::iterator it = selected_items.begin();
-
- for(; it != selected_items.end(); ++it)
- {
- if (dynamic_cast<LLAvalineListItem*>(*it))
- return true;
- }
-
- return false;
-}
-
void LLAvatarList::setVisible(BOOL visible)
{
if ( visible == FALSE && mContextMenu )
@@ -626,63 +588,3 @@ bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_
}
return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2);
}
-
-/************************************************************************/
-/* class LLAvalineListItem */
-/************************************************************************/
-LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarListItem(false)
-, mIsHideNumber(hide_number)
-{
- // should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called.
- buildFromFile( "panel_avatar_list_item.xml");
-}
-
-BOOL LLAvalineListItem::postBuild()
-{
- BOOL rv = LLAvatarListItem::postBuild();
-
- if (rv)
- {
- setOnline(true);
- showLastInteractionTime(false);
- setShowProfileBtn(false);
- setShowInfoBtn(false);
- mAvatarIcon->setValue("Avaline_Icon");
- mAvatarIcon->setToolTip(std::string(""));
- }
- return rv;
-}
-
-// to work correctly this method should be called AFTER setAvatarId for avaline callers with hidden phone number
-void LLAvalineListItem::setName(const std::string& name)
-{
- if (mIsHideNumber)
- {
- static U32 order = 0;
- typedef std::map<LLUUID, U32> avaline_callers_nums_t;
- static avaline_callers_nums_t mAvalineCallersNums;
-
- llassert(getAvatarId() != LLUUID::null);
-
- const LLUUID &uuid = getAvatarId();
-
- if (mAvalineCallersNums.find(uuid) == mAvalineCallersNums.end())
- {
- mAvalineCallersNums[uuid] = ++order;
- LL_DEBUGS("Avaline") << "Set name for new avaline caller: " << uuid << ", order: " << order << LL_ENDL;
- }
- LLStringUtil::format_map_t args;
- args["[ORDER]"] = llformat("%u", mAvalineCallersNums[uuid]);
- std::string hidden_name = LLTrans::getString("AvalineCaller", args);
-
- LL_DEBUGS("Avaline") << "Avaline caller: " << uuid << ", name: " << hidden_name << LL_ENDL;
- LLAvatarListItem::setAvatarName(hidden_name);
- LLAvatarListItem::setAvatarToolTip(hidden_name);
- }
- else
- {
- const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
- LLAvatarListItem::setAvatarName(formatted_phone);
- LLAvatarListItem::setAvatarToolTip(formatted_phone);
- }
-}
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 1a672c279b..48b0e70454 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -98,7 +98,6 @@ public:
virtual S32 notifyParent(const LLSD& info);
- void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name);
void handleDisplayNamesOptionChanged();
void setShowCompleteName(bool show) { mShowCompleteName = show;};
@@ -118,8 +117,6 @@ protected:
private:
- bool isAvalineItemSelected();
-
bool mIgnoreOnlineStatus;
bool mShowLastInteractionTime;
bool mDirty;
@@ -189,27 +186,4 @@ protected:
virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
};
-/**
- * Represents Avaline caller in Avatar list in Voice Control Panel and group chats.
- */
-class LLAvalineListItem : public LLAvatarListItem
-{
-public:
-
- /**
- * Constructor
- *
- * @param hide_number - flag indicating if number should be hidden.
- * In this case It will be shown as "Avaline Caller 1", "Avaline Caller 1", etc.
- */
- LLAvalineListItem(bool hide_number = true);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setName(const std::string& name);
-
-private:
- bool mIsHideNumber;
-};
-
#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index fe94cd27b6..275f17b02a 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -320,9 +320,16 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
// make sure we won't re-report, coro will update timer with correct time later
regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS);
- std::string coroname =
- LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
- boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
+ try
+ {
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
+ }
}
}
@@ -343,10 +350,17 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
// make sure we won't re-request, coro will update timer with correct time later
regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
- // First send a request to get the latest data
- std::string coroname =
- LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
- boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
+ try
+ {
+ // First send a request to get the latest data
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
+ }
}
}
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index bdd516e1de..7ff24f64ac 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -48,6 +48,7 @@
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
#include "llfloatersidepanelcontainer.h"
#include "llmutelist.h"
#include "llstylemap.h"
@@ -118,6 +119,7 @@ public:
mSourceType(CHAT_SOURCE_UNKNOWN),
mFrom(),
mSessionID(),
+ mCreationTime(time_corrected()),
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
@@ -403,6 +405,48 @@ public:
{
LLAvatarActions::pay(getAvatarId());
}
+ else if (level == "report_abuse")
+ {
+ std::string time_string;
+ if (mTime > 0) // have frame time
+ {
+ time_t current_time = time_corrected();
+ time_t message_time = current_time - LLFrameTimer::getElapsedSeconds() + mTime;
+
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] ["
+ + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32)message_time;
+ LLStringUtil::format(time_string, substitution);
+ }
+ else
+ {
+ // From history. This might be empty or not full.
+ // See LLChatLogParser::parse
+ time_string = getChild<LLTextBox>("time_box")->getValue().asString();
+
+ // Just add current date if not full.
+ // Should be fine since both times are supposed to be stl
+ if (!time_string.empty() && time_string.size() < 7)
+ {
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] " + time_string;
+
+ LLSD substitution;
+ // To avoid adding today's date to yesterday's timestamp,
+ // use creation time instead of current time
+ substitution["datetime"] = (S32)mCreationTime;
+ LLStringUtil::format(time_string, substitution);
+ }
+ }
+ LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText);
+ }
else if(level == "block_unblock")
{
LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat);
@@ -477,6 +521,10 @@ public:
{
return canModerate(userdata);
}
+ else if (level == "report_abuse")
+ {
+ return gAgentID != mAvatarID;
+ }
else if (level == "can_ban_member")
{
return canBanGroupMember(getAvatarId());
@@ -634,6 +682,12 @@ public:
mSessionID = chat.mSessionID;
mSourceType = chat.mSourceType;
+ // To be able to report a message, we need a copy of it's text
+ // and it's easier to store text directly than trying to get
+ // it from a lltextsegment or chat's mEditor
+ mText = chat.mText;
+ mTime = chat.mTime;
+
//*TODO overly defensive thing, source type should be maintained out there
if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()))
{
@@ -983,6 +1037,9 @@ protected:
EChatSourceType mSourceType;
std::string mFrom;
LLUUID mSessionID;
+ std::string mText;
+ F64 mTime; // IM's frame time
+ time_t mCreationTime; // Views's time
S32 mMinUserNameWidth;
const LLFontGL* mUserNameFont;
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 80d810d159..036ff17074 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -290,9 +290,14 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
pickerp->getCurG (),
pickerp->getCurB (),
subject->mColor.mV[VALPHA] ); // keep current alpha
- subject->mColor = updatedColor;
- subject->setControlValue(updatedColor.getValue());
- pickerp->setRevertOnCancel(TRUE);
+
+ bool color_changed = subject->mColor != updatedColor;
+ if (color_changed)
+ {
+ subject->mColor = updatedColor;
+ subject->setControlValue(updatedColor.getValue());
+ }
+
if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback)
{
subject->mOnCancelCallback( subject, LLSD());
@@ -306,6 +311,13 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
// just commit change
subject->onCommit ();
}
+
+ if (pick_op == COLOR_CANCEL || pick_op == COLOR_SELECT)
+ {
+ // both select and cancel close LLFloaterColorPicker
+ // but COLOR_CHANGE does not
+ subject->setFocus(TRUE);
+ }
}
}
}
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 86e23e7c83..97b16a5e93 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -391,7 +391,8 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
"can_invite_to_group" == command_name ||
"can_share" == command_name ||
"can_block" == command_name ||
- "can_pay" == command_name)
+ "can_pay" == command_name ||
+ "report_abuse" == command_name)
{
return is_p2p;
}
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a685639427..9ec4fb085b 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -182,6 +182,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
items.push_back(std::string("map"));
items.push_back(std::string("share"));
items.push_back(std::string("pay"));
+ items.push_back(std::string("report_abuse"));
items.push_back(std::string("block_unblock"));
items.push_back(std::string("MuteText"));
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 7d4961c598..4d9ef99319 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -80,9 +80,14 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
{
}
+void LLDoNotDisturbNotificationStorage::reset()
+{
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+}
+
void LLDoNotDisturbNotificationStorage::initialize()
{
- setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+ reset();
getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index c6f0bf1ab5..237d58b4de 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -61,6 +61,7 @@ public:
void loadNotifications();
void updateNotifications();
void removeNotification(const char * name, const LLUUID& id);
+ void reset();
protected:
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 2372ea01a6..2a0f4c93ac 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -133,6 +133,7 @@ public:
inline LLFace* getFace(const S32 i) const;
inline S32 getNumFaces() const;
face_list_t& getFaces() { return mFaces; }
+ const face_list_t& getFaces() const { return mFaces; }
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index e674707c01..6c1abb24c9 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -58,6 +58,7 @@ static BOOL deferred_render = FALSE;
// minimum alpha before discarding a fragment
static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255
+
// minimum alpha before discarding a fragment when rendering impostors
static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f;
@@ -147,6 +148,10 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
+ for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
+ {
+ prepare_alpha_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], false, false); // note: bindDeferredShader will get called during render loop for materials
+ }
// first pass, render rigged objects only and render to depth buffer
forwardRender(true);
@@ -215,9 +220,15 @@ void LLDrawPoolAlpha::render(S32 pass)
{
minimum_alpha = MINIMUM_IMPOSTOR_ALPHA;
}
+
prepare_forward_shader(fullbright_shader, minimum_alpha);
prepare_forward_shader(simple_shader, minimum_alpha);
+ for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
+ {
+ prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha);
+ }
+
//first pass -- rigged only and drawn to depth buffer
forwardRender(true);
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 63e7887d81..361a7666fa 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,7 +125,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
}
- if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
+ if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -212,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
+ bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
if (use_fbo)
{
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index b76dc6a961..1300cf3658 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -2641,7 +2641,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F3
if (!water.isUndefined())
{
- environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time));
+ environment->injectWaterSettings(water, experience_id, LLSettingsBase::Seconds(transition_time));
}
if (updateenvironment)
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 1605e4133d..9bb3bac104 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -504,20 +504,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
is.close();
}
- //get time domain
- LLSD::Real cur_total_time = 0.0;
-
- for (U32 i = 0; i < cur_data.size(); ++i)
- {
- cur_total_time += cur_data[i]["Total"]["Time"].asReal();
- }
-
- LLSD::Real base_total_time = 0.0;
- for (U32 i = 0; i < base_data.size(); ++i)
- {
- base_total_time += base_data[i]["Total"]["Time"].asReal();
- }
-
//allocate raw scratch space
LLPointer<LLImageRaw> scratch = new LLImageRaw(1024, 512, 3);
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index a02bb56489..70e8437190 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -471,7 +471,25 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
}
// check if we are dragging an existing item from the favorites bar
- if (item && mDragItemId == item->getUUID())
+ bool existing_drop = false;
+ if (item && mDragItemId == item->getUUID())
+ {
+ // There is a chance of mDragItemId being obsolete
+ // ex: can happen if something interrupts viewer, which
+ // results in viewer not geting a 'mouse up' signal
+ for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i)
+ {
+ LLViewerInventoryItem* currItem = *i;
+
+ if (currItem->getUUID() == mDragItemId)
+ {
+ existing_drop = true;
+ break;
+ }
+ }
+ }
+
+ if (existing_drop)
{
*accept = ACCEPT_YES_SINGLE;
@@ -500,6 +518,7 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
if (mItems.empty())
{
setLandingTab(NULL);
+ mLastTab = NULL;
}
handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
}
@@ -515,6 +534,12 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
{
+ if (mItems.empty())
+ {
+ // Isn't supposed to be empty
+ return;
+ }
+
// Identify the button hovered and the side to drop
LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
bool insert_before = true;
@@ -787,6 +812,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
if(mItems.empty())
{
mBarLabel->setVisible(TRUE);
+ mLastTab = NULL;
}
else
{
@@ -833,6 +859,10 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
dynamic_cast<LLFavoriteLandmarkButton*> (*cur_it);
if (button)
{
+ if (mLastTab == button)
+ {
+ mLastTab = NULL;
+ }
removeChild(button);
delete button;
}
@@ -870,6 +900,17 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
mLastTab = last_new_button;
}
+ if (!mLastTab && mItems.size() > 0)
+ {
+ // mMoreTextBox was removed, so LLFavoriteLandmarkButtons
+ // should be the only ones in the list
+ LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (childs->back());
+ if (button)
+ {
+ mLastTab = button;
+ }
+ }
+
mFirstDropDownItem = j;
// Chevron button
if (mFirstDropDownItem < mItems.size())
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index ffbb0bbee9..c075f7e8bd 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -114,6 +114,11 @@ BOOL LLFloater360Capture::postBuild()
// by default each time vs restoring the last value
mQualityRadioGroup->setSelectedIndex(0);
+ return true;
+}
+
+void LLFloater360Capture::onOpen(const LLSD& key)
+{
// Construct a URL pointing to the first page to load. Although
// we do not use this page for anything (after some significant
// design changes), we retain the code to load the start page
@@ -154,8 +159,6 @@ BOOL LLFloater360Capture::postBuild()
// We do an initial capture when the floater is opened, albeit at a 'preview'
// quality level (really low resolution, but really fast)
onCapture360ImagesBtn();
-
- return true;
}
// called when the user choose a quality level using
diff --git a/indra/newview/llfloater360capture.h b/indra/newview/llfloater360capture.h
index 6da7ee074a..8f765c0b1b 100644
--- a/indra/newview/llfloater360capture.h
+++ b/indra/newview/llfloater360capture.h
@@ -47,6 +47,7 @@ class LLFloater360Capture:
~LLFloater360Capture();
BOOL postBuild() override;
+ void onOpen(const LLSD& key) override;
void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
void changeInterestListMode(bool send_everything);
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index ab95bc06b8..0186c4aebe 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -105,6 +105,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
mNumResultsReturned(0),
mNearMeListComplete(FALSE),
mCloseOnSelect(FALSE),
+ mExcludeAgentFromSearchResults(FALSE),
mContextConeOpacity (0.f),
mContextConeInAlpha(0.f),
mContextConeOutAlpha(0.f),
@@ -295,7 +296,7 @@ void LLFloaterAvatarPicker::populateNearMe()
for(U32 i=0; i<avatar_ids.size(); i++)
{
LLUUID& av = avatar_ids[i];
- if(av == gAgent.getID()) continue;
+ if(mExcludeAgentFromSearchResults && (av == gAgent.getID())) continue;
LLSD element;
element["id"] = av; // value
LLAvatarName av_name;
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index a3037ed651..ed3dc37043 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -294,7 +294,7 @@ BOOL LLFloaterBvhPreview::postBuild()
loaderp->serialize(dp);
dp.reset();
LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL;
- BOOL success = motionp && motionp->deserialize(dp, mMotionID);
+ BOOL success = motionp && motionp->deserialize(dp, mMotionID, false);
LL_INFOS("BVH") << "Done" << LL_ENDL;
delete []buffer;
@@ -1047,7 +1047,12 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT
mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
mDummyAvatar->mSpecialRenderMode = 1;
mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
- mDummyAvatar->hideSkirt();
+
+ // on idle overall apperance update will set skirt to visible, so either
+ // call early or account for mSpecialRenderMode in updateMeshVisibility
+ mDummyAvatar->updateOverallAppearance();
+ mDummyAvatar->hideHair();
+ mDummyAvatar->hideSkirt();
// stop extraneous animations
mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE );
@@ -1135,6 +1140,7 @@ BOOL LLPreviewAnimation::render()
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
avatarp->dirtyMesh();
+ gPipeline.enableLightsPreview();
avatarPoolp->renderAvatars(avatarp); // renders only one avatar
}
}
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 1a784223c2..ba91277c79 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -173,7 +173,6 @@ void LLFloaterColorPicker::showUI ()
openFloater(getKey());
setVisible ( TRUE );
setFocus ( TRUE );
- setRevertOnCancel(FALSE);
// HACK: if system color picker is required - close the SL one we made and use default system dialog
if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) )
@@ -185,15 +184,23 @@ void LLFloaterColorPicker::showUI ()
// code that will get switched in for default system color picker
if ( swatch )
{
+ // Todo: this needs to be threaded for viewer not to timeout
LLColor4 curCol = swatch->get ();
send_agent_pause();
- getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
+ bool commit = getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
send_agent_resume();
- setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
- setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
-
- LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE );
+ if (commit)
+ {
+ setOrigRgb(curCol[0], curCol[1], curCol[2]);
+ setCurRgb(curCol[0], curCol[1], curCol[2]);
+
+ LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_SELECT);
+ }
+ else
+ {
+ LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_CANCEL);
+ }
}
closeFloater();
@@ -391,10 +398,7 @@ void LLFloaterColorPicker::onClickCancel ( void* data )
if ( self )
{
- if(self->getRevertOnCancel())
- {
- self->cancelSelection ();
- }
+ self->cancelSelection();
self->closeFloater();
}
}
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 16974a872e..39dbc5b763 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -104,9 +104,6 @@ class LLFloaterColorPicker
void setMouseDownInSwatch (BOOL mouse_down_in_swatch);
BOOL getMouseDownInSwatch () { return mMouseDownInSwatch; }
- void setRevertOnCancel (BOOL revertOnCancel) { mRevertOnCancel = revertOnCancel; };
- BOOL getRevertOnCancel () { return mRevertOnCancel; }
-
BOOL isColorChanged ();
// called when text entries (RGB/HSL etc.) are changed by user
@@ -149,8 +146,6 @@ class LLFloaterColorPicker
BOOL mMouseDownInHueRegion;
BOOL mMouseDownInSwatch;
- BOOL mRevertOnCancel;
-
const S32 mRGBViewerImageLeft;
const S32 mRGBViewerImageTop;
const S32 mRGBViewerImageWidth;
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
index 6b1d9306fb..7def855d83 100644
--- a/indra/newview/llfloatercreatelandmark.cpp
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -46,19 +46,60 @@
typedef std::pair<LLUUID, std::string> folder_pair_t;
-class LLLandmarksInventoryObserver : public LLInventoryAddedObserver
+class LLLandmarksInventoryObserver : public LLInventoryObserver
{
public:
LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :
mFloater(create_landmark_floater)
{}
+ void changed(U32 mask) override
+ {
+ if (mFloater->getItem())
+ {
+ checkChanged(mask);
+ }
+ else
+ {
+ checkCreated(mask);
+ }
+ }
+
protected:
- /*virtual*/ void done()
+ void checkCreated(U32 mask)
{
+ if (gInventory.getAddedIDs().empty())
+ {
+ return;
+ }
+
+ if (!(mask & LLInventoryObserver::ADD) ||
+ !(mask & LLInventoryObserver::CREATE) ||
+ !(mask & LLInventoryObserver::UPDATE_CREATE))
+ {
+ return;
+ }
+
mFloater->setItem(gInventory.getAddedIDs());
}
+ void checkChanged(U32 mask)
+ {
+ if (gInventory.getChangedIDs().empty())
+ {
+ return;
+ }
+
+ if ((mask & LLInventoryObserver::LABEL) ||
+ (mask & LLInventoryObserver::INTERNAL) ||
+ (mask & LLInventoryObserver::REMOVE) ||
+ (mask & LLInventoryObserver::STRUCTURE) ||
+ (mask & LLInventoryObserver::REBUILD))
+ {
+ mFloater->updateItem(gInventory.getChangedIDs(), mask);
+ }
+ }
+
private:
LLFloaterCreateLandmark* mFloater;
};
@@ -85,6 +126,9 @@ BOOL LLFloaterCreateLandmark::postBuild()
getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this));
+ mLandmarkTitleEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); });
+ mNotesEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); });
+
mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
return TRUE;
@@ -204,6 +248,33 @@ void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)
}
}
+void LLFloaterCreateLandmark::onCommitTextChanges()
+{
+ if (mItem.isNull())
+ {
+ return;
+ }
+ std::string current_title_value = mLandmarkTitleEditor->getText();
+ std::string item_title_value = mItem->getName();
+ std::string current_notes_value = mNotesEditor->getText();
+ std::string item_notes_value = mItem->getDescription();
+
+ LLStringUtil::trim(current_title_value);
+ LLStringUtil::trim(current_notes_value);
+
+ if (!current_title_value.empty() &&
+ (item_title_value != current_title_value || item_notes_value != current_notes_value))
+ {
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
+ new_item->rename(current_title_value);
+ new_item->setDescription(current_notes_value);
+ LLPointer<LLInventoryCallback> cb;
+ LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0);
+ gInventory.accountForUpdate(up);
+ update_inventory_item(new_item, cb);
+ }
+}
+
void LLFloaterCreateLandmark::onCreateFolderClicked()
{
LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(),
@@ -278,6 +349,8 @@ void LLFloaterCreateLandmark::onSaveClicked()
new_item->updateParentOnServer(FALSE);
}
+ removeObserver();
+
gInventory.updateItem(new_item);
gInventory.notifyObservers();
@@ -286,6 +359,7 @@ void LLFloaterCreateLandmark::onSaveClicked()
void LLFloaterCreateLandmark::onCancelClicked()
{
+ removeObserver();
if (!mItem.isNull())
{
LLUUID item_id = mItem->getUUID();
@@ -314,10 +388,59 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
{
if(!getItem())
{
- removeObserver();
mItem = item;
+ mAssetID = mItem->getAssetUUID();
+ setVisibleAndFrontmost(true);
break;
}
}
}
}
+
+void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask)
+{
+ if (!getItem())
+ {
+ return;
+ }
+
+ LLUUID landmark_id = getItem()->getUUID();
+
+ for (uuid_set_t::const_iterator item_iter = items.begin();
+ item_iter != items.end();
+ ++item_iter)
+ {
+ const LLUUID& item_id = (*item_iter);
+ if (landmark_id == item_id)
+ {
+ if (getItem() != gInventory.getItem(item_id))
+ {
+ // item is obsolete or removed
+ closeFloater();
+ }
+
+ LLUUID folder_id = mFolderCombo->getValue().asUUID();
+ if (folder_id != mItem->getParentUUID())
+ {
+ // user moved landmark in inventory,
+ // assume that we are done all other changes should already be commited
+ closeFloater();
+ }
+
+ if ((mask & LLInventoryObserver::INTERNAL) && mAssetID != mItem->getAssetUUID())
+ {
+ closeFloater();
+ }
+
+ if (mask & LLInventoryObserver::LABEL)
+ {
+ mLandmarkTitleEditor->setText(mItem->getName());
+ }
+
+ if (mask & LLInventoryObserver::INTERNAL)
+ {
+ mNotesEditor->setText(mItem->getDescription());
+ }
+ }
+ }
+}
diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h
index 74ac5e651c..d84f5ae1fc 100644
--- a/indra/newview/llfloatercreatelandmark.h
+++ b/indra/newview/llfloatercreatelandmark.h
@@ -49,6 +49,7 @@ public:
void onOpen(const LLSD& key);
void setItem(const uuid_set_t& items);
+ void updateItem(const uuid_set_t& items, U32 mask);
LLInventoryItem* getItem() { return mItem; }
@@ -56,6 +57,7 @@ private:
void setLandmarkInfo(const LLUUID &folder_id);
void removeObserver();
void populateFoldersList(const LLUUID &folder_id = LLUUID::null);
+ void onCommitTextChanges();
void onCreateFolderClicked();
void onSaveClicked();
void onCancelClicked();
@@ -66,6 +68,7 @@ private:
LLLineEditor* mLandmarkTitleEditor;
LLTextEditor* mNotesEditor;
LLUUID mLandmarksID;
+ LLUUID mAssetID;
LLLandmarksInventoryObserver* mInventoryObserver;
LLPointer<LLInventoryItem> mItem;
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index 24673d5a7c..297ad24359 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -665,6 +665,7 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
if (ctrl_action == ACTION_SAVE)
{
doApplyUpdateInventory(dayclone);
+ clearDirtyFlag();
}
else if (ctrl_action == ACTION_SAVEAS)
{
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index fec218ca3b..aa9a2c164a 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -296,6 +296,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
if (ctrl_action == ACTION_SAVE)
{
doApplyUpdateInventory(setting_clone);
+ clearDirtyFlag();
}
else if (ctrl_action == ACTION_SAVEAS)
{
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
index 42c5e40761..a00fc4aa84 100644
--- a/indra/newview/llfloaterhoverheight.cpp
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -100,11 +100,14 @@ void LLFloaterHoverHeight::onClose(bool app_quitting)
// static
void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData)
{
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- F32 value = sldrCtrl->getValueF32();
- LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
- LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
- gAgentAvatarp->setHoverOffset(offset, false);
+ if (isAgentAvatarValid())
+ {
+ LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
+ F32 value = sldrCtrl->getValueF32();
+ LLVector3 offset(0.0, 0.0, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z));
+ LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
+ gAgentAvatarp->setHoverOffset(offset, false);
+ }
}
// Do send-to-the-server work when slider drag completes, or new
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 1525bb9952..703b5d0011 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -45,6 +45,7 @@
#include "llflashtimer.h"
#include "llfloateravatarpicker.h"
#include "llfloaterpreference.h"
+#include "llfloaterreporter.h"
#include "llimview.h"
#include "llnotificationsutil.h"
#include "lltoolbarview.h"
@@ -1242,6 +1243,18 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
{
LLAvatarActions::pay(userID);
}
+ else if ("report_abuse" == command)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(userID, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(userID, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(userID, "not avaliable");
+ }
+ }
else if ("block_unblock" == command)
{
LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat);
@@ -1507,7 +1520,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
}
// Handle all other options
- if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+ if (("can_invite" == item)
+ || ("can_chat_history" == item)
+ || ("can_share" == item)
+ || ("can_pay" == item)
+ || ("report_abuse" == item))
{
// Those menu items are enable only if a single avatar is selected
return is_single_select;
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index d78f80ad12..1a98ab9d76 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -3056,7 +3056,8 @@ BOOL LLPanelLandCovenant::postBuild()
{
mLastRegionID = LLUUID::null;
mNextUpdateTime = 0;
-
+ mTextEstateOwner = getChild<LLTextBox>("estate_owner_text");
+ mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend);
return TRUE;
}
@@ -3164,8 +3165,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name)
LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
if (self)
{
- LLTextBox* editor = self->getChild<LLTextBox>("estate_owner_text");
- if (editor) editor->setText(name);
+ self->mTextEstateOwner->setText(name);
}
}
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 5d9b411f04..684950d88b 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -413,6 +413,7 @@ protected:
private:
LLUUID mLastRegionID;
F64 mNextUpdateTime; //seconds since client start
+ LLTextBox* mTextEstateOwner;
};
#endif
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index fc2da772f3..fd1af7ccc0 100644..100755
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -51,7 +51,7 @@
// The minor cardinal direction labels are hidden if their height is more
// than this proportion of the map.
-const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f;
+const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f;
//
// Member functions
@@ -77,35 +77,44 @@ LLFloaterMap::~LLFloaterMap()
BOOL LLFloaterMap::postBuild()
{
- mMap = getChild<LLNetMap>("Net Map");
- if (gSavedSettings.getBOOL("DoubleClickTeleport"))
- {
- mMap->setToolTipMsg(getString("AltToolTipMsg"));
- }
- else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
- {
- mMap->setToolTipMsg(getString("ToolTipMsg"));
- }
- sendChildToBack(mMap);
-
- mTextBoxNorth = getChild<LLTextBox> ("floater_map_north");
- mTextBoxEast = getChild<LLTextBox> ("floater_map_east");
- mTextBoxWest = getChild<LLTextBox> ("floater_map_west");
- mTextBoxSouth = getChild<LLTextBox> ("floater_map_south");
- mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast");
- mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast");
- mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
- mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
-
- updateMinorDirections();
-
- // Get the drag handle all the way in back
- sendChildToBack(getDragHandle());
-
- // keep onscreen
- gFloaterView->adjustToFitScreen(this, FALSE);
-
- return TRUE;
+ mMap = getChild<LLNetMap>("Net Map");
+ mMap->setToolTipMsg(getString("ToolTipMsg"));
+ mMap->setParcelNameMsg(getString("ParcelNameMsg"));
+ mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg"));
+ mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg"));
+ mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg"));
+ mMap->setRegionNameMsg(getString("RegionNameMsg"));
+ mMap->setToolTipHintMsg(getString("ToolTipHintMsg"));
+ mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg"));
+ sendChildToBack(mMap);
+
+ mTextBoxNorth = getChild<LLTextBox>("floater_map_north");
+ mTextBoxEast = getChild<LLTextBox>("floater_map_east");
+ mTextBoxWest = getChild<LLTextBox>("floater_map_west");
+ mTextBoxSouth = getChild<LLTextBox>("floater_map_south");
+ mTextBoxSouthEast = getChild<LLTextBox>("floater_map_southeast");
+ mTextBoxNorthEast = getChild<LLTextBox>("floater_map_northeast");
+ mTextBoxSouthWest = getChild<LLTextBox>("floater_map_southwest");
+ mTextBoxNorthWest = getChild<LLTextBox>("floater_map_northwest");
+
+ mTextBoxNorth->reshapeToFitText();
+ mTextBoxEast->reshapeToFitText();
+ mTextBoxWest->reshapeToFitText();
+ mTextBoxSouth->reshapeToFitText();
+ mTextBoxSouthEast->reshapeToFitText();
+ mTextBoxNorthEast->reshapeToFitText();
+ mTextBoxSouthWest->reshapeToFitText();
+ mTextBoxNorthWest->reshapeToFitText();
+
+ updateMinorDirections();
+
+ // Get the drag handle all the way in back
+ sendChildToBack(getDragHandle());
+
+ // keep onscreen
+ gFloaterView->adjustToFitScreen(this, false);
+
+ return true;
}
BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -138,23 +147,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
-void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
+void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation)
{
- // Rotation is in radians.
- // Rotation of 0 means x = 1, y = 0 on the unit circle.
-
- F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2;
- F32 map_half_width = (F32)(getRect().getWidth() / 2) ;
- F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2);
- F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2);
- F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width );
-
- // Inset by a little to account for position display.
- radius -= 8.f;
-
- text_box->setOrigin(
- ll_round(map_half_width - text_half_width + radius * cos( rotation )),
- ll_round(map_half_height - text_half_height + radius * sin( rotation )) );
+ // Rotation is in radians.
+ // Rotation of 0 means x = 1, y = 0 on the unit circle.
+
+ F32 map_half_height = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2);
+ F32 map_half_width = (F32) (getRect().getWidth() / 2);
+ F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2);
+ F32 text_half_width = (F32) (text_box->getRect().getWidth() / 2);
+ F32 extra_padding = (F32) (mTextBoxNorth->getRect().getWidth() / 2);
+ F32 pos_half_height = map_half_height - text_half_height - extra_padding;
+ F32 pos_half_width = map_half_width - text_half_width - extra_padding;
+
+ F32 corner_angle = atan2(pos_half_height, pos_half_width);
+ F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI));
+ if (rotation < 0)
+ {
+ rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top;
+ }
+ F32 rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO));
+ bool at_left_right_edge = rotation_mirrored_into_top_right < corner_angle;
+
+ F32 part_x = cos(rotation);
+ F32 part_y = sin(rotation);
+ F32 y;
+ F32 x;
+ if (at_left_right_edge)
+ {
+ x = std::copysign(pos_half_width, part_x);
+ y = x * part_y / part_x;
+ }
+ else
+ {
+ y = std::copysign(pos_half_height, part_y);
+ x = y * part_x / part_y;
+ }
+
+ text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height));
}
void LLFloaterMap::updateMinorDirections()
@@ -218,32 +248,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
updateMinorDirections();
}
-void LLFloaterMap::handleZoom(const LLSD& userdata)
-{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- mMap->setScale(scale);
- }
-}
-
LLFloaterMap* LLFloaterMap::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map");
diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h
index ff2fb20535..929b1795aa 100644
--- a/indra/newview/llfloatermap.h
+++ b/indra/newview/llfloatermap.h
@@ -48,7 +48,6 @@ public:
/*virtual*/ void draw();
private:
- void handleZoom(const LLSD& userdata);
void setDirectionPos( LLTextBox* text_box, F32 rotation );
void updateMinorDirections();
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 524162ba51..e755e9924c 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -579,7 +579,25 @@ void LLFloaterMarketplaceListings::updateView()
// Update the top message or flip to the tabs and folders view
// *TODO : check those messages and create better appropriate ones in strings.xml
- if (mRootFolderId.notNull())
+ if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)
+ {
+ std::string reason = LLMarketplaceData::instance().getSLMConnectionfailureReason();
+ if (reason.empty())
+ {
+ text = LLTrans::getString("InventoryMarketplaceConnectionError");
+ }
+ else
+ {
+ LLSD args;
+ args["[REASON]"] = reason;
+ text = LLTrans::getString("InventoryMarketplaceConnectionErrorReason", args);
+ }
+
+ title = LLTrans::getString("InventoryOutboxErrorTitle");
+ tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+ LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL;
+ }
+ else if (mRootFolderId.notNull())
{
// "Marketplace listings is empty!" message strings
text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs);
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index 2afd889609..b34961e8a2 100644
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -157,6 +157,18 @@ void LLFloaterMediaSettings::apply()
}
////////////////////////////////////////////////////////////////////////////////
+void LLFloaterMediaSettings::onOpen(const LLSD& key)
+{
+ if (mPanelMediaSettingsGeneral)
+ {
+ // media is expensive, so only load it when nessesary.
+ // If we need to preload it, set volume to 0 and any pause
+ // if applicable, then unpause here
+ mPanelMediaSettingsGeneral->updateMediaPreview();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
void LLFloaterMediaSettings::onClose(bool app_quitting)
{
if(mPanelMediaSettingsGeneral)
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
index f93512eb3a..151e43e6b9 100644
--- a/indra/newview/llfloatermediasettings.h
+++ b/indra/newview/llfloatermediasettings.h
@@ -42,6 +42,7 @@ public:
~LLFloaterMediaSettings();
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
static LLFloaterMediaSettings* getInstance();
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 58fbdba315..66a245b779 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -467,22 +467,25 @@ void LLFloaterModelPreview::loadHighLodModel()
loadModel(3);
}
-void LLFloaterModelPreview::loadModel(S32 lod)
+void LLFloaterModelPreview::prepareToLoadModel(S32 lod)
{
mModelPreview->mLoading = true;
if (lod == LLModel::LOD_PHYSICS)
{
// loading physics from file
mModelPreview->mPhysicsSearchLOD = lod;
+ mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false;
}
-
+}
+void LLFloaterModelPreview::loadModel(S32 lod)
+{
+ prepareToLoadModel(lod);
(new LLMeshFilePicker(mModelPreview, lod))->getFile();
}
void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm)
{
- mModelPreview->mLoading = true;
-
+ prepareToLoadModel(lod);
mModelPreview->loadModel(file_name, lod, force_disable_slm);
}
@@ -507,6 +510,15 @@ void LLFloaterModelPreview::onClickCalculateBtn()
toggleCalculateButton(false);
mUploadBtn->setEnabled(false);
+
+ //disable "simplification" UI
+ LLPanel* simplification_panel = getChild<LLPanel>("physics simplification");
+ LLView* child = simplification_panel->getFirstChild();
+ while (child)
+ {
+ child->setEnabled(false);
+ child = simplification_panel->findNextSibling(child);
+ }
}
// Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function
@@ -1063,11 +1075,18 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
}
S32 file_mode = iface->getItemCount() - 1;
- if (which_mode < file_mode)
+ S32 cube_mode = file_mode - 1;
+ if (which_mode < cube_mode)
{
S32 which_lod = num_lods - which_mode;
sInstance->mModelPreview->setPhysicsFromLOD(which_lod);
}
+ else if (which_mode == cube_mode)
+ {
+ std::string path = gDirUtilp->getAppRODataDir();
+ gDirUtilp->append(path, "cube.dae");
+ sInstance->loadModel(LLModel::LOD_PHYSICS, path);
+ }
LLModelPreview *model_preview = sInstance->mModelPreview;
if (model_preview)
@@ -1662,15 +1681,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod)
{
if (lod == LLModel::LOD_PHYSICS)
- {
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("physics_lod_combo");
if (lod_combo)
{
- lod_combo->setCurrentByIndex(5);
+ lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1);
}
}
else
-{
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);
if (lod_combo)
{
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 1e147cd555..bda042186b 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -221,6 +221,7 @@ private:
void resetUploadOptions();
void clearLogTab();
+ void prepareToLoadModel(S32 lod);
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index 87973c2286..94261b2e4e 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -72,7 +72,7 @@ struct LLGiveMoneyInfo
mFloater(floater), mAmount(amount){}
};
-typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
+typedef std::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
///----------------------------------------------------------------------------
/// Class LLFloaterPay
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 26ea029cac..273810e8d4 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1199,7 +1199,6 @@ void LLFloaterPreference::refreshEnabledState()
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
bumpshiny &&
shaders &&
- gGLManager.mHasFramebufferObject &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);
@@ -1250,7 +1249,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
- gGLManager.mHasFramebufferObject &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);
@@ -1384,8 +1382,7 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
}
// disabled deferred
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
- !gGLManager.mHasFramebufferObject)
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"))
{
ctrl_shadows->setEnabled(FALSE);
ctrl_shadows->setValue(0);
@@ -2952,10 +2949,15 @@ void LLPanelPreferenceControls::cancel()
if (mConflictHandler[i].hasUnsavedChanges())
{
mConflictHandler[i].clear();
+ if (mEditingMode == i)
+ {
+ // cancel() can be called either when preferences floater closes
+ // or when child floater closes (like advanced graphical settings)
+ // in which case we need to clear and repopulate table
+ regenerateControls();
+ }
}
}
- pControlsTable->clearRows();
- pControlsTable->clearColumns();
}
void LLPanelPreferenceControls::saveSettings()
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 296e155d28..07d4dcae38 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -47,6 +47,7 @@
#include "llagent.h"
#include "llappviewer.h"
+#include "llavataractions.h"
#include "llavatarname.h"
#include "llfloateravatarpicker.h"
#include "llbutton.h"
@@ -1322,6 +1323,7 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data)
BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
{
+ static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024;
for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
{
std::string buffer;
@@ -1343,17 +1345,19 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
return FALSE;
}
- if (width > 512 || height > 512)
+ if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE)
{
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_SIZE_X"] = width;
args["TEXTURE_SIZE_Y"] = height;
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainSize", args);
return FALSE;
@@ -1826,7 +1830,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
setCtrlsEnabled(god || owner || manager);
getChildView("apply_btn")->setEnabled(FALSE);
-
+ getChildView("estate_owner")->setEnabled(TRUE);
getChildView("message_estate_btn")->setEnabled(god || owner || manager);
getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
@@ -1888,6 +1892,8 @@ BOOL LLPanelEstateInfo::postBuild()
getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE);
+ getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend);
+
return LLPanelRegionInfo::postBuild();
}
@@ -2134,6 +2140,7 @@ BOOL LLPanelEstateCovenant::postBuild()
{
mEstateNameText = getChild<LLTextBox>("estate_name_text");
mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
+ mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend);
mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
mEditor = getChild<LLViewerTextEditor>("covenant_editor");
LLButton* reset_button = getChild<LLButton>("reset_covenant");
@@ -3683,7 +3690,7 @@ void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::strin
if (!search_string.empty())
{
listCtrl->setSearchColumn(0); // name column
- listCtrl->selectItemByPrefix(search_string, FALSE);
+ listCtrl->searchItems(search_string, false, true);
}
else
{
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index b73755cf4e..2df4ca973d 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -54,6 +54,7 @@
#include "llbutton.h"
#include "llfloaterreg.h"
#include "lltexturectrl.h"
+#include "lltexteditor.h"
#include "llscrolllistctrl.h"
#include "lldispatcher.h"
#include "llviewerobject.h"
@@ -250,9 +251,6 @@ LLFloaterReporter::~LLFloaterReporter()
mPosition.setVec(0.0f, 0.0f, 0.0f);
- std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );
- mMCDList.clear();
-
delete mResourceDatap;
}
@@ -661,6 +659,23 @@ void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::strin
show(avatar_id, avatar_name);
}
+// static
+void LLFloaterReporter::showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description)
+{
+ show(avatar_id, avatar_name);
+
+ LLStringUtil::format_map_t args;
+ args["[MSG_TIME]"] = time;
+ args["[MSG_DESCRIPTION]"] = description;
+
+ LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
+ if (self)
+ {
+ std::string description = self->getString("chat_report_format", args);
+ self->getChild<LLUICtrl>("details_edit")->setValue(description);
+ }
+}
+
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
{
getChild<LLUICtrl>("object_name")->setValue(object_name);
@@ -1028,37 +1043,3 @@ void LLFloaterReporter::onClose(bool app_quitting)
mSnapshotTimer.stop();
gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);
}
-
-
-// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
-// if (self)
-// {
-// self->getChild<LLUICtrl>("details_edit")->setValue(description);
-
-// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer());
-// self->mMCDList.clear();
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
-
-// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
-// if (self)
-// {
-// LLTextEditor* text = self->getChild<LLTextEditor>("details_edit");
-// if (text)
-// {
-// text->insertText(description);
-// }
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index c678df7155..b6c70e866d 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -93,6 +93,7 @@ public:
static void showFromObject(const LLUUID& object_id, const LLUUID& experience_id = LLUUID::null);
static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);
+ static void showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description);
static void showFromExperience(const LLUUID& experience_id);
static void onClickSend (void *userdata);
@@ -101,8 +102,6 @@ public:
void onClickSelectAbuser ();
static void closePickTool (void *userdata);
static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status);
- static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
- static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);
@@ -114,10 +113,8 @@ private:
static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null);
void takeScreenshot(bool use_prev_screenshot = false);
- void sendReportViaCaps(std::string url);
void uploadImage();
bool validateReport();
- void setReporterID();
LLSD gatherReport();
void sendReportViaLegacy(const LLSD & report);
void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);
@@ -144,7 +141,6 @@ private:
BOOL mPicking;
LLVector3 mPosition;
BOOL mCopyrightWarningSeen;
- std::list<LLMeanCollisionData*> mMCDList;
std::string mDefaultSummary;
LLResourceData* mResourceDatap;
boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 2e1fbb09e0..bb3ed77772 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -57,10 +57,10 @@ public:
const size_t parts = tokens.size();
// get the (optional) category for the search
- std::string category;
+ std::string collection;
if (parts > 0)
{
- category = tokens[0].asString();
+ collection = tokens[0].asString();
}
// get the (optional) search string
@@ -72,7 +72,7 @@ public:
// create the LLSD arguments for the search floater
LLFloaterSearch::Params p;
- p.search.category = category;
+ p.search.collection = collection;
p.search.query = LLURI::unescape(search_text);
// open the search floater and perform the requested search
@@ -83,8 +83,9 @@ public:
LLSearchHandler gSearchHandler;
LLFloaterSearch::SearchQuery::SearchQuery()
-: category("category", ""),
- query("query")
+: category("category", ""),
+ collection("collection", ""),
+ query("query")
{}
LLFloaterSearch::LLFloaterSearch(const Params& key) :
@@ -93,16 +94,16 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) :
{
// declare a map that transforms a category name into
// the URL suffix that is used to search that category
- mCategoryPaths = LLSD::emptyMap();
- mCategoryPaths["all"] = "search";
- mCategoryPaths["people"] = "search/people";
- mCategoryPaths["places"] = "search/places";
- mCategoryPaths["events"] = "search/events";
- mCategoryPaths["groups"] = "search/groups";
- mCategoryPaths["wiki"] = "search/wiki";
- mCategoryPaths["land"] = "land";
- mCategoryPaths["destinations"] = "destinations";
- mCategoryPaths["classifieds"] = "classifieds";
+
+ mSearchType.insert("standard");
+ mSearchType.insert("land");
+ mSearchType.insert("classified");
+
+ mCollectionType.insert("events");
+ mCollectionType.insert("destinations");
+ mCollectionType.insert("places");
+ mCollectionType.insert("groups");
+ mCollectionType.insert("people");
}
BOOL LLFloaterSearch::postBuild()
@@ -157,31 +158,49 @@ void LLFloaterSearch::search(const SearchQuery &p)
// work out the subdir to use based on the requested category
LLSD subs;
- if (mCategoryPaths.has(p.category))
+ if (mSearchType.find(p.category) != mSearchType.end())
{
- subs["CATEGORY"] = mCategoryPaths[p.category].asString();
+ subs["TYPE"] = p.category;
}
else
{
- subs["CATEGORY"] = mCategoryPaths["all"].asString();
+ subs["TYPE"] = "standard";
}
// add the search query string
subs["QUERY"] = LLURI::escape(p.query);
+ subs["COLLECTION"] = "";
+ if (subs["TYPE"] == "standard")
+ {
+ if (mCollectionType.find(p.collection) != mCollectionType.end())
+ {
+ subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection);
+ }
+ else
+ {
+ std::string collection_args("");
+ for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it)
+ {
+ collection_args += "&collection_chosen=" + std::string(*it);
+ }
+ subs["COLLECTION"] = collection_args;
+ }
+ }
+
// add the user's preferred maturity (can be changed via prefs)
std::string maturity;
if (gAgent.prefersAdult())
{
- maturity = "42"; // PG,Mature,Adult
+ maturity = "gma"; // PG,Mature,Adult
}
else if (gAgent.prefersMature())
{
- maturity = "21"; // PG,Mature
+ maturity = "gm"; // PG,Mature
}
else
{
- maturity = "13"; // PG
+ maturity = "g"; // PG
}
subs["MATURITY"] = maturity;
diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h
index 35b268e1b2..cc77ce696f 100644
--- a/indra/newview/llfloatersearch.h
+++ b/indra/newview/llfloatersearch.h
@@ -49,6 +49,7 @@ public:
struct SearchQuery : public LLInitParam::Block<SearchQuery>
{
Optional<std::string> category;
+ Optional<std::string> collection;
Optional<std::string> query;
SearchQuery();
@@ -84,7 +85,8 @@ public:
private:
/*virtual*/ BOOL postBuild();
- LLSD mCategoryPaths;
+ std::set<std::string> mSearchType;
+ std::set<std::string> mCollectionType;
U8 mSearchGodLevel;
};
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 77a04bc5d7..b6acba6558 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -46,7 +46,6 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
-#include "llmediactrl.h"
#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llpanelcontents.h"
@@ -240,7 +239,6 @@ BOOL LLFloaterTools::postBuild()
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
mBtnGridOptions = getChild<LLButton>("Options...");
- mTitleMedia = getChild<LLMediaCtrl>("title_media");
mBtnLink = getChild<LLButton>("link_btn");
mBtnUnlink = getChild<LLButton>("unlink_btn");
@@ -329,7 +327,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCheckSnapToGrid(NULL),
mBtnGridOptions(NULL),
- mTitleMedia(NULL),
mComboGridMode(NULL),
mCheckStretchUniform(NULL),
mCheckStretchTexture(NULL),
@@ -369,8 +366,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mLandImpactsObserver(NULL),
mDirty(TRUE),
- mHasSelection(TRUE),
- mNeedMediaTitle(TRUE)
+ mHasSelection(TRUE)
{
gFloaterTools = this;
@@ -394,9 +390,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
- mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
@@ -553,7 +546,7 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
- refreshMedia();
+ mPanelFace->refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
@@ -580,9 +573,6 @@ void LLFloaterTools::draw()
mDirty = FALSE;
}
- // grab media name/title and update the UI widget
- updateMediaTitle();
-
// mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
LLFloater::draw();
}
@@ -906,8 +896,7 @@ void LLFloaterTools::onClose(bool app_quitting)
LLViewerJoystick::getInstance()->moveAvatar(false);
// destroy media source used to grab media title
- if( mTitleMedia )
- mTitleMedia->unloadMediaSource();
+ mPanelFace->unloadMedia();
// Different from handle_reset_view in that it doesn't actually
// move the camera if EditCameraMovement is not set.
@@ -1160,51 +1149,6 @@ void LLFloaterTools::onFocusReceived()
LLFloater::onFocusReceived();
}
-// Media stuff
-void LLFloaterTools::refreshMedia()
-{
- getMediaState();
-}
-
-bool LLFloaterTools::selectedMediaEditable()
-{
- U32 owner_mask_on;
- U32 owner_mask_off;
- U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,
- &owner_mask_on, &owner_mask_off );
- U32 group_mask_on;
- U32 group_mask_off;
- U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,
- &group_mask_on, &group_mask_off );
- U32 everyone_mask_on;
- U32 everyone_mask_off;
- S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,
- &everyone_mask_on, &everyone_mask_off );
-
- bool selected_Media_editable = false;
-
- // if perms we got back are valid
- if ( valid_owner_perms &&
- valid_group_perms &&
- valid_everyone_perms )
- {
-
- if ( ( owner_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) )
- {
- selected_Media_editable = true;
- }
- else
- // user is NOT allowed to press the RESET button
- {
- selected_Media_editable = false;
- };
- };
-
- return selected_Media_editable;
-}
-
void LLFloaterTools::updateLandImpacts()
{
LLParcel *parcel = mParcelSelection->getParcel();
@@ -1221,784 +1165,3 @@ void LLFloaterTools::updateLandImpacts()
}
}
-void LLFloaterTools::getMediaState()
-{
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- LLViewerObject* first_object = selected_objects->getFirstObject();
- LLTextBox* media_info = getChild<LLTextBox>("media_info");
-
- if( !(first_object
- && first_object->getPCode() == LL_PCODE_VOLUME
- &&first_object->permModify()
- ))
- {
- getChildView("add_media")->setEnabled(FALSE);
- media_info->clear();
- clearMediaSettings();
- return;
- }
-
- std::string url = first_object->getRegion()->getCapability("ObjectMedia");
- bool has_media_capability = (!url.empty());
-
- if(!has_media_capability)
- {
- getChildView("add_media")->setEnabled(FALSE);
- LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
- clearMediaSettings();
- return;
- }
-
- BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
- && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
- || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
- bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
-
- // Check modify permissions and whether any selected objects are in
- // the process of being fetched. If they are, then we're not editable
- if (editable)
- {
- LLObjectSelection::iterator iter = selected_objects->begin();
- LLObjectSelection::iterator end = selected_objects->end();
- for ( ; iter != end; ++iter)
- {
- LLSelectNode* node = *iter;
- LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
- if (NULL != object)
- {
- if (!object->permModify())
- {
- LL_INFOS("LLFloaterToolsMedia")
- << "Selection not editable due to lack of modify permissions on object id "
- << object->getID() << LL_ENDL;
-
- editable = false;
- break;
- }
- // XXX DISABLE this for now, because when the fetch finally
- // does come in, the state of this floater doesn't properly
- // update. Re-selecting fixes the problem, but there is
- // contention as to whether this is a sufficient solution.
-// if (object->isMediaDataBeingFetched())
-// {
-// LL_INFOS("LLFloaterToolsMedia")
-// << "Selection not editable due to media data being fetched for object id "
-// << object->getID() << LL_ENDL;
-//
-// editable = false;
-// break;
-// }
- }
- }
- }
-
- // Media settings
- bool bool_has_media = false;
- struct media_functor : public LLSelectedTEGetFunctor<bool>
- {
- bool get(LLViewerObject* object, S32 face)
- {
- LLTextureEntry *te = object->getTE(face);
- if (te)
- {
- return te->hasMedia();
- }
- return false;
- }
- } func;
-
-
- // check if all faces have media(or, all dont have media)
- LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
-
- const LLMediaEntry default_media_data;
-
- struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
- {
- functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- LLMediaEntry get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return *(object->getTE(face)->getMediaData());
- return mMediaEntry;
- };
-
- const LLMediaEntry& mMediaEntry;
-
- } func_media_data(default_media_data);
-
- LLMediaEntry media_data_get;
- LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get ));
-
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- std::string media_title = "";
- // update UI depending on whether "object" (prim or face) has media
- // and whether or not you are allowed to edit it.
-
- getChildView("add_media")->setEnabled(editable);
- // IF all the faces have media (or all dont have media)
- if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
- {
- // TODO: get media title and set it.
- media_info->clear();
- // if identical is set, all faces are same (whether all empty or has the same media)
- if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) )
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- // else all faces might be empty.
- }
- else // there' re Different Medias' been set on on the faces.
- {
- media_title = multi_media_info_str;
- }
-
- getChildView("delete_media")->setEnabled(bool_has_media && editable );
- // TODO: display a list of all media on the face - use 'identical' flag
- }
- else // not all face has media but at least one does.
- {
- // seleted faces have not identical value
- LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data );
-
- if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
- {
- media_title = multi_media_info_str;
- }
- else
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- }
-
- getChildView("delete_media")->setEnabled(TRUE);
- }
-
- navigateToTitleMedia(media_title);
- media_info->setText(media_title);
-
- // load values for media settings
- updateMediaSettings();
-
- LLFloaterMediaSettings::initValues(mMediaSettings, editable );
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to add media to a prim or prim face
-void LLFloaterTools::onClickBtnAddMedia()
-{
- // check if multiple faces are selected
- if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
- {
- LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
- }
- else
- {
- onClickBtnEditMedia();
- }
-}
-
-// static
-bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- gFloaterTools->onClickBtnEditMedia();
- break;
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to edit existing media settings on a prim or prim face
-// TODO: test if there is media on the item and only allow editing if present
-void LLFloaterTools::onClickBtnEditMedia()
-{
- refreshMedia();
- LLFloaterReg::showInstance("media_settings");
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to delete media from a prim or prim face
-void LLFloaterTools::onClickBtnDeleteMedia()
-{
- LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
-}
-
-
-// static
-bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() );
- if(LLFloaterReg::instanceVisible("media_settings"))
- {
- LLFloaterReg::hideInstance("media_settings");
- }
- break;
-
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::clearMediaSettings()
-{
- LLFloaterMediaSettings::clearValues(false);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::navigateToTitleMedia( const std::string url )
-{
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- if (url.empty() || multi_media_info_str == url)
- {
- // nothing to show
- mNeedMediaTitle = false;
- }
- else if (mTitleMedia)
- {
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
-
- if ( media_plugin ) // Shouldn't this be after navigateTo creates plugin?
- {
- // if it's a movie, we don't want to hear it
- media_plugin->setVolume( 0 );
- };
-
- // check if url changed or if we need a new media source
- if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
- {
- mTitleMedia->navigateTo( url );
- }
-
- // flag that we need to update the title (even if no request were made)
- mNeedMediaTitle = true;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaTitle()
-{
- // only get the media name if we need it
- if ( ! mNeedMediaTitle )
- return;
-
- // get plugin impl
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
- if ( media_plugin )
- {
- // get the media name (asynchronous - must call repeatedly)
- std::string media_title = media_plugin->getMediaName();
-
- // only replace the title if what we get contains something
- if ( ! media_title.empty() )
- {
- // update the UI widget
- LLTextBox* media_title_field = getChild<LLTextBox>("media_info");
- if ( media_title_field )
- {
- media_title_field->setText( media_title );
-
- // stop looking for a title when we get one
- // FIXME: check this is the right approach
- mNeedMediaTitle = false;
- };
- };
- };
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaSettings()
-{
- bool identical( false );
- std::string base_key( "" );
- std::string value_str( "" );
- int value_int = 0;
- bool value_bool = false;
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- // TODO: (CP) refactor this using something clever or boost or both !!
-
- const LLMediaEntry default_media_data;
-
- // controls
- U8 value_u8 = default_media_data.getControls();
- struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
- {
- functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
-
- U8 get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getControls();
- return mMediaEntry.getControls();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_controls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
- base_key = std::string( LLMediaEntry::CONTROLS_KEY );
- mMediaSettings[ base_key ] = value_u8;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // First click (formerly left click)
- value_bool = default_media_data.getFirstClickInteract();
- struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getFirstClickInteract();
- return mMediaEntry.getFirstClickInteract();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_first_click(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
- base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Home URL
- value_str = default_media_data.getHomeURL();
- struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHomeURL();
- return mMediaEntry.getHomeURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_home_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
- base_key = std::string( LLMediaEntry::HOME_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Current URL
- value_str = default_media_data.getCurrentURL();
- struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getCurrentURL();
- return mMediaEntry.getCurrentURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_current_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
- base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto zoom
- value_bool = default_media_data.getAutoZoom();
- struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
- {
-
- functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoZoom();
- return mMediaEntry.getAutoZoom();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_zoom(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto play
- //value_bool = default_media_data.getAutoPlay();
- // set default to auto play TRUE -- angela EXT-5172
- value_bool = true;
- struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoPlay();
- //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_play(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
-
- // Auto scale
- // set default to auto scale TRUE -- angela EXT-5172
- //value_bool = default_media_data.getAutoScale();
- value_bool = true;
- struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoScale();
- // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_scale(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto loop
- value_bool = default_media_data.getAutoLoop();
- struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoLoop();
- return mMediaEntry.getAutoLoop();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_loop(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // width pixels (if not auto scaled)
- value_int = default_media_data.getWidthPixels();
- struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWidthPixels();
- return mMediaEntry.getWidthPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_width_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
- base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // height pixels (if not auto scaled)
- value_int = default_media_data.getHeightPixels();
- struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHeightPixels();
- return mMediaEntry.getHeightPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_height_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
- base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Enable Alt image
- value_bool = default_media_data.getAltImageEnable();
- struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAltImageEnable();
- return mMediaEntry.getAltImageEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_enable_alt_image(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
- base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_control(default_media_data);
- identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_interact(default_media_data);
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist enable
- value_bool = default_media_data.getWhiteListEnable();
- struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteListEnable();
- return mMediaEntry.getWhiteListEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_enable(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
- base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist URLs
- std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
- struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
- {
- functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::vector<std::string> get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteList();
- return mMediaEntry.getWhiteList();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_urls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
- base_key = std::string( LLMediaEntry::WHITELIST_KEY );
- mMediaSettings[ base_key ].clear();
- std::vector< std::string >::iterator iter = value_vector_str.begin();
- while( iter != value_vector_str.end() )
- {
- std::string white_list_url = *iter;
- mMediaSettings[ base_key ].append( white_list_url );
- ++iter;
- };
-
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-}
-
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index ffff564ad4..3bb6492a6e 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -44,7 +44,6 @@ class LLRadioGroup;
class LLSlider;
class LLTabContainer;
class LLTextBox;
-class LLMediaCtrl;
class LLTool;
class LLParcelSelection;
class LLObjectSelection;
@@ -98,11 +97,6 @@ public:
static void setEditTool(void* data);
void setTool(const LLSD& user_data);
void saveLastTool();
- void onClickBtnDeleteMedia();
- void onClickBtnAddMedia();
- void onClickBtnEditMedia();
- void clearMediaSettings();
- bool selectedMediaEditable();
void updateLandImpacts();
static void setGridMode(S32 mode);
@@ -111,13 +105,6 @@ public:
private:
void refresh();
- void refreshMedia();
- void getMediaState();
- void updateMediaSettings();
- void navigateToTitleMedia( const std::string url ); // navigate if changed
- void updateMediaTitle();
- static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
- static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
void onClickGridOptions();
@@ -193,19 +180,12 @@ public:
LLParcelSelectionHandle mParcelSelection;
LLObjectSelectionHandle mObjectSelection;
- LLMediaCtrl *mTitleMedia;
- bool mNeedMediaTitle;
-
private:
BOOL mDirty;
BOOL mHasSelection;
std::map<std::string, std::string> mStatusText;
-
-protected:
- LLSD mMediaSettings;
-
public:
static bool sShowObjectCost;
static bool sPreviousFocusOnAvatar;
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index d5c2ad5f81..917d6dfcd0 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -112,16 +112,6 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
- else
- {
- LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
- if(panel_face)
- {
- panel_face->setMediaType(mime_type);
- panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
- }
-
- }
getChildView("loading_label")->setVisible( false);
closeFloater();
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 09235d8fb2..01bfae8934 100644..100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -82,7 +82,6 @@
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
-static const F32 MAP_ZOOM_TIME = 0.2f;
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
@@ -285,7 +284,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)
BOOL LLFloaterWorldMap::postBuild()
{
- mPanel = getChild<LLPanel>("objects_mapview");
+ mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview"));
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
avatar_combo->selectFirstItem();
@@ -306,15 +305,13 @@ BOOL LLFloaterWorldMap::postBuild()
landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
- mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f);
- getChild<LLUICtrl>("zoom slider")->setValue(mCurZoomVal);
-
+ F32 slider_zoom = mMapView->getZoom();
+ getChild<LLUICtrl>("zoom slider")->setValue(slider_zoom);
+
getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this));
setDefaultBtn(NULL);
- mZoomTimer.stop();
-
onChangeMaturity();
return TRUE;
@@ -324,7 +321,7 @@ BOOL LLFloaterWorldMap::postBuild()
LLFloaterWorldMap::~LLFloaterWorldMap()
{
// All cleaned up by LLView destructor
- mPanel = NULL;
+ mMapView = NULL;
// Inventory deletes all observers on shutdown
mInventory = NULL;
@@ -362,17 +359,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
mIsClosing = FALSE;
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->clearLastClick();
+ mMapView->clearLastClick();
{
// reset pan on show, so it centers on you again
if (!center_on_target)
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, true);
}
- map_panel->updateVisibleBlocks();
+ mMapView->updateVisibleBlocks();
// Reload items as they may have changed
LLWorldMap::getInstance()->reloadItems();
@@ -420,18 +415,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- if (!isMinimized() && isFrontmost())
- {
- if(mPanel->pointInView(x, y))
- {
- F32 slider_value = (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal();
- slider_value += ((F32)clicks * -0.3333f);
- getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_value));
- return TRUE;
- }
- }
-
- return LLFloater::handleScrollWheel(x, y, clicks);
+ if (!isMinimized() && isFrontmost())
+ {
+ S32 map_x = x - mMapView->getRect().mLeft;
+ S32 map_y = y - mMapView->getRect().mBottom;
+ if (mMapView->pointInView(map_x, map_y))
+ {
+ F32 old_slider_zoom = (F32) getChild<LLUICtrl>("zoom slider")->getValue().asReal();
+ F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f);
+ getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_zoom));
+ mMapView->zoomWithPivot(slider_zoom, map_x, map_y);
+ return true;
+ }
+ }
+
+ return LLFloater::handleScrollWheel(x, y, clicks);
}
@@ -510,26 +508,13 @@ void LLFloaterWorldMap::draw()
setMouseOpaque(TRUE);
getDragHandle()->setMouseOpaque(TRUE);
-
- //RN: snaps to zoom value because interpolation caused jitter in the text rendering
- if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal())
- {
- mZoomTimer.start();
- }
- F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME;
- if (interp > 1.f)
- {
- interp = 1.f;
- mZoomTimer.stop();
- }
- mCurZoomVal = lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp);
- F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
- LLWorldMapView::setScale( map_scale );
+
+ mMapView->zoom((F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal());
// Enable/disable checkboxes depending on the zoom level
// If above threshold level (i.e. low res) -> Disable all checkboxes
// If under threshold level (i.e. high res) -> Enable all checkboxes
- bool enable = LLWorldMapView::showRegionInfo();
+ bool enable = mMapView->showRegionInfo();
getChildView("people_chk")->setEnabled(enable);
getChildView("infohub_chk")->setEnabled(enable);
getChildView("telehub_chk")->setEnabled(enable);
@@ -1008,7 +993,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLCtrlListInterface *list = mListFriendCombo;
- if (list)
+ if (list && list->getSelectedValue().asString() != "None")
{
list->selectByValue( "None" );
}
@@ -1028,9 +1013,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()
S32 world_height_regions = MAX_VISIBLE_REGIONS;
// Find how much space we have to display the world
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)mPanel;
- LLRect view_rect = map_panel->getRect();
+ LLRect view_rect = mMapView->getRect();
// View size in pixels
S32 view_width = view_rect.getWidth();
@@ -1298,9 +1281,9 @@ void LLFloaterWorldMap::onShowTargetBtn()
void LLFloaterWorldMap::onShowAgentBtn()
{
- LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
- // Set flag so user's location will be displayed if not tracking anything else
- mSetToUserPosition = TRUE;
+ mMapView->setPanWithInterpTime(0, 0, false, 0.1f); // false == animate
+ // Set flag so user's location will be displayed if not tracking anything else
+ mSetToUserPosition = true;
}
void LLFloaterWorldMap::onClickTeleportBtn()
@@ -1368,9 +1351,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
pos_global.clearVec();
}
- LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- !animate);
+ F64 map_scale = (F64)mMapView->getScale();
+ mMapView->setPanWithInterpTime(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)),
+ -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)),
+ !animate, 0.1f);
mWaitingForTracker = FALSE;
}
@@ -1600,7 +1584,7 @@ void LLFloaterWorldMap::onTeleportFinished()
{
if(isInVisibleChain())
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, TRUE);
}
}
@@ -1675,9 +1659,8 @@ void LLFloaterWorldMap::onChangeMaturity()
void LLFloaterWorldMap::onFocusLost()
{
- gViewerWindow->showCursor();
- LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->mPanning = FALSE;
+ gViewerWindow->showCursor();
+ mMapView->mPanning = false;
}
LLPanelHideBeacon::LLPanelHideBeacon() :
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index fcb55e9666..3702226d23 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -44,6 +44,7 @@ class LLInventoryObserver;
class LLItemInfo;
class LLLineEditor;
class LLTabContainer;
+class LLWorldMapView;
class LLFloaterWorldMap : public LLFloater
{
@@ -156,11 +157,7 @@ protected:
void onTeleportFinished();
private:
- LLPanel* mPanel; // Panel displaying the map
-
- // Ties to LLWorldMapView::sMapScale, in pixels per region
- F32 mCurZoomVal;
- LLFrameTimer mZoomTimer;
+ LLWorldMapView* mMapView; // Panel displaying the map
// update display of teleport destination coordinates - pos is in global coordinates
void updateTeleportCoordsDisplay( const LLVector3d& pos );
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 0be748ace9..e395da7f1e 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -327,22 +327,63 @@ void LLFriendCardsManager::syncFriendCardsFolders()
/************************************************************************/
/* Private Methods */
/************************************************************************/
-const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
+const LLUUID& LLFriendCardsManager::findFirstCallingCardSubfolder(const LLUUID &parent_id) const
{
- const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+ if (parent_id.isNull())
+ {
+ return LLUUID::null;
+ }
- std::string friendFolderName = get_friend_folder_name();
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(parent_id, cats, items);
- return findChildFolderUUID(callingCardsFolderID, friendFolderName);
+ if (!cats || !items || cats->size() == 0)
+ {
+ // call failed
+ return LLUUID::null;
+ }
+
+ if (cats->size() > 1)
+ {
+ const LLViewerInventoryCategory* friendFolder = gInventory.getCategory(parent_id);
+ if (friendFolder)
+ {
+ LL_WARNS_ONCE() << friendFolder->getName() << " folder contains more than one folder" << LL_ENDL;
+ }
+ }
+
+ for (LLInventoryModel::cat_array_t::const_iterator iter = cats->begin();
+ iter != cats->end();
+ ++iter)
+ {
+ const LLInventoryCategory* category = (*iter);
+ if (category->getPreferredType() == LLFolderType::FT_CALLINGCARD)
+ {
+ return category->getUUID();
+ }
+ }
+
+ return LLUUID::null;
}
-const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+// Inventorry ->
+// Calling Cards - >
+// Friends - > (the only expected folder)
+// All (the only expected folder)
+
+const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
{
- LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
+ const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+ return findFirstCallingCardSubfolder(callingCardsFolderID);
+}
- std::string friendAllSubfolderName = get_friend_all_subfolder_name();
+const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+{
+ LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
- return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName);
+ return findFirstCallingCardSubfolder(friendFolderUUID);
}
const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index 2fb912a930..f5679d7d85 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -116,6 +116,7 @@ private:
}
const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const;
+ const LLUUID& findFirstCallingCardSubfolder(const LLUUID &parent_id) const;
const LLUUID& findFriendFolderUUIDImpl() const;
const LLUUID& findFriendAllSubfolderUUIDImpl() const;
const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID);
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 91ab445273..7c8e8279c2 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -185,7 +185,7 @@ private:
std::set<LLUUID> mLoadingAssets;
// LLEventHost interface
- boost::shared_ptr<LLGestureListener> mListener;
+ std::shared_ptr<LLGestureListener> mListener;
};
#endif
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index e7bc2a9268..84a1278767 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -196,7 +196,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
// static
void LLGroupActions::search()
{
- LLFloaterReg::showInstance("search");
+ LLFloaterReg::showInstance("search", LLSD().with("collection", "groups"));
}
// static
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 7be35ac260..5952edfc44 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -330,7 +330,7 @@ void LLHUDText::updateVisibility()
if (!mSourceObject)
{
- LL_WARNS() << "HUD text: mSourceObject is NULL, mOnHUDAttachment: " << mOnHUDAttachment << LL_ENDL;
+ // Beacons
mVisible = TRUE;
if (mOnHUDAttachment)
{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 45355da2e0..4d6ebf9cbb 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -532,7 +532,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
mSessionInitialized(false),
mCallBackEnabled(true),
mTextIMPossible(true),
- mOtherParticipantIsAvatar(true),
mStartCallOnInitialize(false),
mStartedAsIMCall(voice),
mIsDNDsend(false),
@@ -544,13 +543,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType)
{
mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
- mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID);
-
- // check if it was AVALINE call
- if (!mOtherParticipantIsAvatar)
- {
- mSessionType = AVALINE_SESSION;
- }
}
else
{
@@ -651,9 +643,6 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
switch(mSessionType)
{
- case AVALINE_SESSION:
- // no text notifications
- break;
case P2P_SESSION:
LLAvatarNameCache::get(mOtherParticipantID, &av_name);
other_avatar_name = av_name.getUserName();
@@ -930,11 +919,6 @@ bool LLIMModel::LLIMSession::isGroupChat()
return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID, TRUE));
}
-bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
-{
- return !mOtherParticipantIsAvatar;
-}
-
LLUUID LLIMModel::LLIMSession::generateOutgoingAdHocHash() const
{
LLUUID hash = LLUUID::null;
@@ -1812,7 +1796,6 @@ LLIMMgr::onConfirmForceCloseError(
LLCallDialogManager::LLCallDialogManager():
mPreviousSessionlName(""),
-mPreviousSessionType(LLIMModel::LLIMSession::P2P_SESSION),
mCurrentSessionlName(""),
mSession(NULL),
mOldState(LLVoiceChannel::STATE_READY)
@@ -1843,12 +1826,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution
return;
}
-
- if (mSession)
- {
- // store previous session type to process Avaline calls in dialogs
- mPreviousSessionType = mSession->mSessionType;
- }
mSession = session;
@@ -1874,7 +1851,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
- mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = LLVoiceChannel::STATE_CALL_STARTED;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@@ -1910,7 +1886,6 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
- mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = new_state;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@@ -1927,8 +1902,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
break;
case LLVoiceChannel::STATE_HUNG_UP:
- // this state is coming before session is changed, so, put it into payload map
- mCallDialogPayload["old_session_type"] = mSession->mSessionType;
+ // this state is coming before session is changed
break;
case LLVoiceChannel::STATE_CONNECTED :
@@ -2048,7 +2022,6 @@ void LLCallDialog::onOpen(const LLSD& key)
void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
{
- // *NOTE: 12/28/2009: check avaline calls: LLVoiceClient::isParticipantAvatar returns false for them
bool participant_is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
bool is_group = participant_is_avatar && gAgent.isInGroup(session_id, TRUE);
@@ -2069,8 +2042,8 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
}
else
{
- avatar_icon->setValue("Avaline_Icon");
- avatar_icon->setToolTip(std::string(""));
+ LL_WARNS() << "Participant neither avatar nor group" << LL_ENDL;
+ group_icon->setValue(session_id);
}
}
@@ -2114,13 +2087,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
// tell the user which voice channel they are leaving
if (!mPayload["old_channel_name"].asString().empty())
{
- bool was_avaline_call = LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["old_session_type"].asInteger();
-
std::string old_caller_name = mPayload["old_channel_name"].asString();
- if (was_avaline_call)
- {
- old_caller_name = LLTextUtil::formatPhoneNumber(old_caller_name);
- }
getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", old_caller_name);
show_oldchannel = true;
@@ -2133,10 +2100,6 @@ void LLOutgoingCallDialog::show(const LLSD& key)
if (!mPayload["disconnected_channel_name"].asString().empty())
{
std::string channel_name = mPayload["disconnected_channel_name"].asString();
- if (LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["session_type"].asInteger())
- {
- channel_name = LLTextUtil::formatPhoneNumber(channel_name);
- }
getChild<LLUICtrl>("nearby")->setTextArg("[VOICE_CHANNEL_NAME]", channel_name);
// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice,
@@ -2152,16 +2115,11 @@ void LLOutgoingCallDialog::show(const LLSD& key)
std::string callee_name = mPayload["session_name"].asString();
LLUUID session_id = mPayload["session_id"].asUUID();
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- if (callee_name == "anonymous")
+ if (callee_name == "anonymous") // obsolete? Likely was part of avaline support
{
callee_name = getString("anonymous");
}
- else if (!is_avatar)
- {
- callee_name = LLTextUtil::formatPhoneNumber(callee_name);
- }
LLSD callee_id = mPayload["other_user_id"];
// Beautification: Since you know who you called, just show display name
@@ -2361,18 +2319,11 @@ BOOL LLIncomingCallDialog::postBuild()
call_type = getString(notify_box_type);
}
- // check to see if this is an Avaline call
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- if (caller_name == "anonymous")
+ if (caller_name == "anonymous") // obsolete? Likely was part of avaline support
{
caller_name = getString("anonymous");
setCallerName(caller_name, caller_name, call_type);
}
- else if (!is_avatar)
- {
- caller_name = LLTextUtil::formatPhoneNumber(caller_name);
- setCallerName(caller_name, caller_name, call_type);
- }
else
{
// Get the full name information
@@ -2392,7 +2343,7 @@ BOOL LLIncomingCallDialog::postBuild()
if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc")
{
- // starting notification's timer for P2P and AVALINE invitations
+ // starting notification's timer for P2P invitations
mLifetimeTimer.start();
}
else
@@ -2401,7 +2352,7 @@ BOOL LLIncomingCallDialog::postBuild()
}
//it's not possible to connect to existing Ad-Hoc/Group chat through incoming ad-hoc call
- //and no IM for avaline
+ bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup");
setCanDrag(FALSE);
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 79c831ebb6..fdf9806e2e 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -72,7 +72,6 @@ public:
P2P_SESSION,
GROUP_SESSION,
ADHOC_SESSION,
- AVALINE_SESSION,
NONE_SESSION,
} SType;
@@ -92,12 +91,10 @@ public:
bool isAdHoc();
bool isP2P();
bool isGroupChat();
- bool isOtherParticipantAvaline();
bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}
bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;}
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
- bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
LLUUID generateOutgoingAdHocHash() const;
@@ -136,7 +133,6 @@ public:
bool mCallBackEnabled;
bool mTextIMPossible;
- bool mOtherParticipantIsAvatar;
bool mStartCallOnInitialize;
//if IM session is created for a voice call
@@ -516,7 +512,6 @@ private:
protected:
std::string mPreviousSessionlName;
- LLIMModel::LLIMSession::SType mPreviousSessionType;
std::string mCurrentSessionlName;
LLIMModel::LLIMSession* mSession;
LLVoiceChannel::EState mOldState;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 884007d2a6..a0bc1035bf 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1115,7 +1115,10 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
LLInventoryModel::cat_array_t categories;
LLInventoryModel::item_array_t items;
gInventory.collectDescendents(local_version_folder_id, categories, items, FALSE);
- if (categories.size() >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount"))
+ LLCachedControl<U32> max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4);
+ LLCachedControl<U32> max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20);
+ if (categories.size() >= max_count
+ || depth > (max_depth + 1))
{
disabled_items.push_back(std::string("New Folder"));
}
@@ -3811,7 +3814,20 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
if (item && can_move_to_landmarks(item))
{
- dropToFavorites(item);
+ if (LLClipboard::instance().isCutMode())
+ {
+ LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
+ llassert(viitem);
+ if (viitem)
+ {
+ //changeItemParent() implicity calls dirtyFilter
+ changeItemParent(model, viitem, parent_id, FALSE);
+ }
+ }
+ else
+ {
+ dropToFavorites(item);
+ }
}
}
else if (LLClipboard::instance().isCutMode())
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 37500176ea..fab7ae8f1a 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -135,15 +135,7 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
///----------------------------------------------------------------------------
/// Class LLInventoryValidationInfo
///----------------------------------------------------------------------------
-LLInventoryValidationInfo::LLInventoryValidationInfo():
- mFatalErrorCount(0),
- mWarningCount(0),
- mLoopCount(0),
- mOrphanedCount(0),
- mInitialized(false),
- mFatalNoRootFolder(false),
- mFatalNoLibraryRootFolder(false),
- mFatalQADebugMode(false)
+LLInventoryValidationInfo::LLInventoryValidationInfo()
{
}
@@ -165,7 +157,6 @@ std::ostream& operator<<(std::ostream& os, const LLInventoryValidationInfo& v)
void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
{
sd["fatal_error_count"] = mFatalErrorCount;
- sd["warning_count"] = mWarningCount;
sd["loop_count"] = mLoopCount;
sd["orphaned_count"] = mOrphanedCount;
sd["initialized"] = mInitialized;
@@ -173,6 +164,20 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
sd["fatal_no_root_folder"] = mFatalNoRootFolder;
sd["fatal_no_library_root_folder"] = mFatalNoLibraryRootFolder;
sd["fatal_qa_debug_mode"] = mFatalQADebugMode;
+
+ sd["warning_count"] = mWarningCount;
+ if (mWarningCount>0)
+ {
+ sd["warnings"] = LLSD::emptyArray();
+ for (auto const& it : mWarnings)
+ {
+ S32 val =LLSD::Integer(it.second);
+ if (val>0)
+ {
+ sd["warnings"][it.first] = val;
+ }
+ }
+ }
if (mMissingRequiredSystemFolders.size()>0)
{
sd["missing_system_folders"] = LLSD::emptyArray();
@@ -344,13 +349,13 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL
return NULL;
}
-LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
+LLInventoryModel::EAncestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
{
LLInventoryObject *object = getObject(object_id);
if (!object)
{
LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL;
- return ANSCESTOR_MISSING;
+ return ANCESTOR_MISSING;
}
std::set<LLUUID> object_ids{ object_id }; // loop protection
@@ -360,19 +365,19 @@ LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(co
if (object_ids.find(parent_id) != object_ids.end())
{
LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL;
- return ANSCESTOR_LOOP;
+ return ANCESTOR_LOOP;
}
object_ids.insert(parent_id);
LLInventoryObject *parent_object = getObject(parent_id);
if (!parent_object)
{
LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL;
- return ANSCESTOR_MISSING;
+ return ANCESTOR_MISSING;
}
object = parent_object;
}
result = object->getUUID();
- return ANSCESTOR_OK;
+ return ANCESTOR_OK;
}
// Get the object by id. Returns NULL if not found.
@@ -541,9 +546,18 @@ void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::E
LLViewerInventoryCategory* cat = getCategory(*it);
changeCategoryParent(cat, main_id, TRUE);
}
-
+
// Purge the emptied folder
- removeCategory(folder_id);
+ // Note that this might be a system folder, don't validate removability
+ LLViewerInventoryCategory* cat = getCategory(folder_id);
+ if (cat)
+ {
+ const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (trash_id.notNull())
+ {
+ changeCategoryParent(cat, trash_id, TRUE);
+ }
+ }
remove_inventory_category(folder_id, NULL);
}
}
@@ -3132,7 +3146,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
gInventory.accountForUpdate(update);
}
- U32 changes = 0x0;
if (account)
{
mask |= LLInventoryObserver::CREATE;
@@ -3140,7 +3153,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
//as above, this loop never seems to loop more than once per call
for (item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
- changes |= gInventory.updateItem(*it, mask);
+ gInventory.updateItem(*it, mask);
}
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
@@ -3899,9 +3912,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo;
S32 fatal_errs = 0;
- S32 warnings = 0;
- S32 loops = 0;
- S32 orphaned = 0;
+ S32 warning_count= 0;
+ S32 loop_count = 0;
+ S32 orphaned_count = 0;
if (getRootFolderID().isNull())
{
@@ -3922,7 +3935,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// ParentChild should be one larger because of the special entry for null uuid.
LL_INFOS("Inventory") << "unexpected sizes: cat map size " << mCategoryMap.size()
<< " parent/child " << mParentChildCategoryTree.size() << LL_ENDL;
- warnings++;
+
+ validation_info->mWarnings["category_map_size"]++;
+ warning_count++;
}
S32 cat_lock = 0;
S32 item_lock = 0;
@@ -3941,32 +3956,35 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cat)
{
LL_WARNS("Inventory") << "null cat" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_cat"]++;
+ warning_count++;
continue;
}
LLUUID topmost_ancestor_id;
// Will leave as null uuid on failure
- EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
+ EAncestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
switch (res)
{
- case ANSCESTOR_MISSING:
- orphaned++;
+ case ANCESTOR_MISSING:
+ orphaned_count++;
break;
- case ANSCESTOR_LOOP:
- loops++;
+ case ANCESTOR_LOOP:
+ loop_count++;
break;
- case ANSCESTOR_OK:
+ case ANCESTOR_OK:
break;
default:
LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["unknown_ancestor_status"]++;
+ warning_count++;
break;
}
if (cat_id != cat->getUUID())
{
LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["cat_id_index_mismatch"]++;
+ warning_count++;
}
if (cat->getParentUUID().isNull())
@@ -3976,7 +3994,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "cat " << cat_id << " has no parent, but is not root ("
<< getRootFolderID() << ") or library root ("
<< getLibraryRootFolderID() << ")" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_parent"]++;
+ warning_count++;
}
}
cat_array_t* cats;
@@ -3985,7 +4004,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cats || !items)
{
LL_WARNS("Inventory") << "invalid direct descendents for " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["direct_descendents"]++;
+ warning_count++;
continue;
}
if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
@@ -4003,7 +4023,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " cached " << cat->getDescendentCount()
<< " expected " << cats->size() << "+" << items->size()
<< "=" << cats->size() +items->size() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["invalid_descendent_count"]++;
+ warning_count++;
}
}
if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
@@ -4027,7 +4048,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!item)
{
LL_WARNS("Inventory") << "null item at index " << i << " for cat " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_item_at_index"]++;
+ warning_count++;
continue;
}
@@ -4038,7 +4060,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "wrong parent for " << item_id << " found "
<< item->getParentUUID() << " expected " << cat_id
<< LL_ENDL;
- warnings++;
+ validation_info->mWarnings["wrong_parent_for_item"]++;
+ warning_count++;
}
@@ -4048,7 +4071,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " found as child of "
<< cat_id << " but not in top level mItemMap" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["item_not_in_top_map"]++;
+ warning_count++;
}
else
{
@@ -4062,11 +4086,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// Topmost ancestor should be root or library.
LLUUID topmost_ancestor_id;
- EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
- if (found != ANSCESTOR_OK)
+ EAncestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
+ if (found != ANCESTOR_OK)
{
LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_found"]++;
+ warning_count++;
}
else
{
@@ -4077,7 +4102,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " got " << topmost_ancestor_id
<< " expected " << getRootFolderID()
<< " or " << getLibraryRootFolderID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_recognized"]++;
+ warning_count++;
}
}
}
@@ -4093,7 +4119,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4111,7 +4137,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
}
}
@@ -4120,7 +4146,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LLFolderType::EType folder_type = cat->getPreferredType();
bool cat_is_in_library = false;
LLUUID topmost_id;
- if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID())
+ if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANCESTOR_OK && topmost_id == getLibraryRootFolderID())
{
cat_is_in_library = true;
}
@@ -4153,14 +4179,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (item->getUUID() != item_id)
{
LL_WARNS("Inventory") << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["item_id_mismatch"]++;
+ warning_count++;
}
const LLUUID& parent_id = item->getParentUUID();
if (parent_id.isNull())
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4171,7 +4198,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4188,7 +4215,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
}
@@ -4206,18 +4233,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType()
<< " missing backlink info at target_id " << target_id
<< LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
// Links should have referents.
if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
{
LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
{
LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
if (target_item && target_item->getIsLinkType())
{
@@ -4289,13 +4316,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (is_automatic)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL;
- fatal_errs++;
validation_info->mMissingRequiredSystemFolders.insert(folder_type);
+ fatal_errs++;
}
else
{
// Can create, and will when needed.
- warnings++;
+ // (Not sure this is really a warning, but worth logging)
+ validation_info->mWarnings["missing_system_folder_can_create"]++;
+ warning_count++;
}
}
else if (count_under_root > 1)
@@ -4306,6 +4335,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
// It is a fatal problem or can lead to fatal problems for COF,
// outfits, trash and other non-automatic folders.
+ validation_info->mFatalSystemDuplicate++;
fatal_errs++;
}
else
@@ -4313,13 +4343,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// For automatic folders it's not a fatal issue and shouldn't
// break inventory or other functionality further
// Exception: FT_SETTINGS is not automatic, but only deserves a warning.
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++;
+ warning_count++;
}
}
if (count_elsewhere > 0)
{
LL_WARNS("Inventory") << "Found " << count_elsewhere << " extra folders of type " << ft << " outside of root" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++;
+ warning_count++;
}
}
}
@@ -4341,12 +4373,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// FIXME need to fail login and tell user to retry, contact support if problem persists.
bool valid = (fatal_errs == 0);
- LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
+ LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warning_count << ", valid: " << valid << LL_ENDL;
validation_info->mFatalErrorCount = fatal_errs;
- validation_info->mWarningCount = warnings;
- validation_info->mLoopCount = loops;
- validation_info->mOrphanedCount = orphaned;
+ validation_info->mWarningCount = warning_count;
+ validation_info->mLoopCount = loop_count;
+ validation_info->mOrphanedCount = orphaned_count;
return validation_info;
}
@@ -4551,12 +4583,10 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore:
}
// as above, this loop never seems to loop more than once per call
- U32 changes(0U);
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
- changes |= gInventory.updateItem(*it);
+ gInventory.updateItem(*it);
}
- // *HUH: Have computed 'changes', nothing uses it.
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index eeec89bfb0..c4133ff9bb 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -65,15 +65,19 @@ public:
void toOstream(std::ostream& os) const;
void asLLSD(LLSD& sd) const;
+ bool mInitialized{false};
+ S32 mWarningCount{0};
+ std::map<std::string,U32> mWarnings;
+
+ S32 mLoopCount{0}; // Presence of folders whose ancestors loop onto themselves
+ S32 mOrphanedCount{0}; // Missing or orphaned items, links and folders
+
+ S32 mFatalErrorCount{0};
+ bool mFatalNoRootFolder{false};
+ S32 mFatalSystemDuplicate{0};
+ bool mFatalNoLibraryRootFolder{false};
+ bool mFatalQADebugMode{false};
- S32 mFatalErrorCount;
- S32 mWarningCount;
- S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves
- S32 mOrphanedCount; // Missing or orphaned items, links and folders
- bool mInitialized;
- bool mFatalNoRootFolder;
- bool mFatalNoLibraryRootFolder;
- bool mFatalQADebugMode;
std::set<LLFolderType::EType> mMissingRequiredSystemFolders;
std::set<LLFolderType::EType> mDuplicateRequiredSystemFolders;
};
@@ -286,13 +290,13 @@ public:
// Check if one object has a parent chain up to the category specified by UUID.
BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const;
- enum EAnscestorResult{
- ANSCESTOR_OK = 0,
- ANSCESTOR_MISSING = 1,
- ANSCESTOR_LOOP = 2,
+ enum EAncestorResult{
+ ANCESTOR_OK = 0,
+ ANCESTOR_MISSING = 1,
+ ANCESTOR_LOOP = 2,
};
// Follow parent chain to the top.
- EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
+ EAncestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
//--------------------------------------------------------------------
// Find
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
index 1364067949..ce4ec668f1 100644
--- a/indra/newview/lllegacyatmospherics.cpp
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -386,7 +386,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
return;
}
- const BOOL hide_clip_plane = TRUE;
LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f);
const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
@@ -472,33 +471,17 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
render_fog_color = sky_fog_color;
- F32 fog_density = 0.f;
fog_distance = mFogRatio * distance;
if (camera_height > water_height)
{
LLColor4 fog(render_fog_color);
mGLFogCol = fog;
-
- if (hide_clip_plane)
- {
- // For now, set the density to extend to the cull distance.
- const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
- fog_density = f_log/fog_distance;
- }
- else
- {
- const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
- fog_density = (f_log)/fog_distance;
- }
}
else
{
LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
F32 depth = water_height - camera_height;
-
- // get the water param manager variables
- float water_fog_density = pwater->getModifiedWaterFogDensity(depth <= 0.0f);
LLColor4 water_fog_color(pwater->getWaterFogColor());
@@ -512,9 +495,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
// set the gl fog color
mGLFogCol = fogCol;
-
- // set the density based on what the shaders use
- fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
}
mFogColor = sky_fog_color;
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index 79dbe17982..af2a9f6afd 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -109,6 +109,8 @@ public:
LLLineEditor* getTextEntry() const { return mTextEntry; }
void handleLoginComplete();
+ bool isNavMeshDirty() { return mIsNavMeshDirty; }
+
private:
enum EParcelIcon
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 044c76ce2c..dd4ae4d201 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -758,7 +758,14 @@ void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type&
if (mMarketPlaceStatus != MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
{
// If already initialized, just confirm the status so the callback gets called
- setSLMStatus(mMarketPlaceStatus);
+ if (mMarketPlaceFailureReason.empty())
+ {
+ setSLMStatus(mMarketPlaceStatus);
+ }
+ else
+ {
+ setSLMConnectionFailure(mMarketPlaceFailureReason);
+ }
}
else
{
@@ -799,28 +806,27 @@ void LLMarketplaceData::getMerchantStatusCoro()
if (httpCode == HTTP_NOT_FOUND)
{
log_SLM_infos("Get /merchant", httpCode, std::string("User is not a merchant"));
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
}
else if (httpCode == HTTP_SERVICE_UNAVAILABLE)
{
log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated"));
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
- else if (httpCode == HTTP_INTERNAL_ERROR)
+ else
{
- // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938
LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode
<< ", reason : " << status.toString()
<< ", code : " << result["error_code"].asString()
<< ", description : " << result["error_description"].asString() << LL_ENDL;
- LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
- }
- else
- {
- std::string err_code = result["error_code"].asString();
- //std::string err_description = result["error_description"].asString();
- log_SLM_warning("Get /merchant", httpCode, status.toString(), err_code, result["error_description"]);
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+ std::string reason = status.toString();
+ if (reason.empty())
+ {
+ reason = result["error_code"].asString();
+ }
+ // Since user might not even have a marketplace, there is no reason to report the error
+ // to the user, instead write it down into listings' floater
+ LLMarketplaceData::instance().setSLMConnectionFailure(reason);
}
return;
}
@@ -1298,6 +1304,17 @@ std::string LLMarketplaceData::getSLMConnectURL(const std::string& route)
void LLMarketplaceData::setSLMStatus(U32 status)
{
mMarketPlaceStatus = status;
+ mMarketPlaceFailureReason.clear();
+ if (mStatusUpdatedSignal)
+ {
+ (*mStatusUpdatedSignal)();
+ }
+}
+
+void LLMarketplaceData::setSLMConnectionFailure(const std::string& reason)
+{
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE;
+ mMarketPlaceFailureReason = reason;
if (mStatusUpdatedSignal)
{
(*mStatusUpdatedSignal)();
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index fee9225f77..088507d850 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -198,7 +198,9 @@ public:
typedef boost::signals2::signal<void ()> status_updated_signal_t;
void initializeSLM(const status_updated_signal_t::slot_type& cb);
U32 getSLMStatus() const { return mMarketPlaceStatus; }
+ std::string getSLMConnectionfailureReason() { return mMarketPlaceFailureReason; }
void setSLMStatus(U32 status);
+ void setSLMConnectionFailure(const std::string& reason);
void getSLMListings();
bool isEmpty() { return (mMarketplaceItems.size() == 0); }
void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb);
@@ -272,6 +274,7 @@ private:
// Handling Marketplace connection and inventory connection
U32 mMarketPlaceStatus;
+ std::string mMarketPlaceFailureReason;
status_updated_signal_t* mStatusUpdatedSignal;
LLInventoryObserver* mInventoryObserver;
bool mDirtyCount; // If true, stock count value need to be updated at the next check
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index bc45eb6d3a..9d0f62a30d 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -154,8 +154,7 @@ void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred)
if (matchPred(*it))
{
(*it)->markDead();
- // *TDOO: When C++11 is in change the following line to: it = c.erase(it);
- c.erase(it++);
+ it = c.erase(it);
}
else
{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d28e929b48..a15a61429b 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -383,6 +383,9 @@ U32 LLMeshRepository::sLODPending = 0;
U32 LLMeshRepository::sCacheBytesRead = 0;
U32 LLMeshRepository::sCacheBytesWritten = 0;
+U32 LLMeshRepository::sCacheBytesHeaders = 0;
+U32 LLMeshRepository::sCacheBytesSkins = 0;
+U32 LLMeshRepository::sCacheBytesDecomps = 0;
U32 LLMeshRepository::sCacheReads = 0;
U32 LLMeshRepository::sCacheWrites = 0;
U32 LLMeshRepository::sMaxLockHoldoffs = 0;
@@ -1877,6 +1880,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
LLMutexLock lock(mHeaderMutex);
mMeshHeaderSize[mesh_id] = header_size;
mMeshHeader[mesh_id] = header;
+ LLMeshRepository::sCacheBytesHeaders += header_size;
}
@@ -2054,17 +2058,6 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_
if (volume->unpackVolumeFaces(stream, data_size))
{
- //load volume faces into decomposition buffer
- S32 vertex_count = 0;
- S32 index_count = 0;
-
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
- vertex_count += face.mNumVertices;
- index_count += face.mNumIndices;
- }
-
d->mPhysicsShapeMesh.clear();
std::vector<LLVector3>& pos = d->mPhysicsShapeMesh.mPositions;
@@ -3019,27 +3012,6 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
return -1;
}
-void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
-{
- mThread->mMeshHeader[data.mUUID] = header;
-
- // we cache the mesh for default parameters
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH);
-
- for (U32 i = 0; i < 4; i++)
- {
- if (data.mModel[i].notNull())
- {
- LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
- volume->copyVolumeFaces(data.mModel[i]);
- volume->setMeshAssetLoaded(TRUE);
- }
- }
-
-}
-
// Handle failed or successful requests for mesh assets.
//
// Support for 200 responses was added for several reasons. One,
@@ -3957,6 +3929,8 @@ void LLMeshRepository::notifyLoadedMeshes()
void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)
{
mSkinMap[info.mMeshID] = info;
+ // Alternative: We can get skin size from header
+ sCacheBytesSkins += info.sizeBytes();
skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID);
if (iter != mLoadingSkins.end())
@@ -3980,10 +3954,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
{ //just insert decomp into map
mDecompositionMap[decomp->mMeshID] = decomp;
mLoadingDecompositions.erase(decomp->mMeshID);
+ sCacheBytesDecomps += decomp->sizeBytes();
}
else
{ //merge decomp with existing entry
+ sCacheBytesDecomps -= iter->second->sizeBytes();
iter->second->merge(decomp);
+ sCacheBytesDecomps += iter->second->sizeBytes();
+
mLoadingDecompositions.erase(decomp->mMeshID);
delete decomp;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 1989350303..f61da3e571 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -554,6 +554,9 @@ public:
static U32 sLODProcessing;
static U32 sCacheBytesRead;
static U32 sCacheBytesWritten;
+ static U32 sCacheBytesHeaders;
+ static U32 sCacheBytesSkins;
+ static U32 sCacheBytesDecomps;
static U32 sCacheReads;
static U32 sCacheWrites;
static U32 sMaxLockHoldoffs; // Maximum sequential locking failures
@@ -643,8 +646,6 @@ public:
std::queue<LLUUID> mPendingPhysicsShapeRequests;
U32 mMeshThreadCount;
-
- void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header);
LLMeshRepoThread* mThread;
std::vector<LLMeshUploadThread*> mUploads;
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 3bca4fde83..642df7f931 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -86,6 +86,7 @@ static const LLColor4 PREVIEW_DEG_FILL_COL(1.f, 0.f, 0.f, 0.5f);
static const F32 PREVIEW_DEG_EDGE_WIDTH(3.f);
static const F32 PREVIEW_DEG_POINT_SIZE(8.f);
static const F32 PREVIEW_ZOOM_LIMIT(10.f);
+static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape";
const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
@@ -432,6 +433,20 @@ void LLModelPreview::rebuildUploadData()
LLFloaterModelPreview::addStringToLog(out, false);
}
}
+ if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS))
+ {
+ // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition.
+ // That's ok, but might not what they wanted. Use default_physics_shape if found.
+ std::ostringstream out;
+ out << "No physics model specified for " << instance.mLabel;
+ if (mDefaultPhysicsShapeP)
+ {
+ out << " - using: " << DEFAULT_PHYSICS_MESH_NAME;
+ lod_model = mDefaultPhysicsShapeP;
+ }
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default.
+ }
if (lod_model)
{
@@ -1034,6 +1049,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
}
else
{
+ if (loaded_lod == LLModel::LOD_PHYSICS)
+ { // Explicitly loading physics. See if there is a default mesh.
+ LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own.
+ mDefaultPhysicsShapeP = nullptr;
+ FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform);
+ mWarnOfUnmatchedPhyicsMeshes = true;
+ }
BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
if (!legacyMatching)
{
@@ -1104,7 +1126,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
}
-
mModel[loaded_lod][idx]->mLabel = name;
}
}
@@ -2680,8 +2701,6 @@ void LLModelPreview::clearBuffers()
void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
{
- U32 tri_count = 0;
- U32 vertex_count = 0;
U32 mesh_count = 0;
@@ -2714,7 +2733,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
continue;
}
- LLModel* base_mdl = *base_iter;
base_iter++;
S32 num_faces = mdl->getNumVolumeFaces();
@@ -2789,7 +2807,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
//find closest weight to vf.mVertices[i].mPosition
LLVector3 pos(vf.mPositions[i].getF32ptr());
- const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
+ const LLModel::weight_list& weight_list = mdl->getJointInfluences(pos);
llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
LLVector4 w(0, 0, 0, 0);
@@ -2817,10 +2835,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
mVertexBuffer[lod][mdl].push_back(vb);
- vertex_count += num_vertices;
- tri_count += num_indices / 3;
++mesh_count;
-
}
}
}
@@ -2916,6 +2931,20 @@ void LLModelPreview::loadedCallback(
{
pPreview->lookupLODModelFiles(lod);
}
+
+ const LLVOAvatar* avatarp = pPreview->getPreviewAvatar();
+ if (avatarp) { // set up ground plane for possible rendering
+ const LLVector3 root_pos = avatarp->mRoot->getPosition();
+ const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents();
+ const LLVector4a min = ext[0], max = ext[1];
+ const F32 center = (max[2] - min[2]) * 0.5f;
+ const F32 ground = root_pos[2] - center;
+ auto plane = pPreview->mGroundPlane;
+ plane[0] = {min[0], min[1], ground};
+ plane[1] = {max[0], min[1], ground};
+ plane[2] = {max[0], max[1], ground};
+ plane[3] = {min[0], max[1], ground};
+ }
}
}
@@ -3123,6 +3152,9 @@ BOOL LLModelPreview::render()
// (note: all these UI updates need to be somewhere that is not render)
fmp->childSetValue("upload_skin", true);
mFirstSkinUpdate = false;
+ upload_skin = true;
+ skin_weight = true;
+ mViewOption["show_skin_weight"] = true;
}
fmp->enableViewOption("show_skin_weight");
@@ -3727,6 +3759,7 @@ BOOL LLModelPreview::render()
{
getPreviewAvatar()->renderBones();
}
+ renderGroundPlane(mPelvisZOffset);
if (shader)
{
shader->bind();
@@ -3748,6 +3781,28 @@ BOOL LLModelPreview::render()
return TRUE;
}
+void LLModelPreview::renderGroundPlane(float z_offset)
+{ // Not necesarilly general - beware - but it seems to meet the needs of LLModelPreview::render
+
+ gGL.diffuseColor3f( 1.0f, 0.0f, 1.0f );
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+ gGL.vertex3fv(mGroundPlane[1].mV);
+
+ gGL.vertex3fv(mGroundPlane[1].mV);
+ gGL.vertex3fv(mGroundPlane[2].mV);
+
+ gGL.vertex3fv(mGroundPlane[2].mV);
+ gGL.vertex3fv(mGroundPlane[3].mV);
+
+ gGL.vertex3fv(mGroundPlane[3].mV);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+
+ gGL.end();
+}
+
+
//-----------------------------------------------------------------------------
// refresh()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
index 215f44357f..df7320768c 100644
--- a/indra/newview/llmodelpreview.h
+++ b/indra/newview/llmodelpreview.h
@@ -224,6 +224,23 @@ private:
LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }
// Count amount of original models, excluding sub-models
static U32 countRootModels(LLModelLoader::model_list models);
+ LLVector3 mGroundPlane[4];
+ void renderGroundPlane(float z_offset = 0.0f);
+ /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh.
+ /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when
+ /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()).
+ ///
+ /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When
+ /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when
+ /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot.
+ /// When there are multiple meshes in each file, they are matched by name or order, and some meshes
+ /// are broken up by limitations into multiple objects, and thus there can be mismatches.)
+ bool mWarnOfUnmatchedPhyicsMeshes{false};
+ /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified.
+ /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME.
+ /// It is reset when such a name is not found, and when resetting the modelpreview.
+ /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true.
+ LLModel* mDefaultPhysicsShapeP{};
typedef enum
{
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 4a8ef53a8b..bf00d77dea 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -352,7 +352,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
void LLMuteList::updateAdd(const LLMute& mute)
{
- // External mutes (e.g. Avaline callers) are local only, don't send them to the server.
+ // External mutes are local only, don't send them to the server.
if (mute.mType == LLMute::EXTERNAL)
{
return;
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 5215126789..8058faa5c7 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -271,6 +271,25 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
return handled;
}
+// virtual
+BOOL LLNameListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
+ LLFloater* floater = gFloaterView->getParentFloater(this);
+ if (floater && floater->isFrontmost() && hit_item)
+ {
+ if(hit_item->isGroup())
+ {
+ ContextMenuType prev_menu = getContextMenuType();
+ setContextMenu(MENU_GROUP);
+ BOOL handled = LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+ setContextMenu(prev_menu);
+ return handled;
+ }
+ }
+ return LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+}
+
// public
void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos,
BOOL enabled)
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index ef0be135e6..5dd5da5892 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -170,6 +170,7 @@ public:
/*virtual*/ void updateColumns(bool force_update);
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
private:
void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false);
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item);
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 19dbbeb60e..f5ee1171d9 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -451,9 +451,9 @@ void LLNavigationBar::onLocationSelection()
if(value.has("AssetUUID"))
{
-
gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
- mSaveToLocationHistory = true;
+ // user teleported by manually inputting inventory landmark's name
+ mSaveToLocationHistory = false;
return;
}
else
@@ -713,7 +713,7 @@ void LLNavigationBar::resizeLayoutPanel()
}
void LLNavigationBar::invokeSearch(std::string search_text)
{
- LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text)));
+ LLFloaterReg::showInstance("search", LLSD().with("category", "standard").with("query", LLSD(search_text)));
}
void LLNavigationBar::clearHistoryCache()
@@ -733,3 +733,8 @@ int LLNavigationBar::getDefFavBarHeight()
{
return mDefaultFpRect.getHeight();
}
+
+bool LLNavigationBar::isRebakeNavMeshAvailable()
+{
+ return mCmbLocation->isNavMeshDirty();
+}
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 646911a62c..11c671294a 100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -102,6 +102,8 @@ public:
int getDefNavBarHeight();
int getDefFavBarHeight();
+
+ bool isRebakeNavMeshAvailable();
private:
// the distance between navigation panel and favorites panel in pixels
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 1240ce7c0f..b34be80b07 100644..100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -37,6 +37,7 @@
#include "llfocusmgr.h"
#include "lllocalcliprect.h"
#include "llrender.h"
+#include "llresmgr.h"
#include "llui.h"
#include "lltooltip.h"
@@ -47,11 +48,16 @@
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
#include "llcallingcard.h" // LLAvatarTracker
+#include "llfloaterland.h"
#include "llfloaterworldmap.h"
+#include "llparcel.h"
#include "lltracker.h"
#include "llsurface.h"
+#include "llurlmatch.h"
+#include "llurlregistry.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
+#include "llviewerparcelmgr.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h"
@@ -64,7 +70,10 @@
static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");
const F32 LLNetMap::MAP_SCALE_MIN = 32;
-const F32 LLNetMap::MAP_SCALE_MID = 1024;
+const F32 LLNetMap::MAP_SCALE_FAR = 32;
+const F32 LLNetMap::MAP_SCALE_MEDIUM = 128;
+const F32 LLNetMap::MAP_SCALE_CLOSE = 256;
+const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024;
const F32 LLNetMap::MAP_SCALE_MAX = 4096;
const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%)
@@ -78,13 +87,13 @@ const F64 COARSEUPDATE_MAX_Z = 1020.0f;
LLNetMap::LLNetMap (const Params & p)
: LLUICtrl (p),
mBackgroundColor (p.bg_color()),
- mScale( MAP_SCALE_MID ),
- mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ),
+ mScale( MAP_SCALE_MEDIUM ),
+ mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ),
mObjectMapTPM(0.f),
mObjectMapPixels(0.f),
- mTargetPan(0.f, 0.f),
mCurPan(0.f, 0.f),
mStartPan(0.f, 0.f),
+ mPopupWorldPos(0.f, 0.f, 0.f),
mMouseDown(0, 0),
mPanning(false),
mUpdateNow(false),
@@ -97,6 +106,13 @@ LLNetMap::LLNetMap (const Params & p)
mPopupMenu(NULL)
{
mScale = gSavedSettings.getF32("MiniMapScale");
+ if (gAgent.isFirstLogin())
+ {
+ // *HACK: On first run, set this to false for new users, otherwise the
+ // default is true to maintain consistent experience for existing
+ // users.
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
}
@@ -107,13 +123,22 @@ LLNetMap::~LLNetMap()
BOOL LLNetMap::postBuild()
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2));
- registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- return TRUE;
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar;
+
+ enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2));
+ commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2));
+ commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
+ commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2));
+ enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2));
+ commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2));
+ commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+ mPopupMenu->setItemEnabled("Re-center map", false);
+
+ return true;
}
void LLNetMap::setScale( F32 scale )
@@ -158,18 +183,32 @@ void LLNetMap::draw()
static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
- static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
+ static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f));
if (mObjectImagep.isNull())
{
createObjectImage();
}
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (auto_center)
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ bool auto_centering = auto_center && !mPanning;
+ mCentering = mCentering && !mPanning;
+
+ if (auto_centering || mCentering)
{
- mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));
+ mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f));
}
+ bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f;
+ if (centered)
+ {
+ mCurPan.mV[0] = 0.0f;
+ mCurPan.mV[1] = 0.0f;
+ mCentering = false;
+ }
+
+ bool can_recenter_map = !(centered || mCentering || auto_centering);
+ mPopupMenu->setItemEnabled("Re-center map", can_recenter_map);
+ updateAboutLandPopupButton();
// Prepare a scissor region
F32 rotation = 0;
@@ -216,7 +255,8 @@ void LLNetMap::draw()
}
// figure out where agent is
- S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const F32 scale_pixels_per_meter = mScale / region_width;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -225,8 +265,8 @@ void LLNetMap::draw()
// Find x and y position relative to camera's center.
LLVector3 origin_agent = regionp->getOriginAgent();
LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
- F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
- F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
+ F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter;
// background region rectangle
F32 bottom = relative_y;
@@ -249,6 +289,7 @@ void LLNetMap::draw()
}
+
// Draw using texture.
gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
gGL.begin(LLRender::QUADS);
@@ -310,8 +351,8 @@ void LLNetMap::draw()
LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
map_center_agent -= camera_position;
- map_center_agent.mV[VX] *= mScale/region_width;
- map_center_agent.mV[VY] *= mScale/region_width;
+ map_center_agent.mV[VX] *= scale_pixels_per_meter;
+ map_center_agent.mV[VY] *= scale_pixels_per_meter;
gGL.getTexUnit(0)->bind(mObjectImagep);
F32 image_half_width = 0.5f*mObjectMapPixels;
@@ -327,6 +368,13 @@ void LLNetMap::draw()
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
gGL.end();
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV);
+ }
gGL.popMatrix();
@@ -451,41 +499,34 @@ void LLNetMap::draw()
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
F32 far_clip_pixels = far_clip_meters * meters_to_pixels;
-
- F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
- F32 half_width_pixels = half_width_meters * meters_to_pixels;
- F32 ctr_x = (F32)center_sw_left;
- F32 ctr_y = (F32)center_sw_bottom;
-
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if( rotate_map )
- {
- gGL.color4fv((map_frustum_color()).mV);
-
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( ctr_x, ctr_y );
- gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
- gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
- gGL.end();
- }
- else
- {
- gGL.color4fv((map_frustum_rotating_color()).mV);
-
- // If we don't rotate the map, we have to rotate the frustum.
- gGL.pushMatrix();
- gGL.translatef( ctr_x, ctr_y, 0 );
- gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( 0, 0 );
- gGL.vertex2f( -half_width_pixels, far_clip_pixels );
- gGL.vertex2f( half_width_pixels, far_clip_pixels );
- gGL.end();
- gGL.popMatrix();
- }
+ F32 ctr_x = (F32)center_sw_left;
+ F32 ctr_y = (F32)center_sw_bottom;
+
+ const F32 steps_per_circle = 40.0f;
+ const F32 steps_per_radian = steps_per_circle / F_TWO_PI;
+ const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f));
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if( rotate_map )
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
+ else
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ // If we don't rotate the map, we have to rotate the frustum.
+ gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
}
gGL.popMatrix();
@@ -552,6 +593,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
}
}
+bool LLNetMap::isMouseOnPopupMenu()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return false;
+ }
+
+ S32 popup_x;
+ S32 popup_y;
+ LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y);
+ // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain
+ // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22
+ constexpr S32 tolerance = 10;
+ // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space.
+ // Assume the size of the popup menu is much larger than the provided tolerance.
+ // In practice, this is a [tolerance]px margin around the popup menu.
+ for (S32 sign_x = -1; sign_x <= 1; sign_x += 2)
+ {
+ for (S32 sign_y = -1; sign_y <= 1; sign_y += 2)
+ {
+ if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance)))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void LLNetMap::updateAboutLandPopupButton()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return;
+ }
+
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos);
+ if (!region)
+ {
+ mPopupMenu->setItemEnabled("About Land", false);
+ }
+ else
+ {
+ // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover
+ // parcel can be used to check if location-sensitive tooltip options are available.
+ if (isMouseOnPopupMenu())
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ bool valid_parcel = false;
+ if (hover_parcel)
+ {
+ valid_parcel = hover_parcel->getOwnerID().notNull();
+ }
+ mPopupMenu->setItemEnabled("About Land", valid_parcel);
+ }
+ }
+}
+
LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
{
x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]);
@@ -579,66 +679,152 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
- F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
+ // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
+ F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
F32 old_scale = mScale;
- setScale(new_scale);
+ setScale(new_scale);
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (!auto_center)
- {
- // Adjust pan to center the zoom on the mouse pointer
- LLVector2 zoom_offset;
- zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
- zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
- mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
- }
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ if (!auto_center)
+ {
+ // Adjust pan to center the zoom on the mouse pointer
+ LLVector2 zoom_offset;
+ zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
+ zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
+ mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
+ }
- return TRUE;
+ return true;
}
-BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask)
{
- if (gDisconnected)
- {
- return FALSE;
- }
+ if (gDisconnected)
+ {
+ return false;
+ }
- // If the cursor is near an avatar on the minimap, a mini-inspector will be
- // shown for the avatar, instead of the normal map tooltip.
- if (handleToolTipAgent(mClosestAgentToCursor))
- {
- return TRUE;
- }
+ // If the cursor is near an avatar on the minimap, a mini-inspector will be
+ // shown for the avatar, instead of the normal map tooltip.
+ if (handleToolTipAgent(mClosestAgentToCursor))
+ {
+ return true;
+ }
- LLRect sticky_rect;
- std::string region_name;
- LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
- if(region)
- {
- // set sticky_rect
- S32 SLOP = 4;
- localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
- sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
- sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
-
- region_name = region->getName();
- if (!region_name.empty())
- {
- region_name += "\n";
- }
- }
+ // The popup menu uses the hover parcel when it is open and the mouse is on
+ // top of it, with some additional tolerance. Returning early here prevents
+ // fighting over that hover parcel when getting tooltip info in the
+ // tolerance region.
+ if (isMouseOnPopupMenu())
+ {
+ return false;
+ }
- LLStringUtil::format_map_t args;
- args["[REGION]"] = region_name;
- std::string msg = mToolTipMsg;
- LLStringUtil::format(msg, args);
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(msg)
- .sticky_rect(sticky_rect));
-
- return TRUE;
+ LLRect sticky_rect;
+ S32 SLOP = 4;
+ localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
+ sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
+ sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
+
+ std::string parcel_name_msg;
+ std::string parcel_sale_price_msg;
+ std::string parcel_sale_area_msg;
+ std::string parcel_owner_msg;
+ std::string region_name_msg;
+
+ LLVector3d posGlobal = viewPosToGlobal(x, y);
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal);
+ if (region)
+ {
+ std::string region_name = region->getName();
+ if (!region_name.empty())
+ {
+ region_name_msg = mRegionNameMsg;
+ LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}});
+ }
+
+ // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is
+ // ambiguous.
+ if (gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ if (hover_parcel)
+ {
+ std::string parcel_name = hover_parcel->getName();
+ if (!parcel_name.empty())
+ {
+ parcel_name_msg = mParcelNameMsg;
+ LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}});
+ }
+
+ const LLUUID parcel_owner = hover_parcel->getOwnerID();
+ std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString();
+ static LLUrlMatch parcel_owner_name_url_match;
+ LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match);
+ if (!parcel_owner_name_url_match.empty())
+ {
+ parcel_owner_msg = mParcelOwnerMsg;
+ std::string parcel_owner_name = parcel_owner_name_url_match.getLabel();
+ LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}});
+ }
+
+ if (hover_parcel->getForSale())
+ {
+ const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID();
+ const LLUUID agent_id = gAgent.getID();
+ bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id;
+ if (show_for_sale)
+ {
+ S32 price = hover_parcel->getSalePrice();
+ S32 area = hover_parcel->getArea();
+ F32 cost_per_sqm = 0.0f;
+ if (area > 0)
+ {
+ cost_per_sqm = F32(price) / area;
+ }
+ std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price);
+ std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm);
+ parcel_sale_price_msg = mParcelSalePriceMsg;
+ LLStringUtil::format(parcel_sale_price_msg,
+ {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}});
+ std::string formatted_area = llformat("%d", area);
+ parcel_sale_area_msg = mParcelSaleAreaMsg;
+ LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}});
+ }
+ }
+ }
+ }
+ }
+
+ std::string tool_tip_hint_msg;
+ if (gSavedSettings.getBOOL("DoubleClickTeleport"))
+ {
+ tool_tip_hint_msg = mAltToolTipHintMsg;
+ }
+ else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
+ {
+ tool_tip_hint_msg = mToolTipHintMsg;
+ }
+
+ LLStringUtil::format_map_t args;
+ args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n';
+ args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n';
+ args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n';
+ args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n';
+ args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n';
+ args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n';
+
+ std::string msg = mToolTipMsg;
+ LLStringUtil::format(msg, args);
+ if (msg.back() == '\n')
+ {
+ msg.resize(msg.size() - 1);
+ }
+ LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect));
+
+ return true;
}
BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id)
@@ -811,59 +997,58 @@ void LLNetMap::createObjectImage()
mUpdateNow = true;
}
-BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (!(mask & MASK_SHIFT)) return FALSE;
-
- // Start panning
- gFocusMgr.setMouseCapture(this);
+ // Start panning
+ gFocusMgr.setMouseCapture(this);
- mStartPan = mCurPan;
- mMouseDown.mX = x;
- mMouseDown.mY = y;
- return TRUE;
+ mStartPan = mCurPan;
+ mMouseDown.mX = x;
+ mMouseDown.mY = y;
+ return true;
}
-BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask)
{
- if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3)
- handleClick(x,y,mask);
+ if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3)
+ {
+ handleClick(x, y, mask);
+ }
- if (hasMouseCapture())
- {
- if (mPanning)
- {
- // restore mouse cursor
- S32 local_x, local_y;
- local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
- local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
- LLRect clip_rect = getRect();
- clip_rect.stretch(-8);
- clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
- LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
-
- // finish the pan
- mPanning = false;
-
- mMouseDown.set(0, 0);
-
- // auto centre
- mTargetPan.setZero();
- }
- gViewerWindow->showCursor();
- gFocusMgr.setMouseCapture(NULL);
- return TRUE;
- }
- return FALSE;
+ if (hasMouseCapture())
+ {
+ if (mPanning)
+ {
+ // restore mouse cursor
+ S32 local_x, local_y;
+ local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
+ local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
+ LLRect clip_rect = getRect();
+ clip_rect.stretch(-8);
+ clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
+ LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
+
+ // finish the pan
+ mPanning = false;
+
+ mMouseDown.set(0, 0);
+ }
+ gViewerWindow->showCursor();
+ gFocusMgr.setMouseCapture(NULL);
+ return true;
+ }
+
+ return false;
}
BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (mPopupMenu)
{
+ mPopupWorldPos = viewPosToGlobal(x, y);
mPopupMenu->buildDrawLabels();
mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
+ mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0));
LLMenuGL::showPopup(this, mPopupMenu, x, y);
}
return TRUE;
@@ -911,6 +1096,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
+F32 LLNetMap::getScaleForName(std::string scale_name)
+{
+ if (scale_name == "very close")
+ {
+ return LLNetMap::MAP_SCALE_VERY_CLOSE;
+ }
+ else if (scale_name == "close")
+ {
+ return LLNetMap::MAP_SCALE_CLOSE;
+ }
+ else if (scale_name == "medium")
+ {
+ return LLNetMap::MAP_SCALE_MEDIUM;
+ }
+ else if (scale_name == "far")
+ {
+ return LLNetMap::MAP_SCALE_FAR;
+ }
+ return 0.0f;
+}
+
// static
bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )
{
@@ -928,7 +1134,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
{
if (!mPanning)
{
- // just started panning, so hide cursor
+ // Just started panning. Hide cursor.
mPanning = true;
gViewerWindow->hideCursor();
}
@@ -938,61 +1144,89 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
// Set pan to value at start of drag + offset
mCurPan += delta;
- mTargetPan = mCurPan;
gViewerWindow->moveCursorToCenter();
}
-
- // Doesn't really matter, cursor should be hidden
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- if (mask & MASK_SHIFT)
- {
- // If shift is held, change the cursor to hint that the map can be dragged
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- gViewerWindow->setCursor( UI_CURSOR_CROSS );
- }
}
+ if (mask & MASK_SHIFT)
+ {
+ // If shift is held, change the cursor to hint that the map can be
+ // dragged. However, holding shift is not required to drag the map.
+ gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
+ }
+ else
+ {
+ gViewerWindow->setCursor( UI_CURSOR_CROSS );
+ }
+
return TRUE;
}
-void LLNetMap::handleZoom(const LLSD& userdata)
+bool LLNetMap::isZoomChecked(const LLSD &userdata)
{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- setScale(scale);
- }
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ return scale == mScale;
+}
+
+void LLNetMap::setZoom(const LLSD &userdata)
+{
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ if (scale != 0.0f)
+ {
+ setScale(scale);
+ }
}
void LLNetMap::handleStopTracking (const LLSD& userdata)
{
if (mPopupMenu)
{
- mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ mPopupMenu->setItemEnabled ("Stop tracking", false);
LLTracker::stopTracking (LLTracker::isTracking(NULL));
}
}
+
+void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; }
+
+bool LLNetMap::isMapOrientationChecked(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate");
+ if (command_name == "north_at_top")
+ {
+ return !rotate_map;
+ }
+
+ if (command_name == "camera_at_top")
+ {
+ return rotate_map;
+ }
+
+ return false;
+}
+
+void LLNetMap::setMapOrientation(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ if (command_name == "north_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
+ else if (command_name == "camera_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", true);
+ }
+}
+
+void LLNetMap::popupShowAboutLand(const LLSD &userdata)
+{
+ // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection.
+ LLViewerParcelMgr::getInstance()->deselectLand();
+ LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos);
+ gMenuHolder->setParcelSelection(selection);
+
+ LLFloaterReg::showInstance("about_land", LLSD(), false);
+}
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 1f7e7d68c6..fe1aca65a9 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -62,9 +62,12 @@ protected:
public:
virtual ~LLNetMap();
- static const F32 MAP_SCALE_MIN;
- static const F32 MAP_SCALE_MID;
- static const F32 MAP_SCALE_MAX;
+ static const F32 MAP_SCALE_MIN;
+ static const F32 MAP_SCALE_FAR;
+ static const F32 MAP_SCALE_MEDIUM;
+ static const F32 MAP_SCALE_CLOSE;
+ static const F32 MAP_SCALE_VERY_CLOSE;
+ static const F32 MAP_SCALE_MAX;
/*virtual*/ void draw();
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
@@ -79,8 +82,17 @@ public:
/*virtual*/ BOOL handleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- void setScale( F32 scale );
- void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setScale(F32 scale);
+
+ void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; }
+ void setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; }
+ void setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; }
+ void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; }
+ void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; }
+ void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; }
+ void setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; }
+
void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
private:
@@ -94,11 +106,14 @@ private:
void drawTracking( const LLVector3d& pos_global,
const LLColor4& color,
BOOL draw_arrow = TRUE);
+ bool isMouseOnPopupMenu();
+ void updateAboutLandPopupButton();
BOOL handleToolTipAgent(const LLUUID& avatar_id);
static void showAvatarInspector(const LLUUID& avatar_id);
void createObjectImage();
+ F32 getScaleForName(std::string scale_name);
static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop);
private:
@@ -112,11 +127,12 @@ private:
F32 mObjectMapPixels; // Width of object map in pixels
F32 mDotRadius; // Size of avatar markers
- bool mPanning; // map is being dragged
- LLVector2 mTargetPan;
- LLVector2 mCurPan;
- LLVector2 mStartPan; // pan offset at start of drag
- LLCoordGL mMouseDown; // pointer position at start of drag
+ bool mPanning; // map is being dragged
+ bool mCentering; // map is being re-centered around the agent
+ LLVector2 mCurPan;
+ LLVector2 mStartPan; // pan offset at start of drag
+ LLVector3d mPopupWorldPos; // world position picked under mouse when context menu is opened
+ LLCoordGL mMouseDown; // pointer position at start of drag
LLVector3d mObjectImageCenterGlobal;
LLPointer<LLImageRaw> mObjectRawImagep;
@@ -125,14 +141,26 @@ private:
LLUUID mClosestAgentToCursor;
LLUUID mClosestAgentAtLastRightClick;
- std::string mToolTipMsg;
+ std::string mToolTipMsg;
+ std::string mParcelNameMsg;
+ std::string mParcelSalePriceMsg;
+ std::string mParcelSaleAreaMsg;
+ std::string mParcelOwnerMsg;
+ std::string mRegionNameMsg;
+ std::string mToolTipHintMsg;
+ std::string mAltToolTipHintMsg;
public:
void setSelected(uuid_vec_t uuids) { gmSelected=uuids; };
private:
- void handleZoom(const LLSD& userdata);
- void handleStopTracking (const LLSD& userdata);
+ bool isZoomChecked(const LLSD& userdata);
+ void setZoom(const LLSD& userdata);
+ void handleStopTracking(const LLSD& userdata);
+ void activateCenterMap(const LLSD& userdata);
+ bool isMapOrientationChecked(const LLSD& userdata);
+ void setMapOrientation(const LLSD& userdata);
+ void popupShowAboutLand(const LLSD& userdata);
LLMenuGL* mPopupMenu;
uuid_vec_t gmSelected;
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 9a030f1d7d..ff33efe4aa 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -120,7 +120,7 @@ void LLPanelProfileTab::setApplyProgress(bool started)
}
}
- LLPanel* panel = findChild<LLPanel>("indicator_stack");
+ LLView* panel = findChild<LLView>("indicator_stack");
if (panel)
{
panel->setVisible(started);
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 6e897e2c7e..ea10aa75ae 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1308,7 +1308,8 @@ void LLPanelEditWearable::changeCamera(U8 subpart)
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
{
- gAgentCamera.setFocusOnAvatar(FALSE, FALSE);
+ // Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE
+ gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating());
gMorphView->updateCamera();
}
}
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 7fe5b1dd3f..178aba11a3 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -49,11 +49,15 @@
#include "llinventoryfunctions.h"
#include "llinventorymodel.h" // gInventory
#include "llinventorymodelbackgroundfetch.h"
+#include "llfloatermediasettings.h"
+#include "llfloaterreg.h"
#include "lllineeditor.h"
#include "llmaterialmgr.h"
+#include "llmediactrl.h"
#include "llmediaentry.h"
#include "llmenubutton.h"
#include "llnotificationsutil.h"
+#include "llpanelcontents.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -99,10 +103,9 @@ std::string USE_TEXTURE;
LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
{
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
+ LLRender::eTexIndex channel_to_edit = (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
(radio_mat_type ? (LLRender::eTexIndex)radio_mat_type->getSelectedIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
@@ -161,6 +164,8 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
+ childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this);
+ childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this);
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
@@ -172,7 +177,6 @@ BOOL LLPanelFace::postBuild()
LLColorSwatchCtrl* mShinyColorSwatch;
LLComboBox* mComboTexGen;
- LLComboBox* mComboMatMedia;
LLCheckBoxCtrl *mCheckFullbright;
@@ -308,6 +312,9 @@ BOOL LLPanelFace::postBuild()
mMenuClipboardColor = getChild<LLMenuButton>("clipboard_color_params_btn");
mMenuClipboardTexture = getChild<LLMenuButton>("clipboard_texture_params_btn");
+
+ mTitleMedia = getChild<LLMediaCtrl>("title_media");
+ mTitleMediaText = getChild<LLTextBox>("media_info");
clearCtrls();
@@ -316,24 +323,31 @@ BOOL LLPanelFace::postBuild()
LLPanelFace::LLPanelFace()
: LLPanel(),
- mIsAlpha(false)
+ mIsAlpha(false),
+ mComboMatMedia(NULL),
+ mTitleMedia(NULL),
+ mTitleMediaText(NULL),
+ mNeedMediaTitle(true)
{
USE_TEXTURE = LLTrans::getString("use_texture");
mCommitCallbackRegistrar.add("PanelFace.menuDoToSelected", boost::bind(&LLPanelFace::menuDoToSelected, this, _2));
mEnableCallbackRegistrar.add("PanelFace.menuEnable", boost::bind(&LLPanelFace::menuEnableItem, this, _2));
}
-
LLPanelFace::~LLPanelFace()
{
- // Children all cleaned up by default view destructor.
+ unloadMedia();
}
-
void LLPanelFace::draw()
{
updateCopyTexButton();
+ // grab media name/title and update the UI widget
+ // Todo: move it, it's preferable not to update
+ // labels inside draw
+ updateMediaTitle();
+
LLPanel::draw();
}
@@ -824,21 +838,20 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- getChildView("button align")->setEnabled(editable);
+ childSetEnabled("button align", editable);
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
- if (combobox_matmedia)
+ if (mComboMatMedia)
{
- if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
+ if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL)
{
- combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
}
+ mComboMatMedia->setEnabled(editable);
}
else
{
LL_WARNS() << "failed getChild for 'combobox matmedia'" << LL_ENDL;
}
- getChildView("combobox matmedia")->setEnabled(editable);
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
if(radio_mat_type)
@@ -847,7 +860,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
}
-
}
else
{
@@ -876,22 +888,22 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
getChildView("color label")->setEnabled(editable);
}
- LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch");
LLColor4 color = LLColor4::white;
bool identical_color = false;
- if(mColorSwatch)
+ if(color_swatch)
{
LLSelectedTE::getColor(color, identical_color);
- LLColor4 prev_color = mColorSwatch->get();
+ LLColor4 prev_color = color_swatch->get();
- mColorSwatch->setOriginal(color);
- mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable);
+ color_swatch->setOriginal(color);
+ color_swatch->set(color, force_set_values || (prev_color != color) || !editable);
- mColorSwatch->setValid(editable);
- mColorSwatch->setEnabled( editable );
- mColorSwatch->setCanApplyImmediately( editable );
+ color_swatch->setValid(editable);
+ color_swatch->setEnabled( editable );
+ color_swatch->setCanApplyImmediately( editable );
}
// Color transparency
@@ -1374,7 +1386,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL identical_repeats = true;
F32 repeats = 1.0f;
- U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
+ U32 material_type = (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
switch (material_type)
@@ -1606,6 +1618,755 @@ void LLPanelFace::refresh()
getState();
}
+void LLPanelFace::refreshMedia()
+{
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject* first_object = selected_objects->getFirstObject();
+
+ if (!(first_object
+ && first_object->getPCode() == LL_PCODE_VOLUME
+ && first_object->permModify()
+ ))
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ mTitleMediaText->clear();
+ clearMediaSettings();
+ return;
+ }
+
+ std::string url = first_object->getRegion()->getCapability("ObjectMedia");
+ bool has_media_capability = (!url.empty());
+
+ if (!has_media_capability)
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
+ clearMediaSettings();
+ return;
+ }
+
+ BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
+ bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
+
+ // Check modify permissions and whether any selected objects are in
+ // the process of being fetched. If they are, then we're not editable
+ if (editable)
+ {
+ LLObjectSelection::iterator iter = selected_objects->begin();
+ LLObjectSelection::iterator end = selected_objects->end();
+ for (; iter != end; ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
+ if (NULL != object)
+ {
+ if (!object->permModify())
+ {
+ LL_INFOS("LLFloaterToolsMedia")
+ << "Selection not editable due to lack of modify permissions on object id "
+ << object->getID() << LL_ENDL;
+
+ editable = false;
+ break;
+ }
+ }
+ }
+ }
+
+ // Media settings
+ bool bool_has_media = false;
+ struct media_functor : public LLSelectedTEGetFunctor<bool>
+ {
+ bool get(LLViewerObject* object, S32 face)
+ {
+ LLTextureEntry *te = object->getTE(face);
+ if (te)
+ {
+ return te->hasMedia();
+ }
+ return false;
+ }
+ } func;
+
+
+ // check if all faces have media(or, all dont have media)
+ LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media);
+
+ const LLMediaEntry default_media_data;
+
+ struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
+ {
+ functor_getter_media_data(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ LLMediaEntry get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return *(object->getTE(face)->getMediaData());
+ return mMediaEntry;
+ };
+
+ const LLMediaEntry& mMediaEntry;
+
+ } func_media_data(default_media_data);
+
+ LLMediaEntry media_data_get;
+ LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get));
+
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ std::string media_title = "";
+ // update UI depending on whether "object" (prim or face) has media
+ // and whether or not you are allowed to edit it.
+
+ getChildView("add_media")->setEnabled(editable);
+ // IF all the faces have media (or all dont have media)
+ if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo)
+ {
+ // TODO: get media title and set it.
+ mTitleMediaText->clear();
+ // if identical is set, all faces are same (whether all empty or has the same media)
+ if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia))
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ // else all faces might be empty.
+ }
+ else // there' re Different Medias' been set on on the faces.
+ {
+ media_title = multi_media_info_str;
+ }
+
+ getChildView("delete_media")->setEnabled(bool_has_media && editable);
+ // TODO: display a list of all media on the face - use 'identical' flag
+ }
+ else // not all face has media but at least one does.
+ {
+ // seleted faces have not identical value
+ LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data);
+
+ if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
+ {
+ media_title = multi_media_info_str;
+ }
+ else
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ }
+
+ getChildView("delete_media")->setEnabled(TRUE);
+ }
+
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
+ if (materials_media == MATMEDIA_MEDIA)
+ {
+ // currently displaying media info, navigateTo and update title
+ navigateToTitleMedia(media_title);
+ }
+ else
+ {
+ // Media can be heavy, don't keep it around
+ // MAC specific: MAC doesn't support setVolume(0) so if not
+ // unloaded, it might keep playing audio until user closes editor
+ unloadMedia();
+ mNeedMediaTitle = false;
+ }
+
+ mTitleMediaText->setText(media_title);
+
+ // load values for media settings
+ updateMediaSettings();
+
+ LLFloaterMediaSettings::initValues(mMediaSettings, editable);
+}
+
+void LLPanelFace::unloadMedia()
+{
+ // destroy media source used to grab media title
+ if (mTitleMedia)
+ mTitleMedia->unloadMediaSource();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelFace::navigateToTitleMedia( const std::string url )
+{
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ if (url.empty() || multi_media_info_str == url)
+ {
+ // nothing to show
+ mNeedMediaTitle = false;
+ }
+ else if (mTitleMedia)
+ {
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ // check if url changed or if we need a new media source
+ if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
+ {
+ mTitleMedia->navigateTo( url );
+
+ LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID());
+ if (impl)
+ {
+ // if it's a page with a movie, we don't want to hear it
+ impl->setVolume(0);
+ };
+ }
+
+ // flag that we need to update the title (even if no request were made)
+ mNeedMediaTitle = true;
+ }
+}
+
+bool LLPanelFace::selectedMediaEditable()
+{
+ U32 owner_mask_on;
+ U32 owner_mask_off;
+ U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
+ &owner_mask_on, &owner_mask_off);
+ U32 group_mask_on;
+ U32 group_mask_off;
+ U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
+ &group_mask_on, &group_mask_off);
+ U32 everyone_mask_on;
+ U32 everyone_mask_off;
+ S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
+ &everyone_mask_on, &everyone_mask_off);
+
+ bool selected_Media_editable = false;
+
+ // if perms we got back are valid
+ if (valid_owner_perms &&
+ valid_group_perms &&
+ valid_everyone_perms)
+ {
+
+ if ((owner_mask_on & PERM_MODIFY) ||
+ (group_mask_on & PERM_MODIFY) ||
+ (everyone_mask_on & PERM_MODIFY))
+ {
+ selected_Media_editable = true;
+ }
+ else
+ // user is NOT allowed to press the RESET button
+ {
+ selected_Media_editable = false;
+ };
+ };
+
+ return selected_Media_editable;
+}
+
+void LLPanelFace::clearMediaSettings()
+{
+ LLFloaterMediaSettings::clearValues(false);
+}
+
+void LLPanelFace::updateMediaSettings()
+{
+ bool identical(false);
+ std::string base_key("");
+ std::string value_str("");
+ int value_int = 0;
+ bool value_bool = false;
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ // TODO: (CP) refactor this using something clever or boost or both !!
+
+ const LLMediaEntry default_media_data;
+
+ // controls
+ U8 value_u8 = default_media_data.getControls();
+ struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
+ {
+ functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
+
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getControls();
+ return mMediaEntry.getControls();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_controls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_controls, value_u8);
+ base_key = std::string(LLMediaEntry::CONTROLS_KEY);
+ mMediaSettings[base_key] = value_u8;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // First click (formerly left click)
+ value_bool = default_media_data.getFirstClickInteract();
+ struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_first_click(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getFirstClickInteract();
+ return mMediaEntry.getFirstClickInteract();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_first_click(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_first_click, value_bool);
+ base_key = std::string(LLMediaEntry::FIRST_CLICK_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Home URL
+ value_str = default_media_data.getHomeURL();
+ struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_home_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHomeURL();
+ return mMediaEntry.getHomeURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_home_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_home_url, value_str);
+ base_key = std::string(LLMediaEntry::HOME_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Current URL
+ value_str = default_media_data.getCurrentURL();
+ struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_current_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getCurrentURL();
+ return mMediaEntry.getCurrentURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_current_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_current_url, value_str);
+ base_key = std::string(LLMediaEntry::CURRENT_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto zoom
+ value_bool = default_media_data.getAutoZoom();
+ struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
+ {
+
+ functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoZoom();
+ return mMediaEntry.getAutoZoom();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_zoom(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_zoom, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_ZOOM_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto play
+ //value_bool = default_media_data.getAutoPlay();
+ // set default to auto play TRUE -- angela EXT-5172
+ value_bool = true;
+ struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoPlay();
+ //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_play(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_play, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_PLAY_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+
+ // Auto scale
+ // set default to auto scale TRUE -- angela EXT-5172
+ //value_bool = default_media_data.getAutoScale();
+ value_bool = true;
+ struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_scale(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoScale();
+ // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_scale(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_scale, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_SCALE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto loop
+ value_bool = default_media_data.getAutoLoop();
+ struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoLoop();
+ return mMediaEntry.getAutoLoop();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_loop(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_loop, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_LOOP_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // width pixels (if not auto scaled)
+ value_int = default_media_data.getWidthPixels();
+ struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_width_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWidthPixels();
+ return mMediaEntry.getWidthPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_width_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_width_pixels, value_int);
+ base_key = std::string(LLMediaEntry::WIDTH_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // height pixels (if not auto scaled)
+ value_int = default_media_data.getHeightPixels();
+ struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHeightPixels();
+ return mMediaEntry.getHeightPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_height_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_height_pixels, value_int);
+ base_key = std::string(LLMediaEntry::HEIGHT_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Enable Alt image
+ value_bool = default_media_data.getAltImageEnable();
+ struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_enable_alt_image(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAltImageEnable();
+ return mMediaEntry.getAltImageEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_enable_alt_image(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_enable_alt_image, value_bool);
+ base_key = std::string(LLMediaEntry::ALT_IMAGE_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_interact(default_media_data);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func_perms_anyone_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_anyone_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist enable
+ value_bool = default_media_data.getWhiteListEnable();
+ struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteListEnable();
+ return mMediaEntry.getWhiteListEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_enable(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_enable, value_bool);
+ base_key = std::string(LLMediaEntry::WHITELIST_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist URLs
+ std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
+ struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
+ {
+ functor_getter_whitelist_urls(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::vector<std::string> get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteList();
+ return mMediaEntry.getWhiteList();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_urls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_urls, value_vector_str);
+ base_key = std::string(LLMediaEntry::WHITELIST_KEY);
+ mMediaSettings[base_key].clear();
+ std::vector< std::string >::iterator iter = value_vector_str.begin();
+ while (iter != value_vector_str.end())
+ {
+ std::string white_list_url = *iter;
+ mMediaSettings[base_key].append(white_list_url);
+ ++iter;
+ };
+
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+}
+
+void LLPanelFace::updateMediaTitle()
+{
+ // only get the media name if we need it
+ if (!mNeedMediaTitle)
+ return;
+
+ // get plugin impl
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ if (media_plugin && mTitleMedia->getCurrentNavUrl() == media_plugin->getNavigateURI())
+ {
+ // get the media name (asynchronous - must call repeatedly)
+ std::string media_title = media_plugin->getMediaName();
+
+ // only replace the title if what we get contains something
+ if (!media_title.empty())
+ {
+ // update the UI widget
+ if (mTitleMediaText)
+ {
+ mTitleMediaText->setText(media_title);
+
+ // stop looking for a title when we get one
+ mNeedMediaTitle = false;
+ };
+ };
+ };
+}
+
//
// Static functions
//
@@ -1664,30 +2425,29 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
self->updateShinyControls(false,true);
self->updateBumpyControls(false,true);
self->updateUI();
+ self->refreshMedia();
}
-// static
void LLPanelFace::updateVisibility()
{
- LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess");
LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness");
- if (!radio_mat_type || !combo_matmedia || !combo_shininess || !combo_bumpiness)
+ if (!radio_mat_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
{
LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
return;
}
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled()));
- bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
+ bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
getChildView("radio_material_type")->setVisible(!show_media);
// Media controls
- getChildView("media_info")->setVisible(show_media);
+ mTitleMediaText->setVisible(show_media);
getChildView("add_media")->setVisible(show_media);
getChildView("delete_media")->setVisible(show_media);
getChildView("button align")->setVisible(show_media);
@@ -1819,12 +2579,11 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh
}
- LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
U32 shiny_value = comboShiny->getCurrentIndex();
bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
getChildView("label glossiness")->setVisible(show_shinyctrls);
@@ -1898,11 +2657,10 @@ void LLPanelFace::updateAlphaControls()
U32 alpha_value = comboAlphaMode->getCurrentIndex();
bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
U32 mat_media = MATMEDIA_MATERIAL;
- if (combobox_matmedia)
+ if (mComboMatMedia)
{
- mat_media = combobox_matmedia->getCurrentIndex();
+ mat_media = mComboMatMedia->getCurrentIndex();
}
U32 mat_type = MATTYPE_DIFFUSE;
@@ -2059,6 +2817,77 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data)
sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
}
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to edit existing media settings on a prim or prim face
+// TODO: test if there is media on the item and only allow editing if present
+void LLPanelFace::onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLFloaterReg::showInstance("media_settings");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to delete media from a prim or prim face
+void LLPanelFace::onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to add media to a prim or prim face
+void LLPanelFace::onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata)
+{
+ // check if multiple faces are selected
+ if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ {
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
+ }
+ else
+ {
+ onClickBtnEditMedia(ctrl, userdata);
+ }
+}
+
+// static
+bool LLPanelFace::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLSelectMgr::getInstance()->selectionSetMedia(0, LLSD());
+ if (LLFloaterReg::instanceVisible("media_settings"))
+ {
+ LLFloaterReg::hideInstance("media_settings");
+ }
+ break;
+
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+// static
+bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLFloaterReg::showInstance("media_settings");
+ break;
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
//static
void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU)
{
@@ -2436,10 +3265,9 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
LLPanelFace* self = (LLPanelFace*) userdata;
LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
- LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = self->mComboMatMedia->getCurrentIndex();
U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : 0;
F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
@@ -3375,14 +4203,6 @@ bool LLPanelFace::menuEnableItem(const LLSD& userdata)
}
-// TODO: I don't know who put these in or what these are for???
-void LLPanelFace::setMediaURL(const std::string& url)
-{
-}
-void LLPanelFace::setMediaType(const std::string& mime_type)
-{
-}
-
// static
void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
{
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index e3b925c1d4..44bc442bbb 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -47,6 +47,7 @@ class LLUICtrl;
class LLViewerObject;
class LLFloater;
class LLMaterialID;
+class LLMediaCtrl;
class LLMenuButton;
// Represents an edit for use in replicating the op across one or more materials in the selection set.
@@ -97,11 +98,11 @@ public:
LLPanelFace();
virtual ~LLPanelFace();
- void draw();
-
void refresh();
- void setMediaURL(const std::string& url);
- void setMediaType(const std::string& mime_type);
+ void refreshMedia();
+ void unloadMedia();
+
+ /*virtual*/ void draw();
LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
{
@@ -117,6 +118,12 @@ public:
LLRender::eTexIndex getTextureChannelToEdit();
protected:
+ void navigateToTitleMedia(const std::string url);
+ bool selectedMediaEditable();
+ void clearMediaSettings();
+ void updateMediaSettings();
+ void updateMediaTitle();
+
void getState();
void sendTexture(); // applies and sends texture
@@ -155,6 +162,9 @@ protected:
void onCloseTexturePicker(const LLSD& data);
+ static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
+ static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
+
// Make UI reflect state of currently selected material (refresh)
// and UI mode (e.g. editing normal map v diffuse map)
//
@@ -199,6 +209,9 @@ protected:
static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata);
static void onCommitBump( LLUICtrl* ctrl, void* userdata);
static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
@@ -251,6 +264,10 @@ private:
F32 getCurrentShinyOffsetU();
F32 getCurrentShinyOffsetV();
+ LLComboBox *mComboMatMedia;
+ LLMediaCtrl *mTitleMedia;
+ LLTextBox *mTitleMediaText;
+
// Update visibility of controls to match current UI mode
// (e.g. materials vs media editing)
//
@@ -258,10 +275,6 @@ private:
//
void updateVisibility();
- // Make material(s) reflect current state of UI (apply edit)
- //
- void updateMaterial();
-
// Hey look everyone, a type-safe alternative to copy and paste! :)
//
@@ -439,6 +452,9 @@ private:
LLSD mClipboardParams;
+ LLSD mMediaSettings;
+ bool mNeedMediaTitle;
+
public:
#if defined(DEF_GET_MAT_STATE)
#undef DEF_GET_MAT_STATE
diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp
index e7bdc51b4a..9e3fc54477 100644
--- a/indra/newview/llpanellandaudio.cpp
+++ b/indra/newview/llpanellandaudio.cpp
@@ -97,6 +97,9 @@ BOOL LLPanelLandAudio::postBuild()
mCheckAVSoundGroup = getChild<LLCheckBoxCtrl>("group av sound check");
childSetCommitCallback("group av sound check", onCommitAny, this);
+ mCheckObscureMOAP = getChild<LLCheckBoxCtrl>("obscure_moap");
+ childSetCommitCallback("obscure_moap", onCommitAny, this);
+
return TRUE;
}
@@ -157,6 +160,9 @@ void LLPanelLandAudio::refresh()
mCheckAVSoundGroup->set(parcel->getAllowGroupAVSounds() || parcel->getAllowAnyAVSounds()); // On if "Everyone" is on
mCheckAVSoundGroup->setEnabled(can_change_av_sounds && !parcel->getAllowAnyAVSounds()); // Enabled if "Everyone" is off
+
+ mCheckObscureMOAP->set(parcel->getObscureMOAP());
+ mCheckObscureMOAP->setEnabled(can_change_media);
}
}
// static
@@ -184,6 +190,8 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
group_av_sound = self->mCheckAVSoundGroup->get();
}
+ bool obscure_moap = self->mCheckObscureMOAP->get();
+
// Remove leading/trailing whitespace (common when copying/pasting)
LLStringUtil::trim(music_url);
@@ -194,6 +202,7 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
parcel->setMusicURL(music_url);
parcel->setAllowAnyAVSounds(any_av_sound);
parcel->setAllowGroupAVSounds(group_av_sound);
+ parcel->setObscureMOAP(obscure_moap);
// Send current parcel data upstream to server
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h
index 7e4fce80e4..b54fe62179 100644
--- a/indra/newview/llpanellandaudio.h
+++ b/indra/newview/llpanellandaudio.h
@@ -53,6 +53,7 @@ private:
LLLineEditor* mMusicURLEdit;
LLCheckBoxCtrl* mCheckAVSoundAny;
LLCheckBoxCtrl* mCheckAVSoundGroup;
+ LLCheckBoxCtrl* mCheckObscureMOAP;
LLSafeHandle<LLParcelSelection>& mParcel;
};
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 9730f0f16d..e1818cc68b 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -98,9 +98,6 @@ BOOL LLPanelMediaSettingsGeneral::postBuild()
childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this);
- // interrogates controls and updates widgets as required
- updateMediaPreview();
-
return true;
}
@@ -313,9 +310,6 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
-
- // interrogates controls and updates widgets as required
- self->updateMediaPreview();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 29c9329a26..f4eaa78f11 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -61,6 +61,7 @@
#include "llcommandhandler.h"
#include "llfloaterprofiletexture.h"
#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
#include "llgroupactions.h"
@@ -582,6 +583,22 @@ public:
}
return true;
}
+
+ // reportAbuse is here due to convoluted avatar handling
+ // in LLScrollListCtrl and LLTextBase
+ if (verb == "reportAbuse" && web == NULL)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(avatar_id, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable");
+ }
+ return true;
+ }
return false;
}
};
@@ -887,8 +904,6 @@ BOOL LLPanelProfileSecondLife::postBuild()
mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
- getChild<LLButton>("open_notes")->setCommitCallback([this](LLUICtrl*, void*) { onOpenNotes(); }, nullptr);
-
mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
@@ -1938,23 +1953,6 @@ void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id)
}
}
-void LLPanelProfileSecondLife::onOpenNotes()
-{
- LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- if (!parent_floater)
- {
- return;
- }
-
- LLTabContainer* tab_container = parent_floater->findChild<LLTabContainer>("panel_profile_tabs", TRUE);
- if (!tab_container)
- {
- return;
- }
-
- tab_container->selectTabByName(PANEL_NOTES);
-}
-
//////////////////////////////////////////////////////////////////////////
// LLPanelProfileWeb
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index ca6ef3f794..d32bb943bd 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -184,7 +184,6 @@ private:
void onShowAgentProfileTexture();
void onShowTexturePicker();
void onCommitProfileImage(const LLUUID& id);
- void onOpenNotes();
private:
typedef std::map<std::string, LLUUID> group_map_t;
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 5b02609a53..39f4c7485b 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -595,13 +595,6 @@ void LLPanelVolume::refresh()
mRootObject = NULL;
}
- BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE;
-
- getChildView("Light FOV")->setVisible( visible);
- getChildView("Light Focus")->setVisible( visible);
- getChildView("Light Ambiance")->setVisible( visible);
- getChildView("light texture control")->setVisible( visible);
-
bool enable_mesh = false;
LLSD sim_features;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 94d20828ec..9b60d1ae2f 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -38,154 +38,11 @@
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
-// See EXT-4301.
-/**
- * class LLAvalineUpdater - observe the list of voice participants in session and check
- * presence of Avaline Callers among them.
- *
- * LLAvalineUpdater is a LLVoiceClientParticipantObserver. It provides two kinds of validation:
- * - whether Avaline caller presence among participants;
- * - whether watched Avaline caller still exists in voice channel.
- * Both validations have callbacks which will notify subscriber if any of event occur.
- *
- * @see findAvalineCaller()
- * @see checkIfAvalineCallersExist()
- */
-class LLAvalineUpdater : public LLVoiceClientParticipantObserver
-{
-public:
- typedef boost::function<void(const LLUUID& speaker_id)> process_avaline_callback_t;
-
- LLAvalineUpdater(process_avaline_callback_t found_cb, process_avaline_callback_t removed_cb)
- : mAvalineFoundCallback(found_cb)
- , mAvalineRemovedCallback(removed_cb)
- {
- LLVoiceClient::getInstance()->addObserver(this);
- }
- ~LLAvalineUpdater()
- {
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
- }
-
- /**
- * Adds UUID of Avaline caller to watch.
- *
- * @see checkIfAvalineCallersExist().
- */
- void watchAvalineCaller(const LLUUID& avaline_caller_id)
- {
- mAvalineCallers.insert(avaline_caller_id);
- }
-
- void onParticipantsChanged()
- {
- uuid_set_t participant_uuids;
- LLVoiceClient::getInstance()->getParticipantList(participant_uuids);
-
-
- // check whether Avaline caller exists among voice participants
- // and notify Participant List
- findAvalineCaller(participant_uuids);
-
- // check whether watched Avaline callers still present among voice participant
- // and remove if absents.
- checkIfAvalineCallersExist(participant_uuids);
- }
-
-private:
- typedef std::set<LLUUID> uuid_set_t;
-
- /**
- * Finds Avaline callers among voice participants and calls mAvalineFoundCallback.
- *
- * When Avatar is in group call with Avaline caller and then ends call Avaline caller stays
- * in Group Chat floater (exists in LLSpeakerMgr). If Avatar starts call with that group again
- * Avaline caller is added to voice channel AFTER Avatar is connected to group call.
- * But Voice Control Panel (VCP) is filled from session LLSpeakerMgr and there is no information
- * if a speaker is Avaline caller.
- *
- * In this case this speaker is created as avatar and will be recreated when it appears in
- * Avatar's Voice session.
- *
- * @see LLParticipantList::onAvalineCallerFound()
- */
- void findAvalineCaller(const uuid_set_t& participant_uuids)
- {
- uuid_set_t::const_iterator it = participant_uuids.begin(), it_end = participant_uuids.end();
-
- for(; it != it_end; ++it)
- {
- const LLUUID& participant_id = *it;
- if (!LLVoiceClient::getInstance()->isParticipantAvatar(participant_id))
- {
- LL_DEBUGS("Avaline") << "Avaline caller found among voice participants: " << participant_id << LL_ENDL;
-
- if (mAvalineFoundCallback)
- {
- mAvalineFoundCallback(participant_id);
- }
- }
- }
- }
-
- /**
- * Finds Avaline callers which are not anymore among voice participants and calls mAvalineRemovedCallback.
- *
- * The problem is when Avaline caller ends a call it is removed from Voice Client session but
- * still exists in LLSpeakerMgr. Server does not send such information.
- * This method implements a HUCK to notify subscribers that watched Avaline callers by class
- * are not anymore in the call.
- *
- * @see LLParticipantList::onAvalineCallerRemoved()
- */
- void checkIfAvalineCallersExist(const uuid_set_t& participant_uuids)
- {
- uuid_set_t::iterator it = mAvalineCallers.begin();
- uuid_set_t::const_iterator participants_it_end = participant_uuids.end();
-
- while (it != mAvalineCallers.end())
- {
- const LLUUID participant_id = *it;
- LL_DEBUGS("Avaline") << "Check avaline caller: " << participant_id << LL_ENDL;
- bool not_found = participant_uuids.find(participant_id) == participants_it_end;
- if (not_found)
- {
- LL_DEBUGS("Avaline") << "Watched Avaline caller is not found among voice participants: " << participant_id << LL_ENDL;
-
- // notify Participant List
- if (mAvalineRemovedCallback)
- {
- mAvalineRemovedCallback(participant_id);
- }
-
- // remove from the watch list
- mAvalineCallers.erase(it++);
- }
- else
- {
- ++it;
- }
- }
- }
-
- process_avaline_callback_t mAvalineFoundCallback;
- process_avaline_callback_t mAvalineRemovedCallback;
-
- uuid_set_t mAvalineCallers;
-};
-
LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) :
LLConversationItemSession(data_source->getSessionID(), root_view_model),
mSpeakerMgr(data_source),
mValidateSpeakerCallback(NULL)
{
-
- mAvalineUpdater = new LLAvalineUpdater(boost::bind(&LLParticipantList::onAvalineCallerFound, this, _1),
- boost::bind(&LLParticipantList::onAvalineCallerRemoved, this, _1));
-
mSpeakerAddListener = new SpeakerAddListener(*this);
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
mSpeakerClearListener = new SpeakerClearListener(*this);
@@ -243,32 +100,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewMode
LLParticipantList::~LLParticipantList()
{
- delete mAvalineUpdater;
-}
-
-/*
- Seems this method is not necessary after onAvalineCallerRemoved was implemented;
-
- It does nothing because list item is always created with correct class type for Avaline caller.
- For now Avaline Caller is removed from the LLSpeakerMgr List when it is removed from the Voice Client
- session.
- This happens in two cases: if Avaline Caller ends call itself or if Resident ends group call.
-
- Probably Avaline caller should be removed from the LLSpeakerMgr list ONLY if it ends call itself.
- Asked in EXT-4301.
-*/
-void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
-{
- removeParticipant(participant_id);
- // re-add avaline caller with a correct class instance.
- addAvatarIDExceptAgent(participant_id);
-}
-
-void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
-{
- LL_DEBUGS("Avaline") << "Removing avaline caller from the list: " << participant_id << LL_ENDL;
-
- mSpeakerMgr->removeAvalineSpeaker(participant_id);
}
void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
@@ -386,7 +217,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
// Create a participant view model instance
participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
- mAvalineUpdater->watchAvalineCaller(avatar_id);
}
// *TODO : Need to update the online/offline status of the participant
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 3a3ae76604..14c0a63692 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -32,7 +32,6 @@
class LLSpeakerMgr;
class LLUICtrl;
-class LLAvalineUpdater;
class LLParticipantList : public LLConversationItemSession
{
@@ -133,8 +132,6 @@ protected:
};
private:
- void onAvalineCallerFound(const LLUUID& participant_id);
- void onAvalineCallerRemoved(const LLUUID& participant_id);
/**
* Adjusts passed participant to work properly.
@@ -156,7 +153,6 @@ private:
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
validate_speaker_callback_t mValidateSpeakerCallback;
- LLAvalineUpdater* mAvalineUpdater;
};
#endif // LL_PARTICIPANTLIST_H
diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp
index 6e3e375488..a7011dfad5 100644
--- a/indra/newview/llpatchvertexarray.cpp
+++ b/indra/newview/llpatchvertexarray.cpp
@@ -69,11 +69,9 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p
// (The -1 is there because an LLSurface has a buffer of 1 on
// its East and North edges).
U32 power_of_two = 1;
- U32 surface_order = 0;
while (power_of_two < (surface_width-1))
{
power_of_two *= 2;
- surface_order += 1;
}
if (power_of_two == (surface_width-1))
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 9bc77393dc..9bf771db8a 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -163,12 +163,16 @@ void LLPersistentNotificationStorage::loadNotifications()
LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
}
-void LLPersistentNotificationStorage::initialize()
+void LLPersistentNotificationStorage::reset()
{
- std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml";
- setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name));
- setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+ std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml";
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name));
+ setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+}
+void LLPersistentNotificationStorage::initialize()
+{
+ reset();
LLNotifications::instance().getChannel("Persistent")->
connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
}
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
index 1fb4487286..335d85aaf6 100644
--- a/indra/newview/llpersistentnotificationstorage.h
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -52,6 +52,7 @@ public:
void saveNotifications();
void loadNotifications();
+ void reset();
protected:
diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp
index 5bfe5c9941..9603ee6329 100644
--- a/indra/newview/llphysicsshapebuilderutil.cpp
+++ b/indra/newview/llphysicsshapebuilderutil.cpp
@@ -29,7 +29,7 @@
#include "llphysicsshapebuilderutil.h"
/* static */
-void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut )
+void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut)
{
const LLProfileParams& profile_params = volume_params.getProfileParams();
const LLPathParams& path_params = volume_params.getPathParams();
@@ -191,6 +191,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
if ( volume_params.shouldForceConvex() )
{
+ // Server distinguishes between convex of a prim vs isSculpt, but we don't care.
specOut.mType = PhysicsShapeSpecification::USER_CONVEX;
}
// Make a simpler convex shape if we can.
@@ -199,6 +200,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
{
specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;
}
+ else if (volume_params.isMeshSculpt() &&
+ // Check overall dimensions, not individual triangles.
+ (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ||
+ scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ||
+ scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE
+ ) )
+ {
+ // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't.
+ specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;
+ }
else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy)
{
specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT;
diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h
index bd5b7d799c..b3b100296f 100644
--- a/indra/newview/llphysicsshapebuilderutil.h
+++ b/indra/newview/llphysicsshapebuilderutil.h
@@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f;
const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f;
const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE;
const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE;
+const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f;
class LLPhysicsVolumeParams : public LLVolumeParams
{
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index c267c3c699..30d0a22ef0 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -332,7 +332,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
else
{
ECameraPreset new_camera_preset = (ECameraPreset)gSavedSettings.getU32("CameraPresetType");
- bool new_camera_offsets = false;
if (IS_CAMERA)
{
if (isDefaultCameraPreset(name))
@@ -354,7 +353,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
{
new_camera_preset = CAMERA_PRESET_CUSTOM;
}
- new_camera_offsets = (!isDefaultCameraPreset(name) || (ECameraPreset)gSavedSettings.getU32("CameraPresetType") != new_camera_preset);
}
for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
{
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 230def5362..3fd4f51559 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -866,7 +866,10 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
buffer[nread] = '\0';
fclose(file);
- mEditor->setText(LLStringExplicit(buffer));
+ std::string text = std::string(buffer);
+ LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab());
+
+ mEditor->setText(text);
delete[] buffer;
return true;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index a32dc8beda..d677a996c1 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -601,7 +601,10 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)
buffer[nread] = '\0';
fclose(file);
- mEditor->setText(LLStringExplicit(buffer));
+ std::string text = std::string(buffer);
+ LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab());
+
+ mEditor->setText(text);
delete[] buffer;
return true;
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 83b0c4f1bf..0faf6bf889 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -42,14 +42,6 @@ bool LLRecentPeople::add(const LLUUID& id, const LLSD& userdata)
if (is_not_group_id)
{
- // For each avaline call the id of caller is different even if
- // the phone number is the same.
- // To avoid duplication of avaline list items in the recent list
- // of panel People, deleting id's with similar phone number.
- const LLUUID& caller_id = getIDByPhoneNumber(userdata);
- if (caller_id.notNull())
- mPeople.erase(caller_id);
-
//[] instead of insert to replace existing id->llsd["date"] with new date value
mPeople[id] = userdata;
mChangedSignal();
@@ -90,35 +82,6 @@ const LLSD& LLRecentPeople::getData(const LLUUID& id) const
return no_data;
}
-bool LLRecentPeople::isAvalineCaller(const LLUUID& id) const
-{
- recent_people_t::const_iterator it = mPeople.find(id);
-
- if (it != mPeople.end())
- {
- const LLSD& user = it->second;
- return user["avaline_call"].asBoolean();
- }
-
- return false;
-}
-
-const LLUUID& LLRecentPeople::getIDByPhoneNumber(const LLSD& userdata)
-{
- if (!userdata["avaline_call"].asBoolean())
- return LLUUID::null;
-
- for (recent_people_t::const_iterator it = mPeople.begin(); it != mPeople.end(); ++it)
- {
- const LLSD& user_info = it->second;
-
- if (user_info["call_number"].asString() == userdata["call_number"].asString())
- return it->first;
- }
-
- return LLUUID::null;
-}
-
// virtual
bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index 18b669ff4f..1b322f2c0a 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -62,9 +62,7 @@ public:
* @param id avatar to add.
*
* @param userdata additional information about last interaction party.
- * For example when last interaction party is not an avatar
- * but an avaline caller, additional info (such as phone
- * number, session id and etc.) should be added.
+ * For example session id can be added.
*
* @return false if the avatar is in the list already, true otherwise
*/
@@ -97,13 +95,6 @@ public:
const LLSD& getData(const LLUUID& id) const;
/**
- * Checks whether specific participant is an avaline caller
- *
- * @param id identifier of specific participant
- */
- bool isAvalineCaller(const LLUUID& id) const;
-
- /**
* Set callback to be called when the list changed.
*
* Multiple callbacks can be set.
@@ -122,8 +113,6 @@ public:
private:
- const LLUUID& getIDByPhoneNumber(const LLSD& userdata);
-
typedef std::map<LLUUID, LLSD> recent_people_t;
recent_people_t mPeople;
signal_t mChangedSignal;
diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp
index f7aa63e34d..e250f9bc7a 100644
--- a/indra/newview/llsceneview.cpp
+++ b/indra/newview/llsceneview.cpp
@@ -266,14 +266,11 @@ void LLSceneView::draw()
U32 count = triangles[idx].size();
- U32 total = 0;
-
gGL.begin(LLRender::LINE_STRIP);
//plot triangles
for (U32 i = 0; i < count; ++i)
{
U32 tri_count = triangles[idx][i];
- total += tri_count;
F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom;
F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft;
@@ -290,15 +287,8 @@ void LLSceneView::draw()
gGL.end();
gGL.flush();
- U32 total_visible = 0;
count = visible_triangles[idx].size();
- for (U32 i = 0; i < count; ++i)
- {
- U32 tri_count = visible_triangles[idx][i];
- total_visible += tri_count;
- }
-
std::string label = llformat("%s Object Triangle Counts (Ktris) -- Visible: %.2f/%.2f (%.2f KB Visible)",
category[idx], total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, total_visible_bytes[idx]/1024.f);
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index e033cae3ab..31f11eb8ef 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -41,9 +41,9 @@ namespace ll
struct PanelData;
struct TabContainerData;
- typedef boost::shared_ptr< SearchableItem > SearchableItemPtr;
- typedef boost::shared_ptr< PanelData > PanelDataPtr;
- typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr;
+ typedef std::shared_ptr< SearchableItem > SearchableItemPtr;
+ typedef std::shared_ptr< PanelData > PanelDataPtr;
+ typedef std::shared_ptr< TabContainerData > TabContainerDataPtr;
typedef std::vector< TabContainerData > tTabContainerDataList;
typedef std::vector< SearchableItemPtr > tSearchableItemList;
@@ -55,7 +55,7 @@ namespace ll
LLView const *mView;
ll::ui::SearchableControl const *mCtrl;
- std::vector< boost::shared_ptr< SearchableItem > > mChildren;
+ std::vector< std::shared_ptr< SearchableItem > > mChildren;
virtual ~SearchableItem();
@@ -68,8 +68,8 @@ namespace ll
LLPanel const *mPanel;
std::string mLabel;
- std::vector< boost::shared_ptr< SearchableItem > > mChildren;
- std::vector< boost::shared_ptr< PanelData > > mChildPanel;
+ std::vector< std::shared_ptr< SearchableItem > > mChildren;
+ std::vector< std::shared_ptr< PanelData > > mChildPanel;
virtual ~PanelData();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 82a165cb35..86f7d2bf25 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -310,14 +310,29 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle)
{
struct f : public LLSelectedNodeFunctor
{
+ f(bool a, LLSelectMgr* p) : mAvatarOverridesPersist(a), mManager(p) {}
+ bool mAvatarOverridesPersist;
+ LLSelectMgr* mManager;
virtual bool apply(LLSelectNode* node)
{
+ if (mAvatarOverridesPersist)
+ {
+ LLViewerObject* object = node->getObject();
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ mManager->mAvatarOverridesMap.emplace(avatar->getID(), AvatarPositionOverride(node->mLastPositionLocal, node->mLastRotation, object));
+ }
+ }
+ }
node->mLastPositionLocal.setVec(0, 0, 0);
node->mLastRotation = LLQuaternion();
node->mLastScale.setVec(0, 0, 0);
return true;
}
- } func;
+ } func(mAllowSelectAvatar, this);
selected_handle->applyToNodes(&func);
}
@@ -351,6 +366,93 @@ void LLSelectMgr::overrideObjectUpdates()
getSelection()->applyToNodes(&func);
}
+void LLSelectMgr::resetAvatarOverrides()
+{
+ mAvatarOverridesMap.clear();
+}
+
+void LLSelectMgr::overrideAvatarUpdates()
+{
+ if (mAvatarOverridesMap.size() == 0)
+ {
+ return;
+ }
+
+ if (!mAllowSelectAvatar || !gFloaterTools)
+ {
+ resetAvatarOverrides();
+ return;
+ }
+
+ if (!gFloaterTools->getVisible() && getSelection()->isEmpty())
+ {
+ // when user switches selection, floater is invisible and selection is empty
+ LLToolset *toolset = LLToolMgr::getInstance()->getCurrentToolset();
+ if (toolset->isShowFloaterTools()
+ && toolset->isToolSelected(0)) // Pie tool
+ {
+ resetAvatarOverrides();
+ return;
+ }
+ }
+
+ // remove selected avatars from this list,
+ // but set object overrides to make sure avatar won't snap back
+ struct f : public LLSelectedNodeFunctor
+ {
+ f(LLSelectMgr* p) : mManager(p) {}
+ LLSelectMgr* mManager;
+ virtual bool apply(LLSelectNode* selectNode)
+ {
+ LLViewerObject* object = selectNode->getObject();
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ uuid_av_override_map_t::iterator iter = mManager->mAvatarOverridesMap.find(avatar->getID());
+ if (iter != mManager->mAvatarOverridesMap.end())
+ {
+ if (selectNode->mLastPositionLocal.isExactlyZero())
+ {
+ selectNode->mLastPositionLocal = iter->second.mLastPositionLocal;
+ }
+ if (selectNode->mLastRotation == LLQuaternion())
+ {
+ selectNode->mLastRotation = iter->second.mLastRotation;
+ }
+ mManager->mAvatarOverridesMap.erase(iter);
+ }
+ }
+ }
+ return true;
+ }
+ } func(this);
+ getSelection()->applyToNodes(&func);
+
+ // Override avatar positions
+ uuid_av_override_map_t::iterator it = mAvatarOverridesMap.begin();
+ while (it != mAvatarOverridesMap.end())
+ {
+ if (it->second.mObject->isDead())
+ {
+ it = mAvatarOverridesMap.erase(it);
+ }
+ else
+ {
+ if (!it->second.mLastPositionLocal.isExactlyZero())
+ {
+ it->second.mObject->setPosition(it->second.mLastPositionLocal);
+ }
+ if (it->second.mLastRotation != LLQuaternion())
+ {
+ it->second.mObject->setRotation(it->second.mLastRotation);
+ }
+ it++;
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// Select just the object, not any other group members.
//-----------------------------------------------------------------------------
@@ -886,7 +988,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
// Can't select yourself
if (objectp->mID == gAgentID
- && !LLSelectMgr::getInstance()->mAllowSelectAvatar)
+ && !mAllowSelectAvatar)
{
continue;
}
@@ -6281,6 +6383,24 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
LLSelectNode::~LLSelectNode()
{
+ LLSelectMgr *manager = LLSelectMgr::getInstance();
+ if (manager->mAllowSelectAvatar
+ && (!mLastPositionLocal.isExactlyZero()
+ || mLastRotation != LLQuaternion()))
+ {
+ LLViewerObject* object = getObject(); //isDead() check
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ // Avatar was moved and needs to stay that way
+ manager->mAvatarOverridesMap.emplace(avatar->getID(), LLSelectMgr::AvatarPositionOverride(mLastPositionLocal, mLastRotation, object));
+ }
+ }
+ }
+
+
delete mPermissions;
mPermissions = NULL;
}
@@ -6788,6 +6908,10 @@ void LLSelectMgr::updateSelectionCenter()
const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection
// center (tractor beam)
+ // override any avatar updates received
+ // Works only if avatar was repositioned
+ // and edit floater is visible
+ overrideAvatarUpdates();
//override any object updates received
//for selected objects
overrideObjectUpdates();
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index ce0316e610..199141fc32 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -467,6 +467,30 @@ public:
void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
void overrideObjectUpdates();
+ void resetAvatarOverrides();
+ void overrideAvatarUpdates();
+
+ struct AvatarPositionOverride
+ {
+ AvatarPositionOverride();
+ AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) :
+ mLastPositionLocal(vec),
+ mLastRotation(quat),
+ mObject(obj)
+ {
+ }
+ LLVector3 mLastPositionLocal;
+ LLQuaternion mLastRotation;
+ LLPointer<LLViewerObject> mObject;
+ };
+
+ // Avatar overrides should persist even after selection
+ // was removed as long as edit floater is up
+ typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t;
+ uuid_av_override_map_t mAvatarOverridesMap;
+public:
+
+
// Returns the previous value of mForceSelection
BOOL setForceSelection(BOOL force);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 0d53950889..42cd1133a2 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1567,6 +1567,62 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
}
}
+// return false if drawable is rigged and:
+// - a linked rigged drawable has a different spatial group
+// - a linked rigged drawable face has the wrong draw order index
+bool check_rigged_group(LLDrawable* drawable)
+{
+ if (drawable->isState(LLDrawable::RIGGED))
+ {
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ LLDrawable* root = drawable->getRoot();
+
+ if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group)
+ {
+ llassert(false);
+ return false;
+ }
+
+ S32 last_draw_index = -1;
+ if (root->isState(LLDrawable::RIGGED))
+ {
+ for (auto& face : root->getFaces())
+ {
+ if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ {
+ llassert(false);
+ return false;
+ }
+ last_draw_index = face->getDrawOrderIndex();
+ }
+ }
+
+ for (auto& child : root->getVObj()->getChildren())
+ {
+ if (child->mDrawable->isState(LLDrawable::RIGGED))
+ {
+ for (auto& face : child->mDrawable->getFaces())
+ {
+ if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ {
+ llassert(false);
+ return false;
+ }
+ last_draw_index = face->getDrawOrderIndex();
+ }
+ }
+
+ if (child->mDrawable->getSpatialGroup() != group)
+ {
+ llassert(false);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
void renderOctree(LLSpatialGroup* group)
{
//render solid object bounding box, color
@@ -1611,6 +1667,9 @@ void renderOctree(LLSpatialGroup* group)
{
continue;
}
+
+ llassert(check_rigged_group(drawable));
+
if (!group->getSpatialPartition()->isBridge())
{
gGL.pushMatrix();
@@ -3028,7 +3087,7 @@ public:
}
- void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+ void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);
@@ -3070,7 +3129,7 @@ public:
}
gGL.begin(LLRender::TRIANGLES);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
iter != branch->getDataEnd();
++iter)
{
@@ -3164,14 +3223,14 @@ void renderRaycast(LLDrawable* drawablep)
{
F32 t = 1.f;
- if (!face.mOctree)
+ if (!face.getOctree())
{
((LLVolumeFace*) &face)->createOctree();
}
LLRenderOctreeRaycast render(start, dir, &t);
- render.traverse(face.mOctree);
+ render.traverse(face.getOctree());
}
gGL.popMatrix();
@@ -3787,7 +3846,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)
}
LL_ALIGN_PREFIX(16)
-class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry>
+class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>>
{
public:
LL_ALIGN_16(LLVector4a mStart);
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 6d3ef33801..f7bc9fb644 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -264,7 +264,7 @@ public:
return lhs->mAvatarp < rhs->mAvatarp;
}
- return lhs->mRenderOrder > rhs->mRenderOrder;
+ return lhs->mRenderOrder < rhs->mRenderOrder;
}
};
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index abb936c3e5..ea671a130e 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -534,7 +534,7 @@ void LLSpeakerMgr::updateSpeakerList()
}
else if (mSpeakers.size() == 0)
{
- // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list
+ // For all other session type (ad-hoc, P2P), we use the initial participants targets list
for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
{
// Add buddies if they are on line, add any other avatar.
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index d1dbf72fe9..ed795b5155 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -245,14 +245,6 @@ public:
bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
/**
- * Removes avaline speaker.
- *
- * This is a HACK due to server does not send information that Avaline caller ends call.
- * It can be removed when server is updated. See EXT-4301 for details
- */
- bool removeAvalineSpeaker(const LLUUID& speaker_id) { return removeSpeaker(speaker_id); }
-
- /**
* Initializes mVoiceModerated depend on LLSpeaker::mModeratorMutedVoice of agent's participant.
*
* Is used only to implement workaround to initialize mVoiceModerated on first join to group chat. See EXT-6937
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 142dc4c46e..054e9530d4 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -255,6 +255,7 @@ static bool mLoginStatePastUI = false;
static bool mBenefitsSuccessfullyInit = false;
const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds
+const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Give region 3 chances
std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
@@ -661,7 +662,7 @@ bool idle_startup()
#else
void* window_handle = NULL;
#endif
- bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle());
+ bool init = gAudiop->init(window_handle, LLAppViewer::instance()->getSecondLifeTitle());
if(init)
{
gAudiop->setMuted(TRUE);
@@ -927,6 +928,12 @@ bool idle_startup()
LLPersistentNotificationStorage::initParamSingleton();
LLDoNotDisturbNotificationStorage::initParamSingleton();
}
+ else
+ {
+ // reinitialize paths in case user switched grids or accounts
+ LLPersistentNotificationStorage::getInstance()->reset();
+ LLDoNotDisturbNotificationStorage::getInstance()->reset();
+ }
// Set PerAccountSettingsFile to the default value.
std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"));
@@ -1388,10 +1395,21 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
}
+ else if (regionp->capabilitiesError())
+ {
+ // Try to connect despite capabilities' error state
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
else
{
U32 num_retries = regionp->getNumSeedCapRetries();
- if (num_retries > 0)
+ if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN)
+ {
+ // Region will keep trying to get capabilities,
+ // but for now continue as if caps were granted
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
+ else if (num_retries > 0)
{
LLStringUtil::format_map_t args;
args["[NUMBER]"] = llformat("%d", num_retries + 1);
@@ -2385,6 +2403,11 @@ void login_callback(S32 option, void *userdata)
void show_release_notes_if_required()
{
static bool release_notes_shown = false;
+ // We happen to know that instantiating LLVersionInfo implicitly
+ // instantiates the LLEventMailDrop named "relnotes", which we (might) use
+ // below. If viewer release notes stop working, might be because that
+ // LLEventMailDrop got moved out of LLVersionInfo and hasn't yet been
+ // instantiated.
if (!release_notes_shown && (LLVersionInfo::instance().getChannelAndVersion() != gLastRunVersion)
&& LLVersionInfo::instance().getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds
&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index d4fc6f3de2..9403e73b87 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1042,7 +1042,8 @@ void LLTextureCache::setReadOnly(BOOL read_only)
mReadOnly = read_only ;
}
-//called in the main thread.
+// Called in the main thread.
+// Returns the unused amount of max_size if any
S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch)
{
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 3f7e8531fb..14fae8d035 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -50,6 +50,10 @@
#include "llpreviewnotecard.h"
#include "llpreviewgesture.h"
#include "llcoproceduremanager.h"
+#include "llthread.h"
+#include "llkeyframemotion.h"
+#include "lldatapacker.h"
+#include "llvoavatarself.h"
void dialog_refresh_all();
@@ -450,9 +454,62 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
errorLabel = "DoNotSupportBulkAnimationUpload";
error = true;
}
- else if (assetType == LLAssetType::AT_ANIMATION)
+ else if (exten == "anim")
+ {
+ // Default unless everything succeeds
+ errorLabel = "ProblemWithFile";
+ error = true;
+
+ // read from getFileName()
+ LLAPRFile infile;
+ infile.open(getFileName(),LL_APR_RB);
+ if (!infile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL;
+ errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str());
+ }
+ else
+ {
+ S32 size = LLAPRFile::size(getFileName());
+ U8* buffer = new U8[size];
+ S32 size_read = infile.read(buffer,size);
+ if (size_read != size)
+ {
+ errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read);
+ }
+ else
+ {
+ LLDataPackerBinaryBuffer dp(buffer, size);
+ LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId());
+ motionp->setCharacter(gAgentAvatarp);
+ if (motionp->deserialize(dp, getAssetId(), false))
+ {
+ // write to temp file
+ bool succ = motionp->dumpToFile(filename);
+ if (succ)
+ {
+ assetType = LLAssetType::AT_ANIMATION;
+ errorLabel = "";
+ error = false;
+ }
+ else
+ {
+ errorMessage = "Failed saving temporary animation file";
+ }
+ }
+ else
+ {
+ errorMessage = "Failed reading animation file";
+ }
+ }
+ }
+ }
+ else
{
- filename = getFileName();
+ // Unknown extension
+ errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
+ errorLabel = "ErrorMessage";
+ error = TRUE;;
}
if (error)
@@ -863,6 +920,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
{
args["FILE"] = uploadInfo->getDisplayName();
args["REASON"] = reason;
+ args["ERROR"] = reason;
}
LLNotificationsUtil::add(label, args);
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index 782285ce36..febae36ae8 100644
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -33,8 +33,6 @@
// comment out to turn off wind
#define kAUDIO_ENABLE_WIND
//#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water
-#define kAUDIO_NUM_BUFFERS 30
-#define kAUDIO_NUM_SOURCES 30
void init_audio();
void audio_update_volume(bool force_update = true);
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 9036e87514..bc46a61fb0 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -639,157 +639,186 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
////////////////////////////////////////////////////////////////////////////
+LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const std::string& setting)
+{
+ LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting);
+ if (cntrl_ptr.isNull())
+ {
+ LL_ERRS() << "Unable to set up setting listener for " << setting
+ << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
+ return cntrl_ptr;
+}
+
+void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void(const LLSD& newvalue)> callback)
+{
+ setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ callback(new_val);
+ });
+}
+
+void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void()> callback)
+{
+ setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ callback();
+ });
+}
+
void settings_setup_listeners()
{
- gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2));
- gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2));
- gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2));
- gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleWindowResized, _2));
- gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2));
- gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleShadowsResized, _2));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
- gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
- gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
- gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));
- gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2));
- gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2));
- gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2));
- gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2));
- gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2));
- gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2));
- gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _2));
- gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));
- gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderVSyncEnable")->getSignal()->connect(boost::bind(&handleVSyncChanged, _2));
- gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
- gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));
- gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2));
- gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
- gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
- gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
- gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
- gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _2));
- gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _2));
- gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUseVAO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
- gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2));
- gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2));
- gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2));
- gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2));
- gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2));
- gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus));
- gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus));
- gSavedSettings.getControl("AgentPause")->getSignal()->connect(boost::bind(&toggle_agent_pause, _2));
- gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2));
- gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2));
- gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2));
- gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
- gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
- gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
- gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
- gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged));
- gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2));
- gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2));
- gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2));
+ setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
+ setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
+ setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged);
+ setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged);
+ setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
+ setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
+ setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged);
+ setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged);
+ setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged);
+ setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged);
+ setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate);
+ setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus);
+ setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus);
+ setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause);
+ setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel);
+ setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel);
+ setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost);
+ setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid);
+ setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged);
+ setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged);
+ setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged);
+ setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged);
+ setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged);
+
+ setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 6a2b06d9b5..bc0fafb29f 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -739,7 +739,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
glh::matrix4f proj = get_current_projection();
glh::matrix4f mod = get_current_modelview();
glViewport(0,0,512,512);
- LLVOAvatar::updateFreezeCounter() ;
LLVOAvatar::updateImpostors();
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 661f70972d..636909e6f2 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -3194,7 +3194,7 @@ bool LLViewerMediaImpl::isForcedUnloaded() const
}
// If this media's class is not supposed to be shown, unload
- if (!shouldShowBasedOnClass())
+ if (!shouldShowBasedOnClass() || isObscured())
{
return true;
}
@@ -3881,6 +3881,26 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
//////////////////////////////////////////////////////////////////////////////////////////
//
+bool LLViewerMediaImpl::isObscured() const
+{
+ if (getUsedInUI() || isParcelMedia()) return false;
+
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!agent_parcel)
+ {
+ return false;
+ }
+
+ if (agent_parcel->getObscureMOAP() && !isInAgentParcel())
+ {
+ return true;
+ }
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const
{
bool result = false;
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 806692929a..b95cfd4c68 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -423,6 +423,7 @@ public:
private:
bool isAutoPlayable() const;
bool shouldShowBasedOnClass() const;
+ bool isObscured() const;
static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj);
static bool isObjectInAgentParcel(LLVOVolume *obj);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ac516b8460..3573af40cb 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -33,10 +33,11 @@
#include "llviewermenu.h"
// linden library includes
-#include "llavatarnamecache.h" // IDEVO
+#include "llavatarnamecache.h" // IDEVO (I Are Not Men!)
+#include "llcombobox.h"
+#include "llcoros.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
-#include "llcombobox.h"
#include "llinventorypanel.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
@@ -53,6 +54,7 @@
#include "llcompilequeue.h"
#include "llconsole.h"
#include "lldebugview.h"
+#include "lldiskcache.h"
#include "llenvironment.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
@@ -93,6 +95,7 @@
#include "llmarketplacefunctions.h"
#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmoveview.h"
+#include "llnavigationbar.h"
#include "llparcel.h"
#include "llrootview.h"
#include "llsceneview.h"
@@ -2100,6 +2103,32 @@ class LLAdvancedDropPacket : public view_listener_t
}
};
+//////////////////////
+// PURGE DISK CACHE //
+//////////////////////
+
+
+class LLAdvancedPurgeDiskCache : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ llassert_always(main_queue);
+ llassert_always(general_queue);
+ main_queue->postTo(
+ general_queue,
+ []() // Work done on general queue
+ {
+ LLDiskCache::getInstance()->purge();
+ // Nothing needed to return
+ },
+ [](){}); // Callback to main thread is empty as there is nothing left to do
+
+ return true;
+ }
+};
+
////////////////////
// EVENT Recorder //
@@ -2324,25 +2353,13 @@ class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t
};
/////////////////////////////////////
-// Enable Framebuffer Objects ///
-/////////////////////////////////////
-class LLAdvancedEnableRenderFBO: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gGLManager.mHasFramebufferObject;
- return new_value;
- }
-};
-
-/////////////////////////////////////
// Enable Deferred Rendering ///
/////////////////////////////////////
class LLAdvancedEnableRenderDeferred: public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
+ bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0;
return new_value;
}
@@ -2355,7 +2372,7 @@ class LLAdvancedEnableRenderDeferredOptions: public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
+ bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred");
return new_value;
}
@@ -2407,6 +2424,7 @@ class LLAdvancedForceErrorLlerror : public view_listener_t
return true;
}
};
+
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2416,6 +2434,22 @@ class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
}
};
+class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLCoros::instance().launch(
+ "AdvancedForceErrorBadMemoryAccessCoro",
+ [](){
+ // Wait for one mainloop() iteration, letting the enclosing
+ // handleEvent() method return.
+ llcoro::suspend();
+ force_error_bad_memory_access(NULL);
+ });
+ return true;
+ }
+};
+
class LLAdvancedForceErrorInfiniteLoop : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2434,6 +2468,22 @@ class LLAdvancedForceErrorSoftwareException : public view_listener_t
}
};
+class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLCoros::instance().launch(
+ "AdvancedForceErrorSoftwareExceptionCoro",
+ [](){
+ // Wait for one mainloop() iteration, letting the enclosing
+ // handleEvent() method return.
+ llcoro::suspend();
+ force_error_software_exception(NULL);
+ });
+ return true;
+ }
+};
+
class LLAdvancedForceErrorDriverCrash : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -5365,12 +5415,10 @@ class LLToolsEnablePathfindingRebakeRegion : public view_listener_t
{
bool returnValue = false;
- if (LLPathfindingManager::getInstance() != NULL)
- {
- LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance();
- returnValue = (rebakeInstance->canRebakeRegion() &&
- (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available));
- }
+ if (LLNavigationBar::instanceExists())
+ {
+ returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable();
+ }
return returnValue;
}
};
@@ -9373,7 +9421,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
// Develop > Render
view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
- view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");
view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions");
view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
@@ -9472,6 +9519,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket");
+ // Advanced > Cache
+ view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache");
+
// Advanced > Recorder
view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
@@ -9482,8 +9532,10 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
+ view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
+ view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index aa31aede7c..d97ed61e11 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -33,6 +33,7 @@
#include "llavataractions.h"
#include "llavatarnamecache.h" // IDEVO HACK
#include "lleventtimer.h"
+#include "llfloatercreatelandmark.h"
#include "llfloaterreg.h"
#include "llfolderview.h"
#include "llfollowcamparams.h"
@@ -1568,6 +1569,17 @@ bool highlight_offered_object(const LLUUID& obj_id)
}
}
+ if (obj->getType() == LLAssetType::AT_LANDMARK)
+ {
+ LLFloaterCreateLandmark *floater = LLFloaterReg::findTypedInstance<LLFloaterCreateLandmark>("add_landmark");
+ if (floater && floater->getItem() && floater->getItem()->getUUID() == obj_id)
+ {
+ // LLFloaterCreateLandmark is supposed to handle this,
+ // keep landmark creation floater at the front
+ return false;
+ }
+ }
+
return true;
}
@@ -3342,13 +3354,6 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
// trigger a control event.
U32 control_flags = gAgent.getControlFlags();
- // Rotation into both directions should cancel out
- U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
- if ((control_flags & mask) == mask)
- {
- control_flags &= ~mask;
- }
-
MASK key_mask = gKeyboard->currentMask(TRUE);
if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index a95636ff23..aad6c14b4d 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -356,6 +356,13 @@ LLViewerObject::~LLViewerObject()
mPartSourcep = NULL;
}
+ if (mText)
+ {
+ // something recovered LLHUDText when object was already dead
+ mText->markDead();
+ mText = NULL;
+ }
+
// Delete memory associated with extra parameters.
std::map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
@@ -2457,11 +2464,19 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
needs_refresh = needs_refresh || child->mUserSelected;
}
+ static LLCachedControl<bool> allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE);
if (needs_refresh)
{
LLSelectMgr::getInstance()->updateSelectionCenter();
dialog_refresh_all();
- }
+ }
+ else if (allow_select_avatar && asAvatar())
+ {
+ // Override any avatar position updates received
+ // Works only if avatar was repositioned using build
+ // tools and build floater is visible
+ LLSelectMgr::getInstance()->overrideAvatarUpdates();
+ }
// Mark update time as approx. now, with the ping delay.
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 55e2386d10..e930b58111 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -571,7 +571,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if(update_cache)
{
- objectp = regionp->updateCacheEntry(local_id, objectp, update_type);
+ //update object cache if the object receives a full-update or terse update
+ objectp = regionp->updateCacheEntry(local_id, objectp);
}
// This looks like it will break if the local_id of the object doesn't change
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index e6974b0f84..7666062f99 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -45,11 +45,11 @@ class LLViewerOctreeGroup;
class LLViewerOctreeEntry;
class LLViewerOctreePartition;
-typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener;
-typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
-typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode;
-typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot;
-typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler;
+typedef LLOctreeListener<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeListener;
+typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
+typedef LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeNode;
+typedef LLOctreeRoot<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeRoot;
+typedef LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeTraveler;
#if LL_OCTREE_PARANOIA_CHECK
#define assert_octree_valid(x) x->validate()
@@ -179,7 +179,7 @@ protected:
//defines an octree group for an octree node, which contains multiple entries.
//LL_ALIGN_PREFIX(16)
class LLViewerOctreeGroup
-: public LLOctreeListener<LLViewerOctreeEntry>
+: public OctreeListener
{
LL_ALIGN_NEW
friend class LLViewerOctreeCull;
@@ -198,8 +198,8 @@ public:
};
public:
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter;
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list;
+ typedef OctreeNode::element_iter element_iter;
+ typedef OctreeNode::element_list element_list;
LLViewerOctreeGroup(OctreeNode* node);
LLViewerOctreeGroup(const LLViewerOctreeGroup& rhs)
@@ -245,7 +245,6 @@ public:
const LLVector4a* getObjectExtents() const {return mObjectExtents;}
//octree wrappers to make code more readable
- element_list& getData() { return mOctreeNode->getData(); }
element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index e69b0347f8..75eb16c085 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1553,6 +1553,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
BOOL region_allow_environment_override = true;
S32 parcel_environment_version = 0;
BOOL agent_parcel_update = false; // updating previous(existing) agent parcel
+ U32 extended_flags = 0; //obscure MOAP
S32 other_clean_time = 0;
@@ -1591,6 +1592,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
{
// new agent parcel
+ // *TODO: Does it really make sense to set the agent parcel to this
+ // parcel if the client doesn't know what kind of parcel data this is?
parcel_mgr.mAgentParcelSequenceID = sequence_id;
parcel = parcel_mgr.mAgentParcel;
}
@@ -1642,6 +1645,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override);
}
+ if (msg->getNumberOfBlocks(_PREHASH_ParcelExtendedFlags))
+ {
+ msg->getU32Fast(_PREHASH_ParcelExtendedFlags, _PREHASH_Flags, extended_flags);
+ }
+
if (msg->getNumberOfBlocks(_PREHASH_ParcelEnvironmentBlock))
{
msg->getS32Fast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_ParcelEnvironmentVersion, parcel_environment_version);
@@ -1698,6 +1706,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
parcel->setParcelEnvironmentVersion(cur_parcel_environment_version);
parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override);
+ parcel->setObscureMOAP((bool)extended_flags);
+
parcel->unpackMessage(msg);
if (parcel == parcel_mgr.mAgentParcel)
@@ -1879,8 +1889,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else
{
- // Check for video
- LLViewerParcelMedia::getInstance()->update(parcel);
+ if (gNonInteractive)
+ {
+ return;
+ }
+
+ // Check for video
+ LLViewerParcelMedia::getInstance()->update(parcel);
// Then check for music
if (gAudiop)
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 02f7bbeed8..785c84c38d 100644..100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -264,7 +264,7 @@ BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
- return PARCEL_SOUND_LOCAL & mOwnership[row * mParcelGridsPerEdge + column];
+ return parcelFlags(row, column, PARCEL_SOUND_LOCAL);
}
U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const
@@ -278,12 +278,19 @@ U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
- return parcelLineFlags(row, column);
+ return parcelFlags(row, column, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE);
}
U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const
{
- U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE;
- if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge)
+ return parcelFlags(row, col, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE);
+}
+
+U8 LLViewerParcelOverlay::parcelFlags(S32 row, S32 col, U8 flags) const
+{
+ if (row >= mParcelGridsPerEdge
+ || col >= mParcelGridsPerEdge
+ || row < 0
+ || col < 0)
{
LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL;
return flags;
@@ -908,8 +915,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
// Always fudge a little vertically.
pull_toward_camera.mV[VZ] += 0.01f;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
// Move to appropriate region coords
LLVector3 origin = mRegion->getOriginAgent();
@@ -1014,7 +1021,66 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
}
- gGL.popMatrix();
+ gGL.popMatrix();
return drawn;
}
+
+// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top
+void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom)
+{
+ gGL.begin(LLRender::LINES);
+
+ if (has_left)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(left, top);
+ }
+ if (has_bottom)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(right, bottom);
+ }
+
+ gGL.end();
+}
+
+void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (!mOwnership)
+ {
+ return;
+ }
+ if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ return;
+ }
+
+ LLVector3 origin_agent = mRegion->getOriginAgent();
+ LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
+ F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter;
+ F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter;
+ const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ glLineWidth(1.0f);
+ gGL.color4fv(parcel_outline_color);
+ for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++)
+ {
+ const F32 bottom = region_bottom + (i * map_parcel_width);
+ const F32 top = bottom + map_parcel_width;
+ for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++)
+ {
+ const F32 left = region_left + (j * map_parcel_width);
+ const F32 right = left + map_parcel_width;
+ const bool is_region_boundary = i == GRIDS_PER_EDGE || j == GRIDS_PER_EDGE;
+ const U8 overlay = is_region_boundary ? 0 : mOwnership[(i * GRIDS_PER_EDGE) + j];
+ // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a
+ // 2D map
+ const bool has_left = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE));
+ const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE));
+ grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom);
+ }
+ }
+}
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index e30dbf17b3..c466cc3b6b 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -69,6 +69,7 @@ public:
// Returns the number of vertices drawn
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
U8 ownership( const LLVector3& pos) const;
U8 parcelLineFlags( const LLVector3& pos) const;
@@ -82,12 +83,14 @@ public:
void idleUpdate(bool update_now = false);
void updateGL();
-
+
private:
// This is in parcel rows and columns, not grid rows and columns
// Stored in bottom three bits.
U8 ownership(S32 row, S32 col) const
- { return 0x7 & mOwnership[row * mParcelGridsPerEdge + col]; }
+ { return parcelFlags(row, col, (U8)0x7); }
+
+ U8 parcelFlags(S32 row, S32 col, U8 flags) const;
void addPropertyLine(std::vector<LLVector3>& vertex_array,
std::vector<LLColor4U>& color_array,
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index f48543822a..ad7321ca4b 100644..100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -95,8 +95,6 @@
// The server only keeps our pending agent info for 60 seconds.
// We want to allow for seed cap retry, but its not useful after that 60 seconds.
-// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
-const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
// Even though we gave up on login, keep trying for caps after we are logged in:
const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
@@ -178,7 +176,6 @@ public:
mCompositionp(NULL),
mEventPoll(NULL),
mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
- mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
mSeedCapAttempts(0),
mHttpResponderID(0),
mLastCameraUpdate(0),
@@ -231,7 +228,6 @@ public:
LLEventPoll* mEventPoll;
S32 mSeedCapMaxAttempts;
- S32 mSeedCapMaxAttemptsBeforeLogin;
S32 mSeedCapAttempts;
S32 mHttpResponderID;
@@ -286,19 +282,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
if (url.empty())
{
LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ regionp->setCapabilitiesError();
return; // this error condition is not recoverable.
}
// record that we just entered a new region
newRegionEntry(*regionp);
- // After a few attempts, continue login. But keep trying to get the caps:
- if (impl->mSeedCapAttempts >= impl->mSeedCapMaxAttemptsBeforeLogin &&
- STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
- }
-
if (impl->mSeedCapAttempts > impl->mSeedCapMaxAttempts)
{
// *TODO: Give a user pop-up about this error?
@@ -334,6 +324,23 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
return;
}
+ if (!LLWorld::instanceExists())
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;
+ return;
+ }
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ impl = regionp->getRegionImplNC();
+
+ ++(impl->mSeedCapAttempts);
+
if (!result.isMap() || result.has("error"))
{
LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL;
@@ -353,23 +360,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
// remove the http_result from the llsd
result.erase("http_result");
- if (!LLWorld::instanceExists())
- {
- LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;
- return;
- }
-
- regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
- if (!regionp) //region was removed
- {
- LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
- return; // this error condition is not recoverable.
- }
-
- impl = regionp->getRegionImplNC();
-
- ++(impl->mSeedCapAttempts);
-
if (id != impl->mHttpResponderID) // region is no longer referring to this request
{
LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
@@ -394,11 +384,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
<< " region name " << regionp->getName() << LL_ENDL;
regionp->setCapabilitiesReceived(true);
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
- }
-
break;
}
while (true);
@@ -442,6 +427,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
if (url.empty())
{
LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ if (regionp->getCapability("Seed").empty())
+ {
+ // initial attempt failed to get this cap as well
+ regionp->setCapabilitiesError();
+ }
break; // this error condition is not recoverable.
}
@@ -643,7 +633,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mCacheLoaded(FALSE),
mCacheDirty(FALSE),
mReleaseNotesRequested(FALSE),
- mCapabilitiesReceived(false),
+ mCapabilitiesState(CAPABILITIES_STATE_INIT),
mSimulatorFeaturesReceived(false),
mBitsReceived(0.f),
mPacketsReceived(0.f),
@@ -1078,6 +1068,15 @@ S32 LLViewerRegion::renderPropertyLines()
}
}
+void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (mParcelOverlay)
+ {
+ mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color);
+ }
+}
+
+
// This gets called when the height field changes.
void LLViewerRegion::dirtyHeights()
{
@@ -1818,13 +1817,8 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
//update object cache if the object receives a full-update or terse update
//update_type == EObjectUpdateType::OUT_TERSE_IMPROVED or EObjectUpdateType::OUT_FULL
-LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type)
+LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp)
{
- if(objectp && update_type != (U32)OUT_TERSE_IMPROVED)
- {
- return objectp; //no need to access cache
- }
-
LLVOCacheEntry* entry = getCacheEntry(local_id);
if (!entry)
{
@@ -1836,11 +1830,8 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o
objectp = addNewObject(entry);
}
- //remove from cache if terse update
- if(update_type == (U32)OUT_TERSE_IMPROVED)
- {
- killCacheEntry(entry, true);
- }
+ //remove from cache.
+ killCacheEntry(entry, true);
return objectp;
}
@@ -2300,6 +2291,11 @@ void LLViewerRegion::requestSimulatorFeatures()
std::string coroname =
LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, url, getHandle()));
+
+ // requestSimulatorFeatures can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL;
}
@@ -3121,6 +3117,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
std::string coroname =
LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle()));
+
+ // setSeedCapability can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
+
return;
}
@@ -3134,6 +3136,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, getHandle()));
+ // setSeedCapability can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
+
LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL;
}
@@ -3255,12 +3262,17 @@ bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const
bool LLViewerRegion::capabilitiesReceived() const
{
- return mCapabilitiesReceived;
+ return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED;
+}
+
+bool LLViewerRegion::capabilitiesError() const
+{
+ return mCapabilitiesState == CAPABILITIES_STATE_ERROR;
}
void LLViewerRegion::setCapabilitiesReceived(bool received)
{
- mCapabilitiesReceived = received;
+ mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT;
// Tell interested parties that we've received capabilities,
// so that they can safely use getCapability().
@@ -3275,6 +3287,11 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
}
}
+void LLViewerRegion::setCapabilitiesError()
+{
+ mCapabilitiesState = CAPABILITIES_STATE_ERROR;
+}
+
boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
{
return mCapabilitiesReceivedSignal.connect(cb);
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index fcbf56c81f..6548e8d372 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -154,6 +154,8 @@ public:
// Draw lines in the dirt showing ownership. Return number of
// vertices drawn.
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
+
// Call this whenever you change the height data in the region.
// (Automatically called by LLSurfacePatch's update routine)
@@ -268,7 +270,9 @@ public:
// has region received its final (not seed) capability list?
bool capabilitiesReceived() const;
+ bool capabilitiesError() const;
void setCapabilitiesReceived(bool received);
+ void setCapabilitiesError();
boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb);
static bool isSpecialCapabilityName(const std::string &name);
@@ -352,7 +356,7 @@ public:
void requestCacheMisses();
void addCacheMissFull(const U32 local_id);
//update object cache if the object receives a full-update or terse update
- LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type);
+ LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp);
void findOrphans(U32 parent_id);
void clearCachedVisibleObjects();
void dumpCache();
@@ -527,12 +531,20 @@ private:
BOOL mCacheLoaded;
BOOL mCacheDirty;
BOOL mAlive; // can become false if circuit disconnects
- BOOL mCapabilitiesReceived;
BOOL mSimulatorFeaturesReceived;
BOOL mReleaseNotesRequested;
BOOL mDead; //if true, this region is in the process of deleting.
BOOL mPaused; //pause processing the objects in the region
+ typedef enum
+ {
+ CAPABILITIES_STATE_INIT = 0,
+ CAPABILITIES_STATE_ERROR,
+ CAPABILITIES_STATE_RECEIVED
+ } eCababilitiesState;
+
+ eCababilitiesState mCapabilitiesState;
+
typedef std::map<U32, std::vector<U32> > orphan_list_t;
orphan_list_t mOrphanMap;
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 086b433c72..1c9360a843 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -556,15 +556,14 @@ void LLViewerShaderMgr::setShaders()
mShaderLevel[SHADER_DEFERRED] = deferred_class;
mShaderLevel[SHADER_TRANSFORM] = transform_class;
- BOOL loaded = loadBasicShaders();
- if (loaded)
+ std::string shader_name = loadBasicShaders();
+ if (shader_name.empty())
{
LL_INFOS() << "Loaded basic shaders." << LL_ENDL;
}
else
{
- LL_ERRS() << "Unable to load basic shaders, verify graphics driver installed and current." << LL_ENDL;
- llassert(loaded);
+ LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL;
reentrance = false; // For hygiene only, re-try probably helps nothing
return;
}
@@ -572,7 +571,7 @@ void LLViewerShaderMgr::setShaders()
gPipeline.mShadersLoaded = true;
// Load all shaders to set max levels
- loaded = loadShadersEnvironment();
+ BOOL loaded = loadShadersEnvironment();
if (loaded)
{
@@ -859,7 +858,7 @@ void LLViewerShaderMgr::unloadShaders()
gPipeline.mShadersLoaded = false;
}
-BOOL LLViewerShaderMgr::loadBasicShaders()
+std::string LLViewerShaderMgr::loadBasicShaders()
{
// Load basic dependency shaders first
// All of these have to load for any shaders to function
@@ -945,8 +944,8 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// Note usage of GL_VERTEX_SHADER_ARB
if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)
{
- LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
- return FALSE;
+ LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
}
}
@@ -1005,12 +1004,12 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// Note usage of GL_FRAGMENT_SHADER_ARB
if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)
{
- LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
- return FALSE;
+ LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
}
}
- return TRUE;
+ return std::string();
}
BOOL LLViewerShaderMgr::loadShadersEnvironment()
@@ -1484,6 +1483,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
if (use_sun_shadow)
{
gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
@@ -1542,6 +1547,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
if (use_sun_shadow)
{
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 93bb29a355..f8a261805b 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -49,7 +49,11 @@ public:
void setShaders();
void unloadShaders();
S32 getShaderLevel(S32 type);
- BOOL loadBasicShaders();
+
+ // loadBasicShaders in case of a failure returns
+ // name of a file error happened at, otherwise
+ // returns an empty string
+ std::string loadBasicShaders();
BOOL loadShadersEffects();
BOOL loadShadersDeferred();
BOOL loadShadersObject();
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 3385d317e6..a4fbbb3e78 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -506,6 +506,7 @@ void send_viewer_stats(bool include_preferences)
system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value();
system["os"] = LLOSInfo::instance().getOSStringSimple();
system["cpu"] = gSysCPU.getCPUString();
+ system["cpu_sse"] = gSysCPU.getSSEVersions();
system["address_size"] = ADDRESS_SIZE;
system["os_bitness"] = LLOSInfo::instance().getOSBitness();
unsigned char MACAddress[MAC_ADDRESS_BYTES];
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index d603f584ff..da3c860ddb 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1148,15 +1148,14 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
total_update_count--;
}
}
-
- S32 fetch_count = 0;
+
size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count));
S32 min_count = max_priority_count + min_update_count;
for (entries_list_t::iterator iter3 = entries.begin();
iter3 != entries.end(); )
{
LLViewerFetchedTexture* imagep = *iter3++;
- fetch_count += (imagep->updateFetch() ? 1 : 0);
+ imagep->updateFetch();
if (min_count <= min_update_count)
{
mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 119859a4ac..8a7d5f12d0 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -772,6 +772,12 @@ public:
ypos += y_inc;
addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f)));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f)));
ypos += y_inc;
}
@@ -1567,9 +1573,11 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
showCursor();
getWindow()->setMouseClipping(FALSE);
- // If losing focus while keys are down, reset them.
+ // If losing focus while keys are down, handle them as
+ // an 'up' to correctly release states, then reset states
if (gKeyboard)
{
+ gKeyboard->resetKeyDownAndHandle();
gKeyboard->resetKeys();
}
@@ -1997,7 +2005,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
}
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
- gGL.init() ;
+ gGL.init(true);
if (LLFeatureManager::getInstance()->isSafe()
|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
@@ -2510,10 +2518,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)
//glViewport(0, 0, width, height );
- if (height > 0)
+ LLViewerCamera * camera = LLViewerCamera::getInstance(); // simpleton, might not exist
+ if (height > 0 && camera)
{
- LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
- LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ camera->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ camera->setAspect( getWorldViewAspectRatio() );
}
calcDisplayScale();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 5c76f7b392..42550ed48d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @File llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation of LLViewerObject
*
@@ -183,8 +183,6 @@ const F32 MAX_STANDOFF_DISTANCE_CHANGE = 32;
// Should probably be 4 or 3, but didn't want to change it while change other logic - SJB
const S32 SWITCH_TO_BAKED_DISCARD = 5;
-const F32 FOOT_COLLIDE_FUDGE = 0.04f;
-
const F32 HOVER_EFFECT_MAX_SPEED = 3.f;
const F32 HOVER_EFFECT_STRENGTH = 0.f;
const F32 UNDERWATER_EFFECT_STRENGTH = 0.1f;
@@ -585,7 +583,6 @@ private:
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
-S32 LLVOAvatar::sFreezeCounter = 0;
U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors
bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)
F32 LLVOAvatar::sRenderDistance = 256.f;
@@ -610,7 +607,6 @@ S32 LLVOAvatar::sNumVisibleChatBubbles = 0;
BOOL LLVOAvatar::sDebugInvisible = FALSE;
BOOL LLVOAvatar::sShowAttachmentPoints = FALSE;
BOOL LLVOAvatar::sShowAnimationDebug = FALSE;
-BOOL LLVOAvatar::sShowFootPlane = FALSE;
BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
F32 LLVOAvatar::sLODFactor = 1.f;
F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
@@ -779,6 +775,13 @@ std::string LLVOAvatar::avString() const
void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment)
{
+ if (gDisconnected)
+ {
+ // If we disconected, these values are likely to be invalid and
+ // avString() might crash due to a dead sAvatarDictionary
+ return;
+ }
+
LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
<< "sec ]"
<< avString()
@@ -2810,6 +2813,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (detailed_update)
{
U32 draw_order = 0;
+ S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment();
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -2849,7 +2853,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
}
// if selecting any attachments, update all of them as non-damped
- if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment())
+ if (attachment_selected)
{
gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
}
@@ -4105,8 +4109,7 @@ void LLVOAvatar::computeUpdatePeriod()
&& (!isSelf() || visually_muted)
&& !isUIAvatar()
&& (sLimitNonImpostors || visually_muted)
- && !mNeedsAnimUpdate
- && !sFreezeCounter)
+ && !mNeedsAnimUpdate)
{
const LLVector4a* ext = mDrawable->getSpatialExtents();
LLVector4a size;
@@ -5079,42 +5082,6 @@ U32 LLVOAvatar::renderSkinned()
return num_indices;
}
- // render collision normal
- // *NOTE: this is disabled (there is no UI for enabling sShowFootPlane) due
- // to DEV-14477. the code is left here to aid in tracking down the cause
- // of the crash in the future. -brad
- if (sShowFootPlane && mDrawable.notNull())
- {
- LLVector3 slaved_pos = mDrawable->getPositionAgent();
- LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]);
- F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW];
- LLVector3 collide_point = slaved_pos;
- collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE);
-
- gGL.begin(LLRender::LINES);
- {
- F32 SQUARE_SIZE = 0.2f;
- gGL.color4f(1.f, 0.f, 0.f, 1.f);
-
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]);
-
- }
- gGL.end();
- gGL.flush();
- }
//--------------------------------------------------------------------
// render all geometry attached to the skeleton
//--------------------------------------------------------------------
@@ -6189,7 +6156,21 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
if (iter == mJointMap.end() || iter->second == NULL)
{ //search for joint and cache found joint in lookup table
- jointp = mRoot->findJoint(name);
+ if (mJointAliasMap.empty())
+ {
+ getJointAliases();
+ }
+ joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
+ std::string canonical_name;
+ if (alias_iter != mJointAliasMap.end())
+ {
+ canonical_name = alias_iter->second;
+ }
+ else
+ {
+ canonical_name = name;
+ }
+ jointp = mRoot->findJoint(canonical_name);
mJointMap[name] = jointp;
}
else
@@ -7241,6 +7222,14 @@ LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx)
}
//-----------------------------------------------------------------------------
+// hideHair()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::hideHair()
+{
+ mMeshLOD[MESH_ID_HAIR]->setVisible(FALSE, TRUE);
+}
+
+//-----------------------------------------------------------------------------
// hideSkirt()
//-----------------------------------------------------------------------------
void LLVOAvatar::hideSkirt()
@@ -10245,23 +10234,6 @@ LLHost LLVOAvatar::getObjectHost() const
}
}
-//static
-void LLVOAvatar::updateFreezeCounter(S32 counter)
-{
- if(counter)
- {
- sFreezeCounter = counter;
- }
- else if(sFreezeCounter > 0)
- {
- sFreezeCounter--;
- }
- else
- {
- sFreezeCounter = 0;
- }
-}
-
BOOL LLVOAvatar::updateLOD()
{
if (mDrawable.isNull())
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 3c3decaad6..8d1dcbcda2 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -326,7 +326,6 @@ public:
static bool sLimitNonImpostors; // use impostors for far away avatars
static F32 sRenderDistance; // distance at which avatars will render.
static BOOL sShowAnimationDebug; // show animation debug info
- static BOOL sShowFootPlane; // show foot collision plane reported by server
static BOOL sShowCollisionVolumes; // show skeletal collision volumes
static BOOL sVisibleInFirstPerson;
static S32 sNumLODChangesThisFrame;
@@ -618,14 +617,6 @@ private:
BOOL mCulled;
//--------------------------------------------------------------------
- // Freeze counter
- //--------------------------------------------------------------------
-public:
- static void updateFreezeCounter(S32 counter = 0);
-private:
- static S32 sFreezeCounter;
-
- //--------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------
public:
@@ -808,6 +799,7 @@ public:
void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);
void processAvatarAppearance(LLMessageSystem* mesgsys);
void applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params);
+ void hideHair();
void hideSkirt();
void startAppearanceAnimation();
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index db8ad183f0..55fc663496 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -366,15 +366,6 @@ void LLVOCacheEntry::updateDebugSettings()
}
timer.reset();
- //the number of frames invisible objects stay in memory
- static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime");
- sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum
-
- //min radius: all objects within this radius remain loaded in memory
- static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
- sNearRadius = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance
- sNearRadius = llmax(sNearRadius, 1.f); //minimum value is 1.0m
-
//objects within the view frustum whose visible area is greater than this threshold will be loaded
static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold");
sFrontPixelThreshold = front_pixel_threshold;
@@ -384,29 +375,38 @@ void LLVOCacheEntry::updateDebugSettings()
sRearPixelThreshold = rear_pixel_threshold;
sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold.
- // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
- static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
- sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m
- sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius".
- sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance.
-
- //make the above parameters adaptive to memory usage
+ //make parameters adaptive to memory usage
//starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB
static LLCachedControl<U32> low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound");
static LLCachedControl<U32> high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound");
LLMemory::updateMemoryInfo() ;
U32 allocated_mem = LLMemory::getAllocatedMemKB().value();
- allocated_mem /= 1024; //convert to MB.
- if(allocated_mem < low_mem_bound_MB)
- {
- return;
- }
- F32 adjust_factor = llmax(0.f, (F32)(high_mem_bound_MB - allocated_mem) / (high_mem_bound_MB - low_mem_bound_MB));
-
- sRearFarRadius = llmin(adjust_factor * sRearFarRadius, 96.f); //[0.f, 96.f]
- sMinFrameRange = (U32)llclamp(adjust_factor * sMinFrameRange, 10.f, 64.f); //[10, 64]
- sNearRadius = llmax(adjust_factor * sNearRadius, 1.0f);
+ static const F32 KB_to_MB = 1.f / 1024.f;
+ U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB);
+ const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB;
+ const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1]
+
+ //min radius: all objects within this radius remain loaded in memory
+ static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
+ static const F32 MIN_RADIUS = 1.0f;
+ const F32 draw_radius = gAgentCamera.mDrawDistance;
+ const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance]
+ sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor);
+
+ // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
+ static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
+ const F32 min_radius_plus_one = sNearRadius + 1.f;
+ const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance;
+ const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance]
+ sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor);
+
+ //the number of frames invisible objects stay in memory
+ static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime");
+ static const U32 MIN_FRAMES = 10;
+ static const U32 MAX_FRAMES = 64;
+ const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64
+ sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor);
}
//static
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index f971554c9d..b0eb8d962c 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -770,8 +770,6 @@ LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string
mReceivedCall(FALSE)
{
// make sure URI reflects encoded version of other user's agent id
- // *NOTE: in case of Avaline call generated SIP URL will be incorrect.
- // But it will be overridden in LLVoiceChannelP2P::setSessionHandle() called when agent accepts call
setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id));
}
@@ -911,8 +909,6 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s
else
{
LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL;
- // In the case of an incoming AvaLine call, the generated URI will be different from the
- // original one. This is because the P2P URI is based on avatar UUID but Avaline is not.
// See LLVoiceClient::sessionAddedEvent()
setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID));
}
@@ -947,22 +943,5 @@ void LLVoiceChannelP2P::setState(EState state)
void LLVoiceChannelP2P::addToTheRecentPeopleList()
{
- bool avaline_call = LLIMModel::getInstance()->findIMSession(mSessionID)->isAvalineSessionType();
-
- if (avaline_call)
- {
- LLSD call_data;
- std::string call_number = LLVoiceChannel::getSessionName();
-
- call_data["avaline_call"] = true;
- call_data["session_id"] = mSessionID;
- call_data["call_number"] = call_number;
- call_data["date"] = LLDate::now();
-
- LLRecentPeople::instance().add(mOtherUserID, call_data);
- }
- else
- {
- LLRecentPeople::instance().add(mOtherUserID);
- }
+ LLRecentPeople::instance().add(mOtherUserID);
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index d399d724f3..2ef2d66f18 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -201,6 +201,7 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion()
LLVoiceVersionInfo result;
result.serverVersion = std::string();
result.serverType = std::string();
+ result.mBuildVersion = std::string();
return result;
}
}
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index cf527a4464..246883b611 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -95,6 +95,7 @@ struct LLVoiceVersionInfo
{
std::string serverType;
std::string serverVersion;
+ std::string mBuildVersion;
};
//////////////////////////////////
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 19036a3f77..ac6369e4e2 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -690,6 +690,10 @@ void LLVivoxVoiceClient::voiceControlCoro()
// surviving longer than LLVivoxVoiceClient
voiceControlStateMachine(state);
}
+ catch (const LLCoros::Stop&)
+ {
+ LL_DEBUGS("LLVivoxVoiceClient") << "Received a shutdown exception" << LL_ENDL;
+ }
catch (const LLContinueError&)
{
LOG_UNHANDLED_EXCEPTION("LLVivoxVoiceClient");
@@ -1606,13 +1610,33 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
}
else
{
- LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
-
+ LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
+ if (channel != NULL)
+ {
+ if (channel->getSessionName().empty() && channel->getSessionID().isNull())
+ {
+ if (LLViewerParcelMgr::getInstance()->allowAgentVoice())
+ {
+ LL_WARNS("Voice") << "No channel credentials for default channel" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
+ }
+ }
}
}
else
{
- LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
+ if (LLViewerParcelMgr::getInstance()->allowAgentVoice())
+ {
+ LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Voice") << "No voice credentials" << LL_ENDL;
+ }
}
// set the spatial channel. If no voice credentials or uri are
@@ -4572,6 +4596,23 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
}
}
+void LLVivoxVoiceClient::voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id)
+{
+ // We don't generally need to process this. However, one occurence is when we first connect, and so it is the
+ // earliest opportunity to learn what we're connected to.
+ if (statusCode)
+ {
+ LL_WARNS("Voice") << "VoiceServiceConnectionStateChangedEvent statusCode: " << statusCode <<
+ "statusString: " << statusString << LL_ENDL;
+ return;
+ }
+ if (build_id.empty())
+ {
+ return;
+ }
+ mVoiceVersion.mBuildVersion = build_id;
+}
+
void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)
{
LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL;
@@ -4758,7 +4799,7 @@ void LLVivoxVoiceClient::sessionState::VerifySessions()
if ((*it).expired())
{
LL_WARNS("Voice") << "Expired session found! removing" << LL_ENDL;
- mSession.erase(it++);
+ it = mSession.erase(it);
}
else
++it;
@@ -6815,7 +6856,7 @@ void LLVivoxVoiceClient::deleteVoiceFont(const LLUUID& id)
if (list_iter->second == id)
{
LL_DEBUGS("VoiceFont") << "Removing " << id << " from the voice font list." << LL_ENDL;
- mVoiceFontList.erase(list_iter++);
+ list_iter = mVoiceFontList.erase(list_iter);
mVoiceFontListDirty = true;
}
else
@@ -7554,6 +7595,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
connectorHandle = string;
else if (!stricmp("VersionID", tag))
versionID = string;
+ else if (!stricmp("Version", tag))
+ mBuildID = string;
else if (!stricmp("AccountHandle", tag))
accountHandle = string;
else if (!stricmp("State", tag))
@@ -7856,7 +7899,8 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
// We don't need to process this, but we also shouldn't warn on it, since that confuses people.
}
else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent"))
- { // Yet another ignored event
+ {
+ LLVivoxVoiceClient::getInstance()->voiceServiceConnectionStateChangedEvent(statusCode, statusString, mBuildID);
}
else if (!stricmp(eventTypeCstr, "AudioDeviceHotSwapEvent"))
{
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index cf30a4e86a..ebc3a62c35 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -465,6 +465,7 @@ protected:
void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType);
void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString);
void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
+ void voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id);
void auxAudioPropertiesEvent(F32 energy);
void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString);
void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string &notificationType);
@@ -969,6 +970,7 @@ protected:
std::string actionString;
std::string connectorHandle;
std::string versionID;
+ std::string mBuildID;
std::string accountHandle;
std::string sessionHandle;
std::string sessionGroupHandle;
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 068e8a131d..f3affbeb33 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -845,9 +845,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
- U32 index_count = 0;
- U32 vertex_count = 0;
-
group->clearDrawMap();
LLVertexBuffer* buffer = group->mVertexBuffer;
@@ -913,9 +910,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
llassert(facep->getIndicesCount() == 6);
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
-
S32 idx = draw_vec.size()-1;
BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f4a938e57d..56028e051f 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1715,7 +1715,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds)
// updates needed, set REBUILD_RIGGED accordingly.
// Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about.
- updateRiggedVolume();
+ updateRiggedVolume(false);
}
LLVolume* volume = mRiggedVolume;
@@ -2009,7 +2009,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mDrawable->isState(LLDrawable::REBUILD_RIGGED))
{
- updateRiggedVolume();
+ updateRiggedVolume(false);
genBBoxes(FALSE);
mDrawable->clearState(LLDrawable::REBUILD_RIGGED);
}
@@ -4615,7 +4615,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- updateRiggedVolume(true);
+ updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES);
volume = mRiggedVolume;
transform = false;
}
@@ -4690,6 +4690,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
continue;
}
+ // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree.
+ // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking.
+ updateRiggedVolume(true, i, false);
face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
&p, &tc, &n, &tn);
@@ -4813,13 +4816,13 @@ void LLVOVolume::clearRiggedVolume()
}
}
-void LLVOVolume::updateRiggedVolume(bool force_update)
+void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//Update mRiggedVolume to match current animation frame of avatar.
//Also update position/size in octree.
- if ((!force_update) && (!treatAsRigged()))
+ if ((!force_treat_as_rigged) && (!treatAsRigged()))
{
clearRiggedVolume();
@@ -4848,10 +4851,10 @@ void LLVOVolume::updateRiggedVolume(bool force_update)
updateRelativeXform();
}
- mRiggedVolume->update(skin, avatar, volume);
+ mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees);
}
-void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume)
+void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index, bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
bool copy = false;
@@ -4882,7 +4885,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
if (is_paused)
{
S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame();
- if (frames_paused > 2)
+ if (frames_paused > 1)
{
return;
}
@@ -4901,7 +4904,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
S32 rigged_vert_count = 0;
S32 rigged_face_count = 0;
LLVector4a box_min, box_max;
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ S32 face_begin;
+ S32 face_end;
+ if (face_index == DO_NOT_UPDATE_FACES)
+ {
+ face_begin = 0;
+ face_end = 0;
+ }
+ else if (face_index == UPDATE_ALL_FACES)
+ {
+ face_begin = 0;
+ face_end = volume->getNumVolumeFaces();
+ }
+ else
+ {
+ face_begin = face_index;
+ face_end = face_begin + 1;
+ }
+ for (S32 i = face_begin; i < face_end; ++i)
{
const LLVolumeFace& vol_face = volume->getVolumeFace(i);
@@ -4986,15 +5006,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
+ if (rebuild_face_octrees)
{
- delete dst_face.mOctree;
- dst_face.mOctree = NULL;
-
- LLVector4a size;
- size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]);
- size.splat(size.getLength3().getF32()*0.5f);
-
- dst_face.createOctree(1.f);
+ dst_face.destroyOctree();
+ dst_face.createOctree();
}
}
}
@@ -5500,7 +5515,7 @@ static inline void add_face(T*** list, U32* count, T* face)
{
if (count[1] < MAX_FACE_COUNT)
{
- face->setDrawOrderIndex(count[1]);
+ //face->setDrawOrderIndex(count[1]);
list[1][count[1]++] = face;
}
}
@@ -5508,15 +5523,40 @@ static inline void add_face(T*** list, U32* count, T* face)
{
if (count[0] < MAX_FACE_COUNT)
{
- face->setDrawOrderIndex(count[0]);
+ //face->setDrawOrderIndex(count[0]);
list[0][count[0]++] = face;
}
}
}
+// return index into linkset for given object (0 for root prim)
+U32 get_linkset_index(LLVOVolume* vobj)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
+ if (vobj->isRootEdit())
+ {
+ return 0;
+ }
+
+ LLViewerObject* root = vobj->getRootEdit();
+ U32 idx = 1;
+ for (const auto& child : root->getChildren())
+ {
+ if (child == vobj)
+ {
+ return idx;
+ }
+ ++idx;
+ }
+
+ llassert(false);
+ return idx; //should never get here
+}
+
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5675,6 +5715,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
avatar->addAttachmentOverridesForObject(vobj, NULL, false);
}
+ U32 linkset_index = get_linkset_index(vobj);
+
// Standard rigged mesh attachments:
bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
@@ -5694,6 +5736,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // order by linkset index first and face index second
+ facep->setDrawOrderIndex(linkset_index * 100 + i);
+
//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
// batch, it will recover its vertex buffer reference from the spatial group
facep->setVertexBuffer(NULL);
@@ -5718,11 +5763,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (facep->isState(LLFace::RIGGED))
{
//face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
- if (pool)
- {
- pool->removeFace(facep);
- }
facep->clearState(LLFace::RIGGED);
facep->mAvatar = NULL;
facep->mSkinInfo = NULL;
@@ -5904,7 +5944,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
else
{
drawablep->clearState(LLDrawable::RIGGED);
- vobj->updateRiggedVolume();
+ vobj->updateRiggedVolume(false);
}
}
}
@@ -6178,6 +6218,13 @@ struct CompareBatchBreakerRigged
}
};
+struct CompareDrawOrder
+{
+ bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
+ {
+ return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex();
+ }
+};
U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged)
{
@@ -6222,6 +6269,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
//sort faces by things that break batches, including avatar and mesh id
std::sort(faces, faces + face_count, CompareBatchBreakerRigged());
}
+ else
+ {
+ // preserve legacy draw order for rigged faces
+ std::sort(faces, faces + face_count, CompareDrawOrder());
+ }
}
else if (!distance_sort)
{
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 4136c13315..01ad40274b 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -65,7 +65,10 @@ public:
{
}
- void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume);
+ using FaceIndex = S32;
+ static const FaceIndex UPDATE_ALL_FACES = -1;
+ static const FaceIndex DO_NOT_UPDATE_FACES = -2;
+ void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES, bool rebuild_face_octrees = true);
std::string mExtraDebugText;
};
@@ -362,8 +365,9 @@ public:
S32 getMDCImplCount() { return mMDCImplCount; }
- //rigged volume update (for raycasting)
- void updateRiggedVolume(bool force_update = false);
+ // Rigged volume update (for raycasting)
+ // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting
+ void updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true);
LLRiggedVolume* getRiggedVolume();
//returns true if volume should be treated as a rigged volume
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 8abb49fba8..aa32ef04b2 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -763,14 +763,13 @@ void LLWorld::updateParticles()
void LLWorld::renderPropertyLines()
{
S32 region_count = 0;
- S32 vertex_count = 0;
for (region_list_t::iterator iter = mVisibleRegionList.begin();
iter != mVisibleRegionList.end(); ++iter)
{
LLViewerRegion* regionp = *iter;
region_count++;
- vertex_count += regionp->renderPropertyLines();
+ regionp->renderPropertyLines();
}
}
@@ -778,7 +777,6 @@ void LLWorld::renderPropertyLines()
void LLWorld::updateNetStats()
{
F64Bits bits;
- U32 packets = 0;
for (region_list_t::iterator iter = mActiveRegionList.begin();
iter != mActiveRegionList.end(); ++iter)
@@ -786,7 +784,6 @@ void LLWorld::updateNetStats()
LLViewerRegion* regionp = *iter;
regionp->updateNetStats();
bits += regionp->mBitsReceived;
- packets += llfloor( regionp->mPacketsReceived );
regionp->mBitsReceived = (F32Bits)0.f;
regionp->mPacketsReceived = 0.f;
}
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 59ac4554d7..6e994b4e68 100644..100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -58,9 +58,15 @@
#include "llglheaders.h"
+// # Constants
+static const F32 MAP_DEFAULT_SCALE = 128.f;
+static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f;
+static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f;
+static const F32 MAP_ZOOM_MAX_INTERP = 0.5f;
+static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f;
+
// Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py
// Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...)
-// # Constants
// OCEAN_COLOR = "#1D475F"
const F32 OCEAN_RED = (F32)(0x1D)/255.f;
const F32 OCEAN_GREEN = (F32)(0x47)/255.f;
@@ -92,14 +98,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL;
-F32 LLWorldMapView::sPanX = 0.f;
-F32 LLWorldMapView::sPanY = 0.f;
-F32 LLWorldMapView::sTargetPanX = 0.f;
-F32 LLWorldMapView::sTargetPanY = 0.f;
S32 LLWorldMapView::sTrackingArrowX = 0;
S32 LLWorldMapView::sTrackingArrowY = 0;
bool LLWorldMapView::sVisibleTilesLoaded = false;
-F32 LLWorldMapView::sMapScale = 128.f;
+F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE;
+LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f);
+LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer();
std::map<std::string,std::string> LLWorldMapView::sStringsMap;
@@ -166,20 +170,27 @@ void LLWorldMapView::cleanupClass()
sForSaleAdultImage = NULL;
}
-LLWorldMapView::LLWorldMapView()
-: LLPanel(),
- mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ),
- mItemPicked(FALSE),
- mPanning( FALSE ),
- mMouseDownPanX( 0 ),
- mMouseDownPanY( 0 ),
- mMouseDownX( 0 ),
- mMouseDownY( 0 ),
- mSelectIDStart(0)
+LLWorldMapView::LLWorldMapView() :
+ LLPanel(),
+ mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)),
+ mItemPicked(FALSE),
+ mPanX(0.f),
+ mPanY(0.f),
+ mTargetPanX(0.f),
+ mTargetPanY(0.f),
+ mPanning(FALSE),
+ mMouseDownPanX(0),
+ mMouseDownPanY(0),
+ mMouseDownX(0),
+ mMouseDownY(0),
+ mSelectIDStart(0),
+ mMapScale(0.f),
+ mTargetMapScale(0.f),
+ mMapIterpTime(MAP_ITERP_TIME_CONSTANT)
{
- //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
+ // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
- clearLastClick();
+ clearLastClick();
}
BOOL LLWorldMapView::postBuild()
@@ -210,6 +221,9 @@ BOOL LLWorldMapView::postBuild()
mTextBoxNorthEast ->reshapeToFitText();
mTextBoxSouthWest->reshapeToFitText();
mTextBoxNorthWest ->reshapeToFitText();
+
+ sZoomTimer.stop();
+ setScale(sMapScaleSetting, true);
return true;
}
@@ -227,59 +241,111 @@ void LLWorldMapView::cleanupTextures()
{
}
+void LLWorldMapView::zoom(F32 zoom)
+{
+ mTargetMapScale = scaleFromZoom(zoom);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomPivot = LLVector2(0, 0);
+ sZoomTimer.start();
+ }
+}
-// static
-void LLWorldMapView::setScale( F32 scale )
+void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y)
{
- if (scale != sMapScale)
- {
- F32 old_scale = sMapScale;
+ mTargetMapScale = scaleFromZoom(zoom);
+ sZoomPivot = LLVector2(x, y);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+}
- sMapScale = scale;
- if (sMapScale <= 0.f)
- {
- sMapScale = 0.1f;
- }
+F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); }
- F32 ratio = (scale / old_scale);
- sPanX *= ratio;
- sPanY *= ratio;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
- }
-}
+F32 LLWorldMapView::getScale() { return mMapScale; }
+// static
+void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; }
+
+// static
+F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; }
+
+void LLWorldMapView::setScale(F32 scale, bool snap)
+{
+ if (scale != mMapScale)
+ {
+ F32 old_scale = mMapScale;
+
+ mMapScale = scale;
+ // Set the scale used when saving the setting
+ sMapScaleSetting = scale;
+ if (mMapScale <= 0.f)
+ {
+ mMapScale = 0.1f;
+ }
+ mMapIterpTime = MAP_ITERP_TIME_CONSTANT;
+ F32 ratio = (scale / old_scale);
+ mPanX *= ratio;
+ mPanY *= ratio;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
+
+ // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here
+ if (!sZoomPivot.isExactlyZero())
+ {
+ LLVector2 relative_pivot;
+ relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0);
+ relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0);
+ LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale);
+ mPanX += zoom_pan_offset.mV[VX];
+ mPanY += zoom_pan_offset.mV[VY];
+ mTargetPanX += zoom_pan_offset.mV[VX];
+ mTargetPanY += zoom_pan_offset.mV[VY];
+ }
+ }
+
+ if (snap)
+ {
+ mTargetMapScale = scale;
+ }
+}
// static
-void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y )
+void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y)
{
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
}
// static
-void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap )
+void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap)
{
- sTargetPanX = (F32)x;
- sTargetPanY = (F32)y;
- if (snap)
- {
- sPanX = sTargetPanX;
- sPanY = sTargetPanY;
- }
- sVisibleTilesLoaded = false;
+ mMapIterpTime = MAP_ITERP_TIME_CONSTANT;
+ mTargetPanX = (F32) x;
+ mTargetPanY = (F32) y;
+ if (snap)
+ {
+ mPanX = mTargetPanX;
+ mPanY = mTargetPanY;
+ }
+ sVisibleTilesLoaded = false;
}
-bool LLWorldMapView::showRegionInfo()
+// static
+void LLWorldMapView::setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time)
{
- return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false);
+ setPan(x, y, snap);
+ mMapIterpTime = interp_time;
}
+bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); }
+
///////////////////////////////////////////////////////////////////////////////////
// HELPERS
@@ -300,9 +366,28 @@ void LLWorldMapView::draw()
mVisibleRegions.clear();
- // animate pan if necessary
- sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f));
- sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f));
+ // animate pan if necessary
+ mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(mMapIterpTime));
+ mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(mMapIterpTime));
+
+ //RN: snaps to zoom value because interpolation caused jitter in the text rendering
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+ bool snap_scale = false;
+ F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME);
+ F32 current_zoom_val = zoomFromScale(mMapScale);
+ F32 target_zoom_val = zoomFromScale(mTargetMapScale);
+ F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp);
+ if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD)
+ {
+ sZoomTimer.stop();
+ snap_scale = true;
+ new_zoom_val = target_zoom_val;
+ }
+ F32 map_scale = scaleFromZoom(new_zoom_val);
+ setScale(map_scale, snap_scale);
const S32 width = getRect().getWidth();
const S32 height = getRect().getHeight();
@@ -310,7 +395,7 @@ void LLWorldMapView::draw()
const F32 half_height = F32(height) / 2.0f;
LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
LLLocalClipRect clip(getLocalRect());
{
@@ -347,15 +432,15 @@ void LLWorldMapView::draw()
// Find x and y position relative to camera's center.
LLVector3d rel_region_pos = origin_global - camera_global;
- F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale;
- F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale;
+ F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale;
+ F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale;
// Coordinates of the sim in pixels in the UI panel
// When the view isn't panned, 0,0 = center of rectangle
- F32 bottom = sPanY + half_height + relative_y;
- F32 left = sPanX + half_width + relative_x;
- F32 top = bottom + sMapScale ;
- F32 right = left + sMapScale ;
+ F32 bottom = mPanY + half_height + relative_y;
+ F32 left = mPanX + half_width + relative_x;
+ F32 top = bottom + mMapScale ;
+ F32 right = left + mMapScale ;
// Discard if region is outside the screen rectangle (not visible on screen)
if ((top < 0.f) || (bottom > height) ||
@@ -416,7 +501,7 @@ void LLWorldMapView::draw()
if (overlayimage)
{
// Inform the fetch mechanism of the size we need
- S32 draw_size = ll_round(sMapScale);
+ S32 draw_size = ll_round(mMapScale);
overlayimage->setKnownDrawSize(ll_round(draw_size * LLUI::getScaleFactor().mV[VX]), ll_round(draw_size * LLUI::getScaleFactor().mV[VY]));
// Draw something whenever we have enough info
if (overlayimage->hasGLTexture())
@@ -444,7 +529,7 @@ void LLWorldMapView::draw()
}
// Draw the region name in the lower left corner
- if (sMapScale >= DRAW_TEXT_THRESHOLD)
+ if (mMapScale >= DRAW_TEXT_THRESHOLD)
{
LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD));
std::string mesg;
@@ -464,7 +549,7 @@ void LLWorldMapView::draw()
LLColor4::white,
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
S32_MAX, //max_chars
- sMapScale, //max_pixels
+ mMapScale, //max_pixels
NULL,
TRUE); //use ellipses
}
@@ -591,7 +676,7 @@ void LLWorldMapView::setVisible(BOOL visible)
void LLWorldMapView::drawMipmap(S32 width, S32 height)
{
// Compute the level of the mipmap to use for the current scale level
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// Set the tile boost level so that unused tiles get to 0
LLWorldMap::getInstance()->equalizeBoostLevels();
@@ -874,7 +959,7 @@ void LLWorldMapView::drawAgents()
void LLWorldMapView::drawFrustum()
{
// Draw frustum
- F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS;
+ F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS;
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
@@ -884,8 +969,8 @@ void LLWorldMapView::drawFrustum()
F32 half_width_pixels = half_width_meters * meters_to_pixels;
// Compute the frustum coordinates. Take the UI scale into account.
- F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]);
- F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]);
+ F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX) * LLUI::getScaleFactor().mV[VX]);
+ F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -942,13 +1027,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos )
LLVector3 pos_local;
pos_local.setVec(relative_pos_global); // convert to floats from doubles
- pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS;
- pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS;
// leave Z component in meters
- pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX;
- pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY;
+ pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX;
+ pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY;
return pos_local;
}
@@ -1019,12 +1104,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
// If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well
LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y )
{
- x -= llfloor((getRect().getWidth() / 2 + sPanX));
- y -= llfloor((getRect().getHeight() / 2 + sPanY));
+ x -= llfloor((getRect().getWidth() / 2 + mPanX));
+ y -= llfloor((getRect().getHeight() / 2 + mPanY));
LLVector3 pos_local( (F32)x, (F32)y, 0.f );
- pos_local *= ( REGION_WIDTH_METERS / sMapScale );
+ pos_local *= ( REGION_WIDTH_METERS / mMapScale );
LLVector3d pos_global;
pos_global.setVec( pos_local );
@@ -1481,7 +1566,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
LLWorldMap::getInstance()->cancelTracking();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// If the zoom level is not too far out already, test hits
if (level <= DRAW_SIMINFO_THRESHOLD)
{
@@ -1598,8 +1683,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask )
{
gFocusMgr.setMouseCapture( this );
- mMouseDownPanX = ll_round(sPanX);
- mMouseDownPanY = ll_round(sPanY);
+ mMouseDownPanX = ll_round(mPanX);
+ mMouseDownPanY = ll_round(mPanY);
mMouseDownX = x;
mMouseDownY = y;
sHandledLastClick = TRUE;
@@ -1614,8 +1699,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
{
// restore mouse cursor
S32 local_x, local_y;
- local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX);
- local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY);
+ local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX);
+ local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY);
LLRect clip_rect = getRect();
clip_rect.stretch(-8);
clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y);
@@ -1643,7 +1728,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
void LLWorldMapView::updateVisibleBlocks()
{
- if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD)
+ if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD)
{
// If we're zoomed out too much, we just don't load all those sim info: too much!
return;
@@ -1659,16 +1744,16 @@ void LLWorldMapView::updateVisibleBlocks()
const F32 half_height = F32(height) / 2.0f;
// Compute center into sim grid coordinates
- S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
- S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
+ S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
+ S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
// Compute the boundaries into sim grid coordinates
- S32 world_left = world_center_x - S32(half_width / sMapScale) - 1;
- S32 world_right = world_center_x + S32(half_width / sMapScale) + 1;
- S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1;
- S32 world_top = world_center_y + S32(half_height / sMapScale) + 1;
+ S32 world_left = world_center_x - S32(half_width / mMapScale) - 1;
+ S32 world_right = world_center_x + S32(half_width / mMapScale) + 1;
+ S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1;
+ S32 world_top = world_center_y + S32(half_height / mMapScale) + 1;
- //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
+ //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top);
}
@@ -1689,10 +1774,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask )
F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY());
// Set pan to value at start of drag + offset
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
gViewerWindow->moveCursorToCenter();
}
@@ -1789,4 +1874,8 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
return FALSE;
}
+// static
+F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; }
+// static
+F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); }
diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h
index a2a6dc53fb..ce8af76a82 100644
--- a/indra/newview/llworldmapview.h
+++ b/indra/newview/llworldmapview.h
@@ -67,12 +67,22 @@ public:
bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track);
void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id);
- // Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered)
- static void setScale( F32 scale );
- static void translatePan( S32 delta_x, S32 delta_y );
- static void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered)
+ // Zoom is used for UI and will interpolate the map scale over multiple frames.
+ void zoom(F32 zoom);
+ void zoomWithPivot(F32 zoom, S32 x, S32 y);
+ F32 getZoom();
+ // Scale is a linear scaling factor of in-world coordinates
+ F32 getScale();
+ // setScaleSetting/getScaleSetting are for the default map setting on login
+ static void setScaleSetting(F32 scaleSetting);
+ static F32 getScaleSetting();
+ // Pan is in pixels relative to the center of the map.
+ void translatePan( S32 delta_x, S32 delta_y );
+ void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ void setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time);
// Return true if the current scale level is above the threshold for accessing region info
- static bool showRegionInfo();
+ bool showRegionInfo();
LLVector3 globalPosToView(const LLVector3d& global_pos);
LLVector3d viewPosToGlobal(S32 x,S32 y);
@@ -153,14 +163,12 @@ public:
static LLUIImagePtr sForSaleImage;
static LLUIImagePtr sForSaleAdultImage;
- static F32 sMapScale; // scale = size of a region in pixels
-
BOOL mItemPicked;
- static F32 sPanX; // in pixels
- static F32 sPanY; // in pixels
- static F32 sTargetPanX; // in pixels
- static F32 sTargetPanY; // in pixels
+ F32 mPanX; // in pixels
+ F32 mPanY; // in pixels
+ F32 mTargetPanX; // in pixels
+ F32 mTargetPanY; // in pixels
static S32 sTrackingArrowX;
static S32 sTrackingArrowY;
static bool sVisibleTilesLoaded;
@@ -194,6 +202,19 @@ public:
private:
void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right);
+
+ void setScale(F32 scale, bool snap = true);
+
+ static F32 scaleFromZoom(F32 zoom);
+ static F32 zoomFromScale(F32 scale);
+
+ F32 mMapScale;
+ F32 mTargetMapScale;
+ static F32 sMapScaleSetting;
+ static LLVector2 sZoomPivot;
+ static LLFrameTimer sZoomTimer;
+
+ F32 mMapIterpTime;
};
#endif
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 32c8ce66a0..5c56a1d34f 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -40,6 +40,7 @@
#include "httpoptions.h"
#include "httpheaders.h"
#include "bufferarray.h"
+#include "llversioninfo.h"
#include "llviewercontrol.h"
// Have to include these last to avoid queue redefinition!
@@ -378,6 +379,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+ std::string user_agent = llformat("%s %d.%d.%d (%d)",
+ LLVersionInfo::instance().getChannel().c_str(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
+ LLVersionInfo::instance().getBuild());
+
+ httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+
///* Setting the DNS cache timeout to -1 disables it completely.
//This might help with bug #503 */
//httpOpts->setDNSCacheTimeout(-1);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 54e6c6fc6e..96ba80dacc 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7238,6 +7238,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
mResetVertexBuffers = false;
mCubeVB = NULL;
+ mDeferredVB = NULL;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -7271,10 +7272,11 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPathingLib::getInstance()->cleanupVBOManager();
}
LLVOPartGroup::destroyGL();
+ gGL.resetVertexBuffer();
SUBSYSTEM_CLEANUP(LLVertexBuffer);
- if (LLVertexBuffer::sGLCount > 0)
+ if (LLVertexBuffer::sGLCount != 0)
{
LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
}
@@ -7295,6 +7297,10 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+ gGL.initVertexBuffer();
+
+ mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
+ mDeferredVB->allocateBuffer(8, 0, true);
LLVOPartGroup::restoreGL();
}
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 1085972d9e..c3ce83e834 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -514,8 +514,8 @@
name="MapFrustumColor"
reference="White_10" />
<color
- name="MapFrustumRotatingColor"
- value="1 1 1 0.2" />
+ name="MapParcelOutlineColor"
+ value="1 1 0 0.5" />
<color
name="MapTrackColor"
reference="Red" />
@@ -607,10 +607,10 @@
value="0 0 0 1" />
<color
name="NetMapGroupOwnAboveWater"
- reference="Purple" />
+ value="0.85 0 0.85 1" />
<color
name="NetMapGroupOwnBelowWater"
- value="0.78 0 0.78 1" />
+ value="0.63 0 0.63 1" />
<color
name="NetMapOtherOwnAboveWater"
value="0.24 0.24 0.24 1" />
@@ -619,10 +619,10 @@
value="0.12 0.12 0.12 1" />
<color
name="NetMapYouOwnAboveWater"
- value="0 1 1 1" />
+ value="0 0.85 0.85 1" />
<color
name="NetMapYouOwnBelowWater"
- value="0 0.78 0.78 1" />
+ value="0 0.63 0.63 1" />
<color
name="NotifyBoxColor"
value="LtGray" />
diff --git a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
deleted file mode 100644
index 3bb7f7183c..0000000000
--- a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 0d0fc5c58e..4429a1677e 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -67,8 +67,6 @@ with the same filename but different name
<texture name="Audio_Off" file_name="icons/Audio_Off.png" preload="false" />
<texture name="Audio_Press" file_name="icons/Audio_Press.png" preload="false" />
- <texture name="Avaline_Icon" file_name="icons/avaline_default_icon.jpg" preload="true" />
-
<texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" />
<texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />
diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml
index 45946fd222..c8a3ad328e 100644
--- a/indra/newview/skins/default/xui/da/panel_region_texture.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml
@@ -7,8 +7,8 @@
ukendt
</text>
<text name="detail_texture_text">
- Terræn teksturer (kræver 512x512, 24 bit .tga filer)
- </text>
+ Terræn teksturer (kræver 1024x1024, 24 bit .tga filer)
+ </text>
<text name="height_text_lbl">
1 (Lav)
</text>
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 5f1bf73f26..e4f99d14e9 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -443,9 +443,6 @@ Prøv venligst om lidt igen.
<string name="GroupNameNone">
(ingen)
</string>
- <string name="AvalineCaller">
- Avaline opkalder [ORDER]
- </string>
<string name="AssetErrorNone">
Ingen fejl
</string>
diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
index 7801be30e4..42ba5b5269 100644
--- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Obere Terraingrenze" name="terrain_raise_spin"/>
<spinner label="Untere Terraingrenze" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 512x512)
- </text>
+ Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 1024x1024)
+ </text>
<text name="height_text_lbl">
1 (niedrig)
</text>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 4625c48714..0120f7e5bd 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -691,9 +691,6 @@ nächsten Eigentümer angehängt werden.
<string name="GroupNameNone">
(keiner)
</string>
- <string name="AvalineCaller">
- Avaline-Anfrufer [ORDER]
- </string>
<string name="AssetErrorNone">
Kein Fehler
</string>
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index dee5e29a3c..4678d65b85 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1893,7 +1893,29 @@ Only large parcels can be listed in search.
left="110"
name="parcel_enable_voice_channel_local"
width="300" />
- </panel>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="media"
+ top_pad="10"
+ width="100">
+ Media:
+ </text>
+ <check_box
+ height="16"
+ label="Obscure MOAP"
+ layout="topleft"
+ left="110"
+ left_pad="0"
+ name="obscure_moap"
+ tool_tip="Media on a prim located outside the parcel should not play automatically for an agent within this parcel and vice versa."
+ width="300" />
+ </panel>
<panel
border="true"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
index bba30626b2..632daaec7e 100644
--- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml
+++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
@@ -88,6 +88,7 @@
spellcheck="true"
text_readonly_color="white"
text_type="ascii_with_newline"
+ commit_on_focus_lost="true"
top_pad="5"
width="290"
wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
index b8893e11d9..9639e70544 100644
--- a/indra/newview/skins/default/xui/en/floater_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
@@ -16,11 +16,35 @@
width="200">
<floater.string
name="ToolTipMsg">
- [REGION](Double-click to open Map, shift-drag to pan)
+ [PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG]
+ </floater.string>
+ <floater.string
+ name="ParcelNameMsg">
+ [PARCEL_NAME]
+ </floater.string>
+ <floater.string
+ name="ParcelSalePriceMsg">
+ Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²)
+ </floater.string>
+ <floater.string
+ name="ParcelSaleAreaMsg">
+ Area: [AREA]m²
+ </floater.string>
+ <floater.string
+ name="ParcelOwnerMsg">
+ Owner: [PARCEL_OWNER]
+ </floater.string>
+ <floater.string
+ name="RegionNameMsg">
+ Region: [REGION_NAME]
</floater.string>
<floater.string
- name="AltToolTipMsg">
- [REGION](Double-click to teleport, shift-drag to pan)
+ name="ToolTipHintMsg">
+ Double-click to open map
+ </floater.string>
+ <floater.string
+ name="AltToolTipHintMsg">
+ Double-click to teleport
</floater.string>
<floater.string name="mini_map_caption">
Mini-map
@@ -37,105 +61,73 @@
<text
type="string"
length="1"
- bottom="218"
label="N"
layout="topleft"
- left="0"
name="floater_map_north"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
N
</text>
<text
type="string"
length="1"
- bottom="218"
label="E"
layout="topleft"
- left="0"
name="floater_map_east"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
E
</text>
<text
type="string"
length="1"
- bottom="205"
label="W"
layout="topleft"
- left="0"
name="floater_map_west"
- right="11"
- text_color="1 1 1 0.7"
- top="175">
+ text_color="1 1 1 0.7">
W
</text>
<text
type="string"
length="1"
- bottom="218"
label="S"
layout="topleft"
- left="0"
name="floater_map_south"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
S
</text>
<text
type="string"
length="1"
- bottom="218"
label="SE"
layout="topleft"
- left="0"
name="floater_map_southeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SE
</text>
<text
type="string"
length="1"
- bottom="218"
label="NE"
layout="topleft"
- left="0"
name="floater_map_northeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NE
</text>
<text
type="string"
length="1"
- bottom="218"
label="SW"
layout="topleft"
- left="0"
name="floater_map_southwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SW
</text>
<text
type="string"
length="1"
- bottom="218"
label="NW"
layout="topleft"
- left="0"
name="floater_map_northwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NW
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index e499ddbc2f..21c894d3af 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -830,6 +830,7 @@
<combo_item name="physics_medium"> Medium </combo_item>
<combo_item name="physics_low"> Low </combo_item>
<combo_item name="physics_lowest"> Lowest </combo_item>
+ <combo_item name="physics_bounding_box"> Bounding Box </combo_item>
<combo_item name="load_from_file"> From file </combo_item>
</combo_box>
<line_editor
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index d07e3cb31b..343e72f057 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -11,6 +11,11 @@
name="Screenshot">
Screenshot
</floater.string>
+ <floater.string
+ name="chat_report_format">
+Time: [MSG_TIME]
+Text: [MSG_DESCRIPTION]
+ </floater.string>
<texture_picker
allow_no_texture="true"
default_image_name="None"
@@ -19,7 +24,7 @@
layout="topleft"
left="60"
name="screenshot"
- top="15"
+ top="20"
width="220" />
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index 45e11fc836..c965a4427c 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -733,6 +733,7 @@
name="zoom_icon"
top_pad="7"
width="16" ></icon>
+ <!-- NOTE: min_val for zoom slider is hardcoded for performance reasons -->
<slider
follows="left|bottom"
height="16"
@@ -740,7 +741,7 @@
initial_value="-2"
left_pad="0"
layout="topleft"
- max_val="0"
+ max_val="4"
min_val="-8"
name="zoom slider"
show_text="false"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
index 05ab4d35a0..9f394a4c74 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -96,6 +96,13 @@
name="Pay">
<on_click function="AvatarIcon.Action" parameter="pay" />
</menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <on_click function="AvatarIcon.Action" parameter="report_abuse" />
+ <on_enable function="AvatarIcon.Enable" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index ed362b36e5..59e6106a28 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -132,6 +132,13 @@
<on_click function="Avatar.DoToSelected" parameter="pay" />
<on_enable function="Avatar.EnableItem" parameter="can_pay" />
</menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="report_abuse">
+ <on_click function="Avatar.DoToSelected" parameter="report_abuse" />
+ <on_enable function="Avatar.EnableItem" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
index 43287c6ec3..b38fae4404 100644
--- a/indra/newview/skins/default/xui/en/menu_im_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -79,6 +79,13 @@
</menu_item_call>
<menu_item_separator
layout="topleft"/>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <on_click function="Avatar.GearDoToSelected" parameter="report_abuse" />
+ <on_enable function="Avatar.EnableGearItem" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml
index ea263d05ce..2715c916d4 100644
--- a/indra/newview/skins/default/xui/en/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml
@@ -8,63 +8,109 @@
top="724"
visible="false"
width="128">
- <menu_item_call
- label="Zoom Close"
- name="Zoom Close">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check
+ label="Zoom very close"
+ name="Zoom very close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
+ parameter="very close" />
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="very close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom close"
+ name="Zoom close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="close" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Medium"
- name="Zoom Medium">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom medium"
+ name="Zoom medium">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="medium" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Far"
- name="Zoom Far">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="medium" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom far"
+ name="Zoom far">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="far" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Default"
- name="Zoom Default">
- <menu_item_call.on_click
- function="Minimap.Zoom"
- parameter="default" />
- </menu_item_call>
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="far" />
+ </menu_item_check>
<menu_item_separator />
<menu_item_check
- label="Rotate Map"
- name="Rotate Map">
+ label="North at top"
+ name="North at top">
<menu_item_check.on_check
- control="MiniMapRotate" />
+ function="Minimap.MapOrientation.Check"
+ parameter="north_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapRotate" />
+ function="Minimap.MapOrientation.Set"
+ parameter="north_at_top" />
</menu_item_check>
<menu_item_check
- label="Auto Center"
- name="Auto Center">
+ label="Camera at top"
+ name="Camera at top">
<menu_item_check.on_check
- control="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Check"
+ parameter="camera_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Set"
+ parameter="camera_at_top" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_check
+ label="Show parcel boundaries"
+ name="Show parcel boundaries">
+ <menu_item_check.on_check
+ control="MiniMapShowPropertyLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapShowPropertyLines" />
</menu_item_check>
<menu_item_separator />
+ <menu_item_check
+ label="Auto-center map"
+ name="Auto-center map">
+ <menu_item_check.on_check
+ control="MiniMapAutoCenter" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapAutoCenter" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_call
+ label="Re-center map"
+ name="Re-center map">
+ <menu_item_call.on_click
+ function="Minimap.Center.Activate" />
+ </menu_item_call>
<menu_item_call
- label="Stop Tracking"
- name="Stop Tracking">
+ label="Stop tracking"
+ name="Stop tracking">
<menu_item_call.on_click
function="Minimap.Tracker"
parameter="task_properties" />
</menu_item_call>
<menu_item_separator />
<menu_item_call
+ label="About Land"
+ name="About Land">
+ <menu_item_call.on_click
+ function="Minimap.AboutLand" />
+ </menu_item_call>
+ <menu_item_call
label="World Map"
name="World Map">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
index e8b6116026..5ca8be2123 100644
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -29,7 +29,14 @@
name="remove_friend">
<menu_item_call.on_click
function="Url.RemoveFriend" />
- </menu_item_call>
+ </menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="report_abuse">
+ <menu_item_call.on_click
+ function="Url.ReportAbuse" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index e2d088c697..58584345a9 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -422,7 +422,9 @@
</menu_item_call>
<menu_item_call
label="Stop animations"
- name="Stop Animating My Avatar">
+ name="Stop Animating My Avatar"
+ allow_key_repeat="true"
+ shortcut="alt|shift|A">
<menu_item_call.on_click
function="Tools.StopAllAnimations" />
</menu_item_call>
@@ -2646,6 +2648,12 @@ function="World.EnvPreset"
function="Advanced.ForceErrorBadMemoryAccess" />
</menu_item_call>
<menu_item_call
+ label="Force Bad Memory Access in Coroutine"
+ name="Force Bad Memory Access in Coroutine">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorBadMemoryAccessCoro" />
+ </menu_item_call>
+ <menu_item_call
label="Force Infinite Loop"
name="Force Infinite Loop">
<menu_item_call.on_click
@@ -3325,6 +3333,18 @@ function="World.EnvPreset"
function="Advanced.DropPacket" />
</menu_item_call>
</menu>
+ <menu
+ create_jump_keys="true"
+ label="Cache"
+ name="Cache"
+ tear_off="true">
+ <menu_item_call
+ label="Purge Disk Cache"
+ name="Purge Disk Cache">
+ <menu_item_call.on_click
+ function="Advanced.PurgeDiskCache" />
+ </menu_item_call>
+ </menu>
<menu_item_call
label="Dump Scripted Camera"
name="Dump Scripted Camera">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 998c7a08d1..1ddec93668 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1521,7 +1521,7 @@ Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<notification
icon="alert.tga"
name="ProfileUnpublishedClassified"
- type="alert">
+ type="alertmodal">
You have unpublished classifieds. They will be lost if you close the window.
<tag>confirm</tag>
<usetemplate
@@ -1533,7 +1533,7 @@ Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<notification
icon="alert.tga"
name="ProfileUnsavedChanges"
- type="alert">
+ type="alertmodal">
You have usaved changes.
<tag>confirm</tag>
<tag>save</tag>
@@ -3945,7 +3945,7 @@ Are you sure you want to return objects owned by [USER_NAME]?
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH].
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
<tag>fail</tag>
</notification>
@@ -3956,7 +3956,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y].
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
</notification>
<notification
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index aa1b929412..54f038c24f 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -155,6 +155,7 @@
right="-3"
mouse_opaque="true"
name="speaking_indicator"
+ tool_tip="Voice volume"
visible="true"
width="20" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index 8243c2715d..2aaea04a6d 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -86,7 +86,7 @@
name="detail_texture_text"
top="110"
width="300">
- Terrain Textures (requires 512x512, 24 bit .tga files)
+ Terrain Textures (requires 1024x1024, 24 bit .tga files)
</text>
<texture_picker
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index 0cbd7fe2dd..c7052bb737 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -550,10 +550,7 @@
top_pad="4"
tool_tip="Add Media"
label="Choose..."
- width="85">
- <button.commit_callback
- function="BuildTool.AddMedia"/>
- </button>
+ width="85"/>
<button
follows="top|left"
height="18"
@@ -563,10 +560,7 @@
tool_tip="Delete this media texture"
top_delta="0"
label="Remove"
- width="85">
- <button.commit_callback
- function="BuildTool.DeleteMedia"/>
- </button>
+ width="85"/>
<button
follows="left|top"
height="18"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 8c2db9bde3..6f95e282ca 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -348,8 +348,6 @@ can be attached to notecards.
<!-- Group name: text shown for LLUUID::null -->
<string name="GroupNameNone">(none)</string>
- <string name="AvalineCaller">Avaline Caller [ORDER]</string>
-
<!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. -->
<string name="AssetErrorNone">No error</string>
<string name="AssetErrorRequestFailed">Asset request: failed</string>
@@ -2342,6 +2340,14 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
An error occurred while opening Marketplace Listings.
If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
</string>
+ <string name="InventoryMarketplaceConnectionError">
+Marketplace Listings failed to connect.
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
+ </string>
+ <string name="InventoryMarketplaceConnectionErrorReason">
+Marketplace Listings failed to connect. Reason: [REASON]
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
+ </string>
<string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string>
<string name="InventoryMarketplaceListingsNoItemsTooltip"></string>
<string name="InventoryMarketplaceListingsNoItems">
diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
index cb6c03dbb5..9aba5299cb 100644
--- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
@@ -12,8 +12,8 @@ del terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Límite de bajada del
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas del terreno (requiere archivos .tga de 512x512, 24 bits)
- </text>
+ Texturas del terreno (requiere archivos .tga de 1024x1024, 24 bits)
+ </text>
<text name="height_text_lbl">
1 (bajo)
</text>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 20f7f81962..5a03e65b49 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -680,9 +680,6 @@ pueden adjuntarse a las notas.
<string name="GroupNameNone">
(ninguno)
</string>
- <string name="AvalineCaller">
- Avaline: [ORDER]
- </string>
<string name="AssetErrorNone">
No hay ningún error
</string>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
index 97f486d3a3..bbab00ca24 100644
--- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terrain" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite d&apos;abaissement
du terrain" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Textures du terrain (fichiers .tga 512 x 512, 24 bit requis)
- </text>
+ Textures du terrain (fichiers .tga 1024 x 1024, 24 bit requis)
+ </text>
<text name="height_text_lbl">
1 (Bas)
</text>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 943d1635cd..21825c6b2f 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -692,9 +692,6 @@ peuvent être joints aux notes.
<string name="GroupNameNone">
(aucun)
</string>
- <string name="AvalineCaller">
- Appelant Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Aucune erreur
</string>
diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
index c61ac3ecce..e08c55f63b 100644
--- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite di abbassamento
del terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texture terreno (richiede file 512x512, 24 bit .tga)
- </text>
+ Texture terreno (richiede file 1024x1024, 24 bit .tga)
+ </text>
<text name="height_text_lbl">
1 (basso)
</text>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 52f5f7af18..1ebdadb930 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -685,9 +685,6 @@ possono essere allegati ai biglietti.
<string name="GroupNameNone">
(nessuno)
</string>
- <string name="AvalineCaller">
- Chiamante Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Nessun errore
</string>
diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
index fb853c1925..c1080a7d7b 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="地形の上昇限度" name="terrain_raise_spin"/>
<spinner label="地形の下降限度" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形テクスチャ(512x512 の 24 bit .tga ファイル)
- </text>
+ 地形テクスチャ(1024x1024 の 24 bit .tga ファイル)
+ </text>
<text name="height_text_lbl">
1(低)
</text>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index c5bba021ac..d90772ab0a 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -691,9 +691,6 @@ support@secondlife.com にお問い合わせください。
<string name="GroupNameNone">
(なし)
</string>
- <string name="AvalineCaller">
- Avaline コール [ORDER]
- </string>
<string name="AssetErrorNone">
エラーなし
</string>
diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
index f086a52dcd..2d4286334f 100644
--- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
@@ -7,7 +7,7 @@
<spinner label="Górny limit terenu" name="terrain_raise_spin" />
<spinner label="Dolny limit terenu" name="terrain_lower_spin" />
<text name="detail_texture_text">
- Tekstury terenu (512x512 / 1024x1024, 24 bitowy plik .tga)
+ Tekstury terenu (1024x1024, 24 bitowy plik .tga)
</text>
<text name="height_text_lbl">
1 (Nisko)
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index 2b182dc3cc..90d2d86c02 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -596,9 +596,6 @@ Spróbuj zalogować się ponownie za minutę.
<string name="GroupNameNone">
(brak danych)
</string>
- <string name="AvalineCaller">
- Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Brak błędu
</string>
diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
index 74330a8946..1d312aeed9 100644
--- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite mais baixo do
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas de terreno (exige arquivos .tga 512x512, 24 bit)
- </text>
+ Texturas de terreno (exige arquivos .tga 1024x1024, 24 bit)
+ </text>
<text name="height_text_lbl">
1 (Baixo)
</text>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index 7a425a2622..ae452d6a4d 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -47,7 +47,7 @@ Placa de vídeo: [GRAPHICS_CARD_VENDOR]
Placa gráfica: [GRAPHICS_CARD]
</string>
<string name="AboutDriver">
- Versão do driver de vídeo Windows: [GRAPHICS_CARD_VENDOR]
+ Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION]
</string>
<string name="AboutOGL">
Versão do OpenGL: [OPENGL_VERSION]
@@ -645,9 +645,6 @@ ser anexado às anotações.
<string name="GroupNameNone">
(nenhum)
</string>
- <string name="AvalineCaller">
- Interlocutor Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Nenhum erro
</string>
diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
index 5e3de180f9..331ba889d8 100644
--- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
@@ -14,7 +14,7 @@
<label name="favorites_bar_label" tool_tip="Перетаскивайте сюда закладки, чтобы было удобнее переходить в любимые места в Second Life!">
Избранное
</label>
- <more_button name="&gt;&gt;" tool_tip="Показать больше избранного">
+ <more_button name="&gt;&gt;" tool_tip="Показать больше избранного" width="60">
Больше ▼
</more_button>
</favorites_bar>
diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
index af25565226..76b4f513a8 100644
--- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Верх. точка ландшафта" name="terrain_raise_spin"/>
<spinner label="Ниж. точка ландшафта" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Текстуры ландшафта (требования: 512x512, 24-битные, TGA)
- </text>
+ Текстуры ландшафта (требования: 1024x1024, 24-битные, TGA)
+ </text>
<text name="height_text_lbl">
1 (Низ)
</text>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index c0dc32340a..61d836a2d1 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -689,9 +689,6 @@ support@secondlife.com.
<string name="GroupNameNone">
(нет)
</string>
- <string name="AvalineCaller">
- [ORDER] абонента Avaline
- </string>
<string name="AssetErrorNone">
Ошибок нет
</string>
diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
index 8d43e3fb5a..ae9bc33bfa 100644
--- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
@@ -14,7 +14,7 @@
<label name="favorites_bar_label" tool_tip="Second Life içerisinde sık kullandığınız yerlere hızla erişmek için Yer İmlerini buraya sürükleyin!">
Favoriler Çubuğu
</label>
- <more_button name="&gt;&gt;" tool_tip="Favorilerimden daha çok göster">
+ <more_button name="&gt;&gt;" tool_tip="Favorilerimden daha çok göster" width="65">
Daha Fazla ▼
</more_button>
</favorites_bar>
diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
index 3226ee008e..e25047301d 100644
--- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Yüzey Yükslt. Limiti" name="terrain_raise_spin"/>
<spinner label="Yüzey Alçatma Limiti" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir)
- </text>
+ Yüzey Dokuları (1024x1024, 24 bit .tga dosyalar gerektirir)
+ </text>
<text name="height_text_lbl">
1 (Düşük)
</text>
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index d1076b8b79..e709a4c5d6 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -689,9 +689,6 @@ kartlarına eklenebilir.
<string name="GroupNameNone">
(hiçbiri)
</string>
- <string name="AvalineCaller">
- Avaline Arayanı [ORDER]
- </string>
<string name="AssetErrorNone">
Hata yok
</string>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
index 85e759e445..81bce46876 100644
--- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="地形提升限制" name="terrain_raise_spin"/>
<spinner label="地形降低限制" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形材質(須 512x512,24 位元 .tga 檔格式)
+ 地形材質(須 1024x1024,24 位元 .tga 檔格式)
</text>
<text name="height_text_lbl">
1(低)
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index a4e1b21ce6..bdb16c9bf1 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -685,9 +685,6 @@ http://secondlife.com/viewer-access-faq
<string name="GroupNameNone">
(無)
</string>
- <string name="AvalineCaller">
- Avaline 通話者 [ORDER]
- </string>
<string name="AssetErrorNone">
無錯誤
</string>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index de5ac5ed3d..59eb18b734 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -568,6 +568,7 @@ class WindowsManifest(ViewerManifest):
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
@@ -954,6 +955,7 @@ class DarwinManifest(ViewerManifest):
self.path("licenses-mac.txt", dst="licenses.txt")
self.path("featuretable_mac.txt")
+ self.path("cube.dae")
self.path("SecondLife.nib")
with self.prefix(src=pkgdir,dst=""):
@@ -1427,6 +1429,7 @@ class LinuxManifest(ViewerManifest):
print("Skipping llcommon.so (assuming llcommon was linked statically)")
self.path("featuretable_linux.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index 8a7e6407ed..5d50d1e182 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -257,21 +257,25 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
if (printable_params["wait_for_updater"].asBoolean())
{
std::string reason_response = responses["data"]["reason"].asString();
- if (reason_response == "update") // No point waiting if not an update
+ // Timeout should produce the isUndefined() object passed here.
+ if (reason_response == "update")
{
- // Timeout should produce the isUndefined() object passed here.
LL_INFOS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD());
-
- if (updater.isUndefined())
- {
- LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
- << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
- }
+ }
+ else
+ {
+ LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
+ updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 3, LLSD());
+ }
+ if (updater.isUndefined())
+ {
+ LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
}
}