summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Kundiman <erik@megapahit.org>2025-12-04 13:11:22 +0800
committerErik Kundiman <erik@megapahit.org>2025-12-04 13:11:22 +0800
commitd9d932f6375df28dbc59088fc09cd986043651d0 (patch)
tree0dae07bf66d2e8b3ad25a1a9ec994b303a5f01f8
parentdcc927e1d29b2b927ae27f8f50a1dcadb4488c80 (diff)
parent780b5c3bd9a2a97790efc1169817f1fc574f3387 (diff)
Merge branch '2025.08'
-rw-r--r--.git-blame-ignore-revs1
-rw-r--r--.github/dependabot.yaml7
-rw-r--r--.github/workflows/build.yaml9
-rw-r--r--.github/workflows/pre-commit.yaml4
-rw-r--r--.pre-commit-config.yaml8
-rw-r--r--README.md2
-rw-r--r--autobuild.xml84
-rwxr-xr-xbuild.sh2
-rw-r--r--indra/CMakeLists.txt1
-rw-r--r--indra/cmake/APR.cmake5
-rw-r--r--indra/cmake/CMakeLists.txt1
-rw-r--r--indra/cmake/LLPhysicsExtensions.cmake23
-rw-r--r--indra/cmake/VHACD.cmake30
-rw-r--r--indra/llappearance/llpolymesh.cpp1
-rw-r--r--indra/llappearance/lltexlayer.cpp5
-rw-r--r--indra/llappearance/lltexlayerparams.cpp5
-rw-r--r--indra/llcommon/llfile.cpp390
-rw-r--r--indra/llcommon/llfile.h108
-rw-r--r--indra/llcommon/llleap.cpp11
-rw-r--r--indra/llcommon/llqueuedthread.cpp34
-rw-r--r--indra/llcommon/llsys.cpp8
-rw-r--r--indra/llcommon/tests/llprocess_test.cpp44
-rwxr-xr-xindra/llcorehttp/llhttpconstants.cpp2
-rwxr-xr-xindra/llcorehttp/llhttpconstants.h2
-rw-r--r--indra/llcrashlogger/llcrashlogger.cpp4
-rw-r--r--indra/llfilesystem/lldir_utils_objc.mm28
-rw-r--r--indra/llfilesystem/llfilesystem.cpp3
-rw-r--r--indra/llimagej2coj/llimagej2coj.cpp18
-rw-r--r--indra/llinventory/llpermissions.cpp1
-rw-r--r--indra/llmath/llvolume.cpp28
-rw-r--r--indra/llmessage/llcoproceduremanager.cpp33
-rw-r--r--indra/llphysicsextensionsos/CMakeLists.txt47
-rw-r--r--indra/llphysicsextensionsos/LLPathingLibStubImpl.cpp109
-rw-r--r--indra/llphysicsextensionsos/LLPathingLibStubImpl.h78
-rw-r--r--indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.cpp51
-rw-r--r--indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.h46
-rw-r--r--indra/llphysicsextensionsos/llconvexdecomposition.cpp84
-rw-r--r--indra/llphysicsextensionsos/llconvexdecomposition.h231
-rw-r--r--indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp492
-rw-r--r--indra/llphysicsextensionsos/llconvexdecompositionvhacd.h339
-rw-r--r--indra/llphysicsextensionsos/llpathinglib.cpp83
-rw-r--r--indra/llphysicsextensionsos/llpathinglib.h187
-rw-r--r--indra/llphysicsextensionsos/llphysicsextensions.cpp78
-rw-r--r--indra/llphysicsextensionsos/llphysicsextensions.h59
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp18
-rw-r--r--indra/llplugin/slplugin/slplugin-objc.mm96
-rw-r--r--indra/llprimitive/CMakeLists.txt11
-rw-r--r--indra/llprimitive/llgltfmaterial.cpp31
-rw-r--r--indra/llprimitive/llgltfmaterial.h8
-rw-r--r--indra/llprimitive/llmodel.cpp4
-rw-r--r--indra/llprimitive/llmodel.h3
-rw-r--r--indra/llrender/llcubemap.cpp10
-rw-r--r--indra/llrender/llglslshader.cpp3
-rw-r--r--indra/llrender/llglslshader.h1
-rw-r--r--indra/llrender/llimagegl.cpp6
-rw-r--r--indra/llrender/llshadermgr.cpp1
-rw-r--r--indra/llui/llaccordionctrl.cpp1
-rw-r--r--indra/llui/llaccordionctrltab.cpp54
-rw-r--r--indra/llui/llemojidictionary.cpp11
-rw-r--r--indra/llui/llemojihelper.cpp10
-rw-r--r--indra/llui/llfloater.cpp2
-rw-r--r--indra/llui/llfolderview.cpp1
-rw-r--r--indra/llui/llfolderviewitem.cpp30
-rw-r--r--indra/llui/llfolderviewitem.h1
-rw-r--r--indra/llui/lltextbase.cpp52
-rw-r--r--indra/llui/lltextbase.h5
-rw-r--r--indra/llui/lltoolbar.cpp2
-rw-r--r--indra/llui/lltoolbar.h2
-rw-r--r--indra/llui/llviewereventrecorder.cpp2
-rw-r--r--indra/llwebrtc/llwebrtc.cpp65
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h5
-rw-r--r--indra/llwindow/llopenglview-objc.mm318
-rw-r--r--indra/llwindow/llwindow.h1
-rw-r--r--indra/llwindow/llwindowcallbacks.cpp8
-rw-r--r--indra/llwindow/llwindowcallbacks.h3
-rw-r--r--indra/llwindow/llwindowheadless.h1
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm214
-rw-r--r--indra/llwindow/llwindowmacosx.cpp2
-rw-r--r--indra/llwindow/llwindowmacosx.h1
-rw-r--r--indra/llwindow/llwindowsdl.cpp2
-rw-r--r--indra/llwindow/llwindowsdl.h2
-rw-r--r--indra/llwindow/llwindowwin32.cpp52
-rw-r--r--indra/llwindow/llwindowwin32.h2
-rw-r--r--indra/newview/CMakeLists.txt41
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml41
-rw-r--r--indra/newview/gltf/accessor.cpp5
-rw-r--r--indra/newview/gltf/llgltfloader.cpp37
-rw-r--r--indra/newview/gltf/llgltfloader.h2
-rw-r--r--indra/newview/licenses-linux.txt33
-rw-r--r--indra/newview/licenses-mac.txt32
-rw-r--r--indra/newview/licenses-win32.txt33
-rw-r--r--indra/newview/llagent.cpp34
-rw-r--r--indra/newview/llagentwearables.cpp23
-rw-r--r--indra/newview/llagentwearables.h1
-rw-r--r--indra/newview/llappdelegate-objc.mm154
-rw-r--r--indra/newview/llappearancemgr.cpp106
-rw-r--r--indra/newview/llappviewer.cpp25
-rw-r--r--indra/newview/llappviewer.h11
-rw-r--r--indra/newview/llappviewermacosx-objc.mm12
-rw-r--r--indra/newview/llappviewerwin32.cpp16
-rw-r--r--indra/newview/llchathistory.cpp10
-rw-r--r--indra/newview/llconversationlog.cpp20
-rw-r--r--indra/newview/lldrawpoolbump.cpp10
-rw-r--r--indra/newview/lleventpoll.cpp64
-rw-r--r--indra/newview/lleventpoll.h25
-rw-r--r--indra/newview/llfeaturemanager.cpp47
-rw-r--r--indra/newview/llfeaturemanager.h2
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp8
-rw-r--r--indra/newview/llfetchedgltfmaterial.h1
-rw-r--r--indra/newview/llfilepicker_mac.mm112
-rw-r--r--indra/newview/llfloateravatarwelcomepack.cpp8
-rw-r--r--indra/newview/llfloaterdestinations.cpp12
-rw-r--r--indra/newview/llfloaterdisplayname.cpp22
-rw-r--r--indra/newview/llfloateremojipicker.cpp9
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp13
-rw-r--r--indra/newview/llfloaterimagepreview.cpp8
-rw-r--r--indra/newview/llfloaterimcontainer.cpp5
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp18
-rw-r--r--indra/newview/llfloaterinspect.cpp3
-rw-r--r--indra/newview/llfloaterland.cpp3
-rw-r--r--indra/newview/llfloatermarketplace.cpp13
-rw-r--r--indra/newview/llfloatermodelpreview.cpp12
-rw-r--r--indra/newview/llfloaterpreference.cpp23
-rw-r--r--indra/newview/llfloaterpreference.h2
-rw-r--r--indra/newview/llfloaterregioninfo.cpp39
-rw-r--r--indra/newview/llfloaterregioninfo.h1
-rw-r--r--indra/newview/llfloatersearch.cpp15
-rw-r--r--indra/newview/llfloatertoybox.cpp2
-rw-r--r--indra/newview/llfloaterurlentry.cpp10
-rw-r--r--indra/newview/llgltfmateriallist.cpp4
-rw-r--r--indra/newview/llimview.cpp4
-rw-r--r--indra/newview/llinventorybridge.cpp26
-rw-r--r--indra/newview/llinventorygallery.cpp24
-rw-r--r--indra/newview/llinventorygallerymenu.cpp35
-rw-r--r--indra/newview/llinventoryitemslist.cpp85
-rw-r--r--indra/newview/llinventoryitemslist.h13
-rw-r--r--indra/newview/lllocalbitmaps.cpp5
-rw-r--r--indra/newview/lllogchat.cpp52
-rw-r--r--indra/newview/lllogininstance.cpp2
-rw-r--r--indra/newview/llmeshrepository.cpp582
-rw-r--r--indra/newview/llmeshrepository.h37
-rw-r--r--indra/newview/llmodelpreview.cpp24
-rw-r--r--indra/newview/llmodelpreview.h2
-rw-r--r--indra/newview/llnotificationlistitem.cpp21
-rw-r--r--indra/newview/lloutfitgallery.cpp1
-rw-r--r--indra/newview/lloutfitslist.cpp8
-rw-r--r--indra/newview/llpanelface.cpp2
-rw-r--r--indra/newview/llpanellandmarkinfo.cpp4
-rw-r--r--indra/newview/llpanelobjectinventory.cpp13
-rw-r--r--indra/newview/llpanelprofile.cpp2
-rw-r--r--indra/newview/llpanelteleporthistory.cpp15
-rw-r--r--indra/newview/llpanelvoicedevicesettings.cpp29
-rw-r--r--indra/newview/llpanelvolume.cpp6
-rw-r--r--indra/newview/llscriptfloater.cpp34
-rw-r--r--indra/newview/llselectmgr.cpp104
-rw-r--r--indra/newview/llsettingspicker.cpp6
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp3
-rw-r--r--indra/newview/llstartup.cpp21
-rw-r--r--indra/newview/llsurface.cpp91
-rw-r--r--indra/newview/llsurface.h14
-rw-r--r--indra/newview/lltexturectrl.cpp20
-rw-r--r--indra/newview/lltexturefetch.cpp38
-rw-r--r--indra/newview/lltoastgroupnotifypanel.cpp19
-rw-r--r--indra/newview/lltoolbarview.cpp29
-rw-r--r--indra/newview/lltoolbarview.h2
-rw-r--r--indra/newview/lltooldraganddrop.cpp215
-rw-r--r--indra/newview/llviewercontrol.cpp18
-rw-r--r--indra/newview/llviewerdisplay.cpp10
-rw-r--r--indra/newview/llviewerinventory.cpp4
-rw-r--r--indra/newview/llviewermedia.cpp118
-rw-r--r--indra/newview/llviewermedia.h7
-rw-r--r--indra/newview/llviewermenu.cpp2
-rw-r--r--indra/newview/llviewermessage.cpp5
-rw-r--r--indra/newview/llviewerobject.cpp130
-rw-r--r--indra/newview/llviewerobject.h4
-rw-r--r--indra/newview/llviewerobjectlist.cpp4
-rw-r--r--indra/newview/llviewerstats.h3
-rw-r--r--indra/newview/llviewertexture.cpp7
-rw-r--r--indra/newview/llviewerwindow.cpp108
-rw-r--r--indra/newview/llviewerwindow.h3
-rw-r--r--indra/newview/llvocache.cpp2
-rw-r--r--indra/newview/llvoicevivox.cpp1
-rw-r--r--indra/newview/llvoicewebrtc.cpp38
-rw-r--r--indra/newview/llvovolume.cpp6
-rw-r--r--indra/newview/llworldmap.cpp18
-rw-r--r--indra/newview/pipeline.cpp27
-rw-r--r--indra/newview/skins/default/xui/da/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/de/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_inspect.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_marketplace.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml149
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml20
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_roles.xml1179
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmark_info.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_place_profile.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_general.xml31
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_move.xml40
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_firstlife.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_secondlife.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_sound_devices.xml4
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_item_info.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/control_table_contents_columns_basic.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_360capture.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about_land.xml28
-rw-r--r--indra/newview/skins/default/xui/ja/floater_add_payment_method.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_avatar_textures.xml16
-rw-r--r--indra/newview/skins/default/xui/ja/floater_bumps.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_god_tools.xml10
-rw-r--r--indra/newview/skins/default/xui/ja/floater_incoming_call.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_inspect.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_joystick.xml30
-rw-r--r--indra/newview/skins/default/xui/ja/floater_lagmeter.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_land_holdings.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_lsl_guide.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_model_preview.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_outgoing_call.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml20
-rw-r--r--indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml24
-rw-r--r--indra/newview/skins/default/xui/ja/floater_performance.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preferences.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preferences_view_advanced.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_scene_load_stats.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_settings_debug.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_snapshot.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_stats.xml26
-rw-r--r--indra/newview/skins/default/xui/ja/floater_tools.xml64
-rw-r--r--indra/newview/skins/default/xui/ja/floater_top_objects.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_translation_settings.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/floater_ui_preview.xml18
-rw-r--r--indra/newview/skins/default/xui/ja/floater_url_entry.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_attachment_other.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_avatar_other.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_conversation.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_gesture_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_participant_list.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_nearby.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_profile_other.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_profile_self.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_settings_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_slurl.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/menu_url_agent.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_url_http.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_viewer.xml58
-rw-r--r--indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml102
-rw-r--r--indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_universal.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_bulk_ban.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_creation_sidetray.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_invite.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_notices.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_roles.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_landmark_info.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_main_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_media_settings_general.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_nearby_media.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_notification_list_item.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_people.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_performance_autoadjustments.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_performance_huds.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_performance_preferences.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_place_profile.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_postcard_settings.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_chat.xml14
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_colors.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_general.xml10
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_sound.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_presets_pulldown.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_covenant.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_environment.xml10
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_terrain.xml10
-rw-r--r--indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_status_bar.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_tools_texture.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/sidepanel_item_info.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/sidepanel_task_info.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml122
-rw-r--r--indra/newview/skins/default/xui/ja/teleport_strings.xml2
-rw-r--r--indra/newview/tests/llworldmap_test.cpp6
-rwxr-xr-xindra/newview/viewer_manifest.py12
-rw-r--r--scripts/code_tools/fix_whitespace.py2
303 files changed, 6743 insertions, 2638 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index c68131402b..ce934f1a21 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -1,6 +1,7 @@
# Replace tabs with spaces
1b68f71348ecf3983b76b40d7940da8377f049b7
33418a77b716e122da9778869cdbabe97c83ff37
+6b974724826a038b0db794460b322eb4921da735
# Trim trailing whitespace
a0b3021bdcf76859054fda8e30abb3ed47749e83
8444cd9562a6a7b755fcb075864e205122354192
diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml
new file mode 100644
index 0000000000..3e3e1df3e2
--- /dev/null
+++ b/.github/dependabot.yaml
@@ -0,0 +1,7 @@
+version: 2
+updates:
+
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: monthly
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 8f89db0923..4c948e5586 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -1,6 +1,7 @@
name: Build
on:
+ workflow_dispatch:
pull_request:
push:
branches: ["main", "release/*", "project/*"]
@@ -85,7 +86,7 @@ jobs:
variants: ${{ matrix.configuration }}
steps:
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
@@ -94,14 +95,14 @@ jobs:
with:
python-version: "3.11"
- name: Checkout build variables
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
with:
repository: secondlife/build-variables
ref: master
path: .build-variables
- name: Checkout master-message-template
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
with:
repository: secondlife/master-message-template
path: .master-message-template
@@ -309,7 +310,7 @@ jobs:
steps:
- name: Sign and package Windows viewer
if: env.AZURE_KEY_VAULT_URI && env.AZURE_CERT_NAME && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET && env.AZURE_TENANT_ID
- uses: secondlife/viewer-build-util/sign-pkg-windows@v2
+ uses: secondlife/viewer-build-util/sign-pkg-windows@v2.0.4
with:
vault_uri: "${{ env.AZURE_KEY_VAULT_URI }}"
cert_name: "${{ env.AZURE_CERT_NAME }}"
diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml
index d626eef38d..726e1cd889 100644
--- a/.github/workflows/pre-commit.yaml
+++ b/.github/workflows/pre-commit.yaml
@@ -11,8 +11,8 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- uses: actions/setup-python@v4
with:
python-version: 3.x
- - uses: pre-commit/action@v3.0.0
+ - uses: pre-commit/action@v3.0.1
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8baac5a81d..d1dcc93976 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -7,14 +7,14 @@ repos:
- id: no-trigraphs
- id: copyright
- id: end-of-file
- files: \.(cpp|c|h|py|glsl|cmake|txt)$
+ files: \.(cpp|c|m|mm|h|py|glsl|cmake|txt)$
exclude: language.txt
- id: indent-with-spaces
- files: \.(cpp|c|h|inl|py|glsl|cmake)$
+ files: \.(cpp|c|m|mm|h|inl|py|glsl|cmake)$
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v5.0.0
+ rev: v6.0.0
hooks:
- id: check-xml
- id: mixed-line-ending
- id: trailing-whitespace
- files: \.(cpp|c|h|inl|py|glsl|cmake|yaml|sh)$
+ files: \.(cpp|c|m|mm|h|inl|py|glsl|cmake|yaml|sh)$
diff --git a/README.md b/README.md
index 9f6cd51f5c..767458a8a6 100644
--- a/README.md
+++ b/README.md
@@ -64,7 +64,7 @@ $ megapahit
### Fedora
```
-$ sudo dnf install cmake gcc-c++ patch patchelf rpm-build perl-FindBin apr-util-devel boost-devel boost-url expat-devel fltk-devel glm-devel mesa-libGLU-devel hunspell-devel minizip-ng-compat-devel libnghttp2-devel nanosvg-devel openjpeg-devel pipewire-devel pulseaudio-libs-devel SDL2-devel vlc-devel libvorbis-devel libXcursor-devel libXfixes-devel libXinerama-devel xxhash-devel
+$ sudo dnf install cmake gcc-c++ patch patchelf rpm-build perl-FindBin apr-util-devel boost-devel boost-url expat-devel fltk-devel glm-devel mesa-libGLU-devel hunspell-devel minizip-ng-compat-devel libnghttp2-devel nanosvg-devel openjpeg-devel pipewire-devel pulseaudio-libs-devel SDL2-devel v-hacd-devel vlc-devel libvorbis-devel libXcursor-devel libXfixes-devel libXinerama-devel xxhash-devel
$ export LL_BUILD="-O3 -std=c++20 -fPIC -DLL_LINUX=1"
```
build with FMOD Studio: ([register with fmod to get linux package][fmod] and then place the `.tar.gz` in `~/Downloads`)
diff --git a/autobuild.xml b/autobuild.xml
index 26c3532170..a14d477234 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1468,58 +1468,6 @@
<key>name</key>
<string>llphysicsextensions_source</string>
</map>
- <key>llphysicsextensions_stub</key>
- <map>
- <key>platforms</key>
- <map>
- <key>darwin64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>f290b000b31f9e36f2489946cbc99f5e</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/59995/563653/llphysicsextensions_stub-1.0.542456-darwin64-542456.tar.bz2</string>
- </map>
- <key>name</key>
- <string>darwin64</string>
- </map>
- <key>linux64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>711f4ec769e4b5f59ba25ee43c11bcbc</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4724/14846/llphysicsextensions_stub-1.0.504712-linux64-504712.tar.bz2</string>
- </map>
- <key>name</key>
- <string>linux64</string>
- </map>
- <key>windows64</key>
- <map>
- <key>archive</key>
- <map>
- <key>hash</key>
- <string>2e5f1f7046a49d8b0bc295aa878116bc</string>
- <key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/60043/564063/llphysicsextensions_stub-1.0.542456-windows-542456.tar.bz2</string>
- </map>
- <key>name</key>
- <string>windows64</string>
- </map>
- </map>
- <key>license</key>
- <string>internal</string>
- <key>license_file</key>
- <string>LICENSES/llphysicsextensions.txt</string>
- <key>copyright</key>
- <string>Copyright (c) 2010, Linden Research, Inc.</string>
- <key>version</key>
- <string>1.0.542456</string>
- <key>name</key>
- <string>llphysicsextensions_stub</string>
- </map>
<key>llphysicsextensions_tpv</key>
<map>
<key>platforms</key>
@@ -2947,6 +2895,38 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>description</key>
<string>Discord Social SDK</string>
</map>
+ <key>vhacd</key>
+ <map>
+ <key>platforms</key>
+ <map>
+ <key>common</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>140d8fc952a10edb5f2d72ab405336019ef32cadfa64f0cfce76c9de4bc6268cbc87cc8cd89d3417fb78b531d441701afc8d016bafe4bd275df2707f7daf1387</string>
+ <key>hash_algorithm</key>
+ <string>blake2b</string>
+ <key>url</key>
+ <string>https://github.com/AlchemyViewer/3p-vhacd/releases/download/v4.1.0-r2/vhacd-4.1.0-r2-common-18166921729.tar.zst</string>
+ </map>
+ <key>name</key>
+ <string>common</string>
+ </map>
+ </map>
+ <key>license</key>
+ <string>BSD</string>
+ <key>license_file</key>
+ <string>LICENSES/vhacd.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2011, Khaled Mamou</string>
+ <key>version</key>
+ <string>4.1.0-r2</string>
+ <key>name</key>
+ <string>vhacd</string>
+ <key>description</key>
+ <string>Voxelized Hierarchical Approximate Convex Decomposition</string>
+ </map>
</map>
<key>package_description</key>
<map>
diff --git a/build.sh b/build.sh
index 6707b40f82..762eeeba67 100755
--- a/build.sh
+++ b/build.sh
@@ -70,7 +70,7 @@ installer_Darwin()
{
local package_name="$1"
local package_dir="$(build_dir_Darwin)/newview/"
- local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_x86_64\\.dmg\$"
+ local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_universal\\.dmg\$"
# since the additional packages are built after the base package,
# sorting oldest first ensures that the unqualified package is returned
# even if someone makes a qualified name that duplicates the last word of the base name
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index adf30de2b5..6f3ec1cfff 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -70,6 +70,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)
add_subdirectory(${LIBS_OPEN_PREFIX}llmath)
add_subdirectory(${LIBS_OPEN_PREFIX}llmeshoptimizer)
add_subdirectory(${LIBS_OPEN_PREFIX}llmessage)
+add_subdirectory(${LIBS_OPEN_PREFIX}llphysicsextensionsos)
add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive)
add_subdirectory(${LIBS_OPEN_PREFIX}llrender)
add_subdirectory(${LIBS_OPEN_PREFIX}llfilesystem)
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index 4ce0d47f7f..22e94f2c8f 100644
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -45,3 +45,8 @@ if(DARWIN)
endif()
target_include_directories(ll::apr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/apr-1)
+
+# Fix erroneous check for __attribute__ definition introduced with APR 1.7.5, causing lots of "this declaration may not have extern 'C' linkage" errors in VS
+file(READ ${LIBS_PREBUILT_DIR}/include/apr-1/apr.h APR_HEADER_CONTENTS)
+string(REPLACE "#if !(defined(__attribute__) || defined(__has_attribute))" "#if !defined(__attribute__)" APR_HEADER_CONTENTS "${APR_HEADER_CONTENTS}")
+file(WRITE ${LIBS_PREBUILT_DIR}/include/apr-1/apr.h "${APR_HEADER_CONTENTS}")
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index a3233f1c6f..be1e9008e5 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -61,6 +61,7 @@ set(cmake_SOURCE_FILES
UI.cmake
UnixInstall.cmake
Variables.cmake
+ VHACD.cmake
ViewerMiscLibs.cmake
VisualLeakDetector.cmake
LibVLCPlugin.cmake
diff --git a/indra/cmake/LLPhysicsExtensions.cmake b/indra/cmake/LLPhysicsExtensions.cmake
index f9870e4a28..84722b45a7 100644
--- a/indra/cmake/LLPhysicsExtensions.cmake
+++ b/indra/cmake/LLPhysicsExtensions.cmake
@@ -29,17 +29,18 @@ if (HAVOK)
#target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensionsstub)
else()
target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions)
+ target_compile_definitions( llphysicsextensions_impl INTERFACE LL_HAVOK=1 )
endif()
+ target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
elseif (HAVOK_TPV)
use_prebuilt_binary(llphysicsextensions_tpv)
- if (CMAKE_OSX_ARCHITECTURES MATCHES x86_64)
- target_link_directories( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE} )
- endif ()
- target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions_tpv)
-else (HAVOK)
- use_prebuilt_binary(llphysicsextensions_stub)
- set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub)
- target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensionsstub)
-endif (HAVOK)
-
-target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
+ if (NOT DARWIN)
+ if(WINDOWS)
+ target_link_libraries( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS}/llphysicsextensions_tpv.lib)
+ elseif(LINUX)
+ target_link_libraries( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS}/libllphysicsextensions_tpv.a)
+ endif()
+ target_compile_definitions( llphysicsextensions_impl INTERFACE LL_HAVOK=1 )
+ endif()
+ target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
+endif ()
diff --git a/indra/cmake/VHACD.cmake b/indra/cmake/VHACD.cmake
new file mode 100644
index 0000000000..b368fe28e0
--- /dev/null
+++ b/indra/cmake/VHACD.cmake
@@ -0,0 +1,30 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+add_library(ll::vhacd INTERFACE IMPORTED)
+
+if (FALSE)
+use_system_binary(vhacd)
+use_prebuilt_binary(vhacd)
+
+elseif (NOT (${LINUX_DISTRO} MATCHES fedora))
+ if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/vhacd_installed OR NOT ${vhacd_installed} EQUAL 0)
+ if (NOT EXISTS ${CMAKE_BINARY_DIR}/v-hacd-4.1.0.tar.gz)
+ file(DOWNLOAD
+ https://github.com/kmammou/v-hacd/archive/refs/tags/v4.1.0.tar.gz
+ ${CMAKE_BINARY_DIR}/v-hacd-4.1.0.tar.gz
+ )
+ endif ()
+ file(ARCHIVE_EXTRACT
+ INPUT ${CMAKE_BINARY_DIR}/v-hacd-4.1.0.tar.gz
+ DESTINATION ${CMAKE_BINARY_DIR}
+ )
+ file(MAKE_DIRECTORY ${LIBS_PREBUILT_DIR}/include/vhacd)
+ file(
+ COPY ${CMAKE_BINARY_DIR}/v-hacd-4.1.0/include/VHACD.h
+ DESTINATION ${LIBS_PREBUILT_DIR}/include/vhacd
+ )
+ file(WRITE ${PREBUILD_TRACKING_DIR}/vhacd_installed "0")
+ endif ()
+target_include_directories(ll::vhacd SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/vhacd/)
+endif ()
diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
index 719381b4fc..d5323e0b84 100644
--- a/indra/llappearance/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -283,6 +283,7 @@ bool LLPolyMeshSharedData::loadMesh( const std::string& fileName )
LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
if (!fp)
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "can't open: " << fileName << LL_ENDL;
return false;
}
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index f72f47723f..bcb00e6afd 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -1892,7 +1892,10 @@ LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name,
image_raw->copyUnscaledAlphaMask(alpha_image_raw, LLColor4U::black);
}
- tex->createGLTexture(0, image_raw, 0, true, LLGLTexture::LOCAL);
+ if (!tex->createGLTexture(0, image_raw, 0, true, LLGLTexture::LOCAL))
+ {
+ LL_WARNS() << "Failed to create GL texture for image: " << file_name << LL_ENDL;
+ }
gGL.getTexUnit(0)->bind(tex);
tex->setAddressMode(LLTexUnit::TAM_CLAMP);
diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp
index 30551c115d..dd2499cf37 100644
--- a/indra/llappearance/lltexlayerparams.cpp
+++ b/indra/llappearance/lltexlayerparams.cpp
@@ -338,7 +338,10 @@ bool LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
// Create the GL texture, and then hang onto it for future use.
if (mNeedsCreateTexture)
{
- mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw);
+ if (!mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw))
+ {
+ LL_WARNS() << "Failed to create GL texture for image: " << mCachedProcessedTexture->getID() << LL_ENDL;
+ }
mNeedsCreateTexture = false;
gGL.getTexUnit(0)->bind(mCachedProcessedTexture);
mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP);
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 53659ac13f..a539e4fe28 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -35,7 +35,6 @@
#if LL_WINDOWS
#include "llwin32headers.h"
-#include <stdlib.h> // Windows errno
#include <vector>
#else
#include <errno.h>
@@ -49,6 +48,86 @@ static std::string empty;
// variants of strerror() to report errors.
#if LL_WINDOWS
+// For the situations where we directly call into Windows API functions we need to translate
+// the Windows error codes into errno values
+namespace
+{
+ struct errentry
+ {
+ unsigned long oserr; // Windows OS error value
+ int errcode; // System V error code
+ };
+}
+
+// translation table between Windows OS error value and System V errno code
+static errentry const errtable[]
+{
+ { ERROR_INVALID_FUNCTION, EINVAL }, // 1
+ { ERROR_FILE_NOT_FOUND, ENOENT }, // 2
+ { ERROR_PATH_NOT_FOUND, ENOENT }, // 3
+ { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, // 4
+ { ERROR_ACCESS_DENIED, EACCES }, // 5
+ { ERROR_INVALID_HANDLE, EBADF }, // 6
+ { ERROR_ARENA_TRASHED, ENOMEM }, // 7
+ { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, // 8
+ { ERROR_INVALID_BLOCK, ENOMEM }, // 9
+ { ERROR_BAD_ENVIRONMENT, E2BIG }, // 10
+ { ERROR_BAD_FORMAT, ENOEXEC }, // 11
+ { ERROR_INVALID_ACCESS, EINVAL }, // 12
+ { ERROR_INVALID_DATA, EINVAL }, // 13
+ { ERROR_INVALID_DRIVE, ENOENT }, // 15
+ { ERROR_CURRENT_DIRECTORY, EACCES }, // 16
+ { ERROR_NOT_SAME_DEVICE, EXDEV }, // 17
+ { ERROR_NO_MORE_FILES, ENOENT }, // 18
+ { ERROR_LOCK_VIOLATION, EACCES }, // 33
+ { ERROR_BAD_NETPATH, ENOENT }, // 53
+ { ERROR_NETWORK_ACCESS_DENIED, EACCES }, // 65
+ { ERROR_BAD_NET_NAME, ENOENT }, // 67
+ { ERROR_FILE_EXISTS, EEXIST }, // 80
+ { ERROR_CANNOT_MAKE, EACCES }, // 82
+ { ERROR_FAIL_I24, EACCES }, // 83
+ { ERROR_INVALID_PARAMETER, EINVAL }, // 87
+ { ERROR_NO_PROC_SLOTS, EAGAIN }, // 89
+ { ERROR_DRIVE_LOCKED, EACCES }, // 108
+ { ERROR_BROKEN_PIPE, EPIPE }, // 109
+ { ERROR_DISK_FULL, ENOSPC }, // 112
+ { ERROR_INVALID_TARGET_HANDLE, EBADF }, // 114
+ { ERROR_WAIT_NO_CHILDREN, ECHILD }, // 128
+ { ERROR_CHILD_NOT_COMPLETE, ECHILD }, // 129
+ { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, // 130
+ { ERROR_NEGATIVE_SEEK, EINVAL }, // 131
+ { ERROR_SEEK_ON_DEVICE, EACCES }, // 132
+ { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, // 145
+ { ERROR_NOT_LOCKED, EACCES }, // 158
+ { ERROR_BAD_PATHNAME, ENOENT }, // 161
+ { ERROR_MAX_THRDS_REACHED, EAGAIN }, // 164
+ { ERROR_LOCK_FAILED, EACCES }, // 167
+ { ERROR_ALREADY_EXISTS, EEXIST }, // 183
+ { ERROR_FILENAME_EXCED_RANGE, ENOENT }, // 206
+ { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, // 215
+ { ERROR_NO_UNICODE_TRANSLATION, EILSEQ }, // 1113
+ { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } // 1816
+};
+
+static int set_errno_from_oserror(unsigned long oserr)
+{
+ if (!oserr)
+ return 0;
+
+ // Check the table for the Windows OS error code
+ for (const struct errentry &entry : errtable)
+ {
+ if (oserr == entry.oserr)
+ {
+ _set_errno(entry.errcode);
+ return -1;
+ }
+ }
+
+ _set_errno(EINVAL);
+ return -1;
+}
+
// On Windows, use strerror_s().
std::string strerr(int errn)
{
@@ -57,7 +136,67 @@ std::string strerr(int errn)
return buffer;
}
-typedef std::basic_ios<char,std::char_traits < char > > _Myios;
+inline bool is_slash(wchar_t const c)
+{
+ return c == L'\\' || c == L'/';
+}
+
+static std::wstring utf8path_to_wstring(const std::string& utf8path)
+{
+ if (utf8path.size() >= MAX_PATH)
+ {
+ // By prepending "\\?\" to a path, Windows widechar file APIs will not fail on long path names
+ std::wstring utf16path = L"\\\\?\\" + ll_convert<std::wstring>(utf8path);
+ // We need to make sure that the path does not contain forward slashes as above
+ // prefix does bypass the path normalization that replaces slashes with backslashes
+ // before passing the path to kernel mode APIs
+ std::replace(utf16path.begin(), utf16path.end(), L'/', L'\\');
+ return utf16path;
+ }
+ return ll_convert<std::wstring>(utf8path);
+}
+
+static unsigned short get_fileattr(const std::wstring& utf16path, bool dontFollowSymLink = false)
+{
+ unsigned long flags = FILE_FLAG_BACKUP_SEMANTICS;
+ if (dontFollowSymLink)
+ {
+ flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+ }
+ HANDLE file_handle = CreateFileW(utf16path.c_str(), FILE_READ_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ nullptr, OPEN_EXISTING, flags, nullptr);
+ if (file_handle != INVALID_HANDLE_VALUE)
+ {
+ FILE_ATTRIBUTE_TAG_INFO attribute_info;
+ if (GetFileInformationByHandleEx(file_handle, FileAttributeTagInfo, &attribute_info, sizeof(attribute_info)))
+ {
+ // A volume path alone (only drive letter) is not recognized as directory while it technically is
+ bool is_directory = (attribute_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
+ (iswalpha(utf16path[0]) && utf16path[1] == ':' &&
+ (!utf16path[2] || (is_slash(utf16path[2]) && !utf16path[3])));
+ unsigned short st_mode = is_directory ? S_IFDIR :
+ (attribute_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ? S_IFLNK : S_IFREG);
+ st_mode |= (attribute_info.FileAttributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
+ // we do not try to guess executable flag
+
+ // propagate user bits to group/other fields:
+ st_mode |= (st_mode & 0700) >> 3;
+ st_mode |= (st_mode & 0700) >> 6;
+
+ CloseHandle(file_handle);
+ return st_mode;
+ }
+ }
+ // Retrieve last error and set errno before calling CloseHandle()
+ set_errno_from_oserror(GetLastError());
+
+ if (file_handle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(file_handle);
+ }
+ return 0;
+}
#else
// On Posix we want to call strerror_r(), but alarmingly, there are two
@@ -108,18 +247,13 @@ std::string strerr(int errn)
}
#endif // ! LL_WINDOWS
-// On either system, shorthand call just infers global 'errno'.
-std::string strerr()
-{
- return strerr(errno);
-}
-
-int warnif(const std::string& desc, const std::string& filename, int rc, int accept=0)
+static int warnif(const std::string& desc, const std::string& filename, int rc, int accept = 0)
{
if (rc < 0)
{
// Capture errno before we start emitting output
int errn = errno;
+
// For certain operations, a particular errno value might be
// acceptable -- e.g. stat() could permit ENOENT, mkdir() could permit
// EEXIST. Don't warn if caller explicitly says this errno is okay.
@@ -176,62 +310,59 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc
// static
int LLFile::mkdir(const std::string& dirname, int perms)
{
+ // We often use mkdir() to ensure the existence of a directory that might
+ // already exist. There is no known case in which we want to call out as
+ // an error the requested directory already existing.
#if LL_WINDOWS
// permissions are ignored on Windows
- std::wstring utf16dirname = ll_convert<std::wstring>(dirname);
- int rc = _wmkdir(utf16dirname.c_str());
+ int rc = 0;
+ std::wstring utf16dirname = utf8path_to_wstring(dirname);
+ if (!CreateDirectoryW(utf16dirname.c_str(), nullptr))
+ {
+ // Only treat other errors than an already existing file as a real error
+ unsigned long oserr = GetLastError();
+ if (oserr != ERROR_ALREADY_EXISTS)
+ {
+ rc = set_errno_from_oserror(oserr);
+ }
+ }
#else
int rc = ::mkdir(dirname.c_str(), (mode_t)perms);
-#endif
- // We often use mkdir() to ensure the existence of a directory that might
- // already exist. There is no known case in which we want to call out as
- // an error the requested directory already existing.
if (rc < 0 && errno == EEXIST)
{
// this is not the error you want, move along
return 0;
}
+#endif
// anything else might be a problem
- return warnif("mkdir", dirname, rc, EEXIST);
+ return warnif("mkdir", dirname, rc);
}
// static
-int LLFile::rmdir(const std::string& dirname)
+int LLFile::rmdir(const std::string& dirname, int suppress_error)
{
#if LL_WINDOWS
- // permissions are ignored on Windows
- std::wstring utf16dirname = ll_convert<std::wstring>(dirname);
+ std::wstring utf16dirname = utf8path_to_wstring(dirname);
int rc = _wrmdir(utf16dirname.c_str());
#else
int rc = ::rmdir(dirname.c_str());
#endif
- return warnif("rmdir", dirname, rc);
+ return warnif("rmdir", dirname, rc, suppress_error);
}
// static
-LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawfinder: ignore */
-{
-#if LL_WINDOWS
- std::wstring utf16filename = ll_convert<std::wstring>(filename);
- std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode));
- return _wfopen(utf16filename.c_str(),utf16mode.c_str());
-#else
- return ::fopen(filename.c_str(),mode); /* Flawfinder: ignore */
-#endif
-}
-
-LLFILE* LLFile::_fsopen(const std::string& filename, const char* mode, int sharingFlag)
+LLFILE* LLFile::fopen(const std::string& filename, const char* mode)
{
#if LL_WINDOWS
- std::wstring utf16filename = ll_convert<std::wstring>(filename);
+ std::wstring utf16filename = utf8path_to_wstring(filename);
std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode));
- return _wfsopen(utf16filename.c_str(),utf16mode.c_str(),sharingFlag);
+ return _wfopen(utf16filename.c_str(), utf16mode.c_str());
#else
- llassert(0);//No corresponding function on non-windows
- return NULL;
+ return ::fopen(filename.c_str(),mode);
#endif
}
+// static
int LLFile::close(LLFILE * file)
{
int ret_value = 0;
@@ -242,9 +373,10 @@ int LLFile::close(LLFILE * file)
return ret_value;
}
+// static
std::string LLFile::getContents(const std::string& filename)
{
- LLFILE* fp = fopen(filename, "rb"); /* Flawfinder: ignore */
+ LLFILE* fp = LLFile::fopen(filename, "rb");
if (fp)
{
fseek(fp, 0, SEEK_END);
@@ -261,42 +393,80 @@ std::string LLFile::getContents(const std::string& filename)
return LLStringUtil::null;
}
-int LLFile::remove(const std::string& filename, int supress_error)
+// static
+int LLFile::remove(const std::string& filename, int suppress_error)
{
#if LL_WINDOWS
- std::wstring utf16filename = ll_convert<std::wstring>(filename);
- int rc = _wremove(utf16filename.c_str());
+ // Posix remove() works on both files and directories although on Windows
+ // remove() and its wide char variant _wremove() only removes files just
+ // as its siblings unlink() and _wunlink().
+ // If we really only want to support files we should instead use
+ // unlink() in the non-Windows part below too
+ int rc = -1;
+ std::wstring utf16filename = utf8path_to_wstring(filename);
+ unsigned short st_mode = get_fileattr(utf16filename);
+ if (S_ISDIR(st_mode))
+ {
+ rc = _wrmdir(utf16filename.c_str());
+ }
+ else if (S_ISREG(st_mode))
+ {
+ rc = _wunlink(utf16filename.c_str());
+ }
+ else if (st_mode)
+ {
+ // it is something else than a file or directory
+ // this should not really happen as long as we do not allow for symlink
+ // detection in the optional parameter to get_fileattr()
+ rc = set_errno_from_oserror(ERROR_INVALID_PARAMETER);
+ }
+ else
+ {
+ // get_fileattr() failed and already set errno, preserve it for correct error reporting
+ }
#else
int rc = ::remove(filename.c_str());
#endif
- return warnif("remove", filename, rc, supress_error);
+ return warnif("remove", filename, rc, suppress_error);
}
-int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error)
+// static
+int LLFile::rename(const std::string& filename, const std::string& newname, int suppress_error)
{
#if LL_WINDOWS
- std::wstring utf16filename = ll_convert<std::wstring>(filename);
- std::wstring utf16newname = ll_convert<std::wstring>(newname);
- int rc = _wrename(utf16filename.c_str(),utf16newname.c_str());
+ // Posix rename() will gladly overwrite a file at newname if it exists, the Windows
+ // rename(), respectively _wrename(), will bark on that. Instead call directly the Windows
+ // API MoveFileEx() and use its flags to specify that overwrite is allowed.
+ std::wstring utf16filename = utf8path_to_wstring(filename);
+ std::wstring utf16newname = utf8path_to_wstring(newname);
+ int rc = 0;
+ if (!MoveFileExW(utf16filename.c_str(), utf16newname.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
+ {
+ rc = set_errno_from_oserror(GetLastError());
+ }
#else
int rc = ::rename(filename.c_str(),newname.c_str());
#endif
- return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error);
+ return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, suppress_error);
}
+// Make this a define rather than using magic numbers multiple times in the code
+#define LLFILE_COPY_BUFFER_SIZE 16384
+
+// static
bool LLFile::copy(const std::string& from, const std::string& to)
{
bool copied = false;
- LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */
+ LLFILE* in = LLFile::fopen(from, "rb");
if (in)
{
- LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */
+ LLFILE* out = LLFile::fopen(to, "wb");
if (out)
{
- char buf[16384]; /* Flawfinder: ignore */
+ char buf[LLFILE_COPY_BUFFER_SIZE];
size_t readbytes;
bool write_ok = true;
- while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
+ while (write_ok && (readbytes = fread(buf, 1, LLFILE_COPY_BUFFER_SIZE, in)))
{
if (fwrite(buf, 1, readbytes, out) != readbytes)
{
@@ -315,33 +485,62 @@ bool LLFile::copy(const std::string& from, const std::string& to)
return copied;
}
-int LLFile::stat(const std::string& filename, llstat* filestatus)
+// static
+int LLFile::stat(const std::string& filename, llstat* filestatus, int suppress_error)
{
#if LL_WINDOWS
- std::wstring utf16filename = ll_convert<std::wstring>(filename);
- int rc = _wstat(utf16filename.c_str(),filestatus);
+ std::wstring utf16filename = utf8path_to_wstring(filename);
+ int rc = _wstat64(utf16filename.c_str(), filestatus);
#else
- int rc = ::stat(filename.c_str(),filestatus);
+ int rc = ::stat(filename.c_str(), filestatus);
#endif
- // We use stat() to determine existence (see isfile(), isdir()).
- // Don't spam the log if the subject pathname doesn't exist.
- return warnif("stat", filename, rc, ENOENT);
+ return warnif("stat", filename, rc, suppress_error);
}
-bool LLFile::isdir(const std::string& filename)
+// static
+unsigned short LLFile::getattr(const std::string& filename, bool dontFollowSymLink, int suppress_error)
{
- llstat st;
+#if LL_WINDOWS
+ // _wstat64() is a bit heavyweight on Windows, use a more lightweight API
+ // to just get the attributes
+ int rc = -1;
+ std::wstring utf16filename = utf8path_to_wstring(filename);
+ unsigned short st_mode = get_fileattr(utf16filename, dontFollowSymLink);
+ if (st_mode)
+ {
+ return st_mode;
+ }
+#else
+ llstat filestatus;
+ int rc = dontFollowSymLink ? ::lstat(filename.c_str(), &filestatus) : ::stat(filename.c_str(), &filestatus);
+ if (rc == 0)
+ {
+ return filestatus.st_mode;
+ }
+#endif
+ warnif("getattr", filename, rc, suppress_error);
+ return 0;
+}
- return stat(filename, &st) == 0 && S_ISDIR(st.st_mode);
+// static
+bool LLFile::isdir(const std::string& filename)
+{
+ return S_ISDIR(getattr(filename));
}
+// static
bool LLFile::isfile(const std::string& filename)
{
- llstat st;
+ return S_ISREG(getattr(filename));
+}
- return stat(filename, &st) == 0 && S_ISREG(st.st_mode);
+// static
+bool LLFile::islink(const std::string& filename)
+{
+ return S_ISLNK(getattr(filename, true));
}
+// static
const char *LLFile::tmpdir()
{
static std::string utf8path;
@@ -368,75 +567,8 @@ const char *LLFile::tmpdir()
return utf8path.c_str();
}
-
-/***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/
-
#if LL_WINDOWS
-LLFILE * LLFile::_Fiopen(const std::string& filename,
- std::ios::openmode mode)
-{ // open a file
- static const char *mods[] =
- { // fopen mode strings corresponding to valid[i]
- "r", "w", "w", "a", "rb", "wb", "wb", "ab",
- "r+", "w+", "a+", "r+b", "w+b", "a+b",
- 0};
- static const int valid[] =
- { // valid combinations of open flags
- ios_base::in,
- ios_base::out,
- ios_base::out | ios_base::trunc,
- ios_base::out | ios_base::app,
- ios_base::in | ios_base::binary,
- ios_base::out | ios_base::binary,
- ios_base::out | ios_base::trunc | ios_base::binary,
- ios_base::out | ios_base::app | ios_base::binary,
- ios_base::in | ios_base::out,
- ios_base::in | ios_base::out | ios_base::trunc,
- ios_base::in | ios_base::out | ios_base::app,
- ios_base::in | ios_base::out | ios_base::binary,
- ios_base::in | ios_base::out | ios_base::trunc
- | ios_base::binary,
- ios_base::in | ios_base::out | ios_base::app
- | ios_base::binary,
- 0};
-
- LLFILE *fp = 0;
- int n;
- ios_base::openmode atendflag = mode & ios_base::ate;
- ios_base::openmode norepflag = mode & ios_base::_Noreplace;
-
- if (mode & ios_base::_Nocreate)
- mode |= ios_base::in; // file must exist
- mode &= ~(ios_base::ate | ios_base::_Nocreate | ios_base::_Noreplace);
- for (n = 0; valid[n] != 0 && valid[n] != mode; ++n)
- ; // look for a valid mode
-
- if (valid[n] == 0)
- return (0); // no valid mode
- else if (norepflag && mode & (ios_base::out | ios_base::app)
- && (fp = LLFile::fopen(filename, "r")) != 0) /* Flawfinder: ignore */
- { // file must not exist, close and fail
- fclose(fp);
- return (0);
- }
- else if (fp != 0 && fclose(fp) != 0)
- return (0); // can't close after test open
-// should open with protection here, if other than default
- else if ((fp = LLFile::fopen(filename, mods[n])) == 0) /* Flawfinder: ignore */
- return (0); // open failed
-
- if (!atendflag || fseek(fp, 0, SEEK_END) == 0)
- return (fp); // no need to seek to end, or seek succeeded
-
- fclose(fp); // can't position at end
- return (0);
-}
-
-#endif /* LL_WINDOWS */
-
-
-#if LL_WINDOWS
/************** input file stream ********************************/
llifstream::llifstream() {}
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index 1661cbeb55..04a2946ac4 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -41,8 +41,9 @@ typedef FILE LLFILE;
#include <sys/stat.h>
#if LL_WINDOWS
-// windows version of stat function and stat data structure are called _stat
-typedef struct _stat llstat;
+// The Windows version of stat function and stat data structure are called _stat64
+// We use _stat64 here to support 64-bit st_size and time_t values
+typedef struct _stat64 llstat;
#else
typedef struct stat llstat;
#include <sys/types.h>
@@ -56,35 +57,110 @@ typedef struct stat llstat;
# define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
#endif
+// Windows C runtime library does not define this and does not support symlink detection in the
+// stat functions but we do in our getattr() function
+#ifndef S_IFLNK
+#define S_IFLNK 0xA000 /* symlink */
+#endif
+
+#ifndef S_ISLNK
+#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
+#endif
+
#include "llstring.h" // safe char* -> std::string conversion
+/// LLFile is a class of static functions operating on paths
+/// All the functions with a path string input take UTF8 path/filenames
class LL_COMMON_API LLFile
{
public:
- // All these functions take UTF8 path/filenames.
- static LLFILE* fopen(const std::string& filename,const char* accessmode); /* Flawfinder: ignore */
- static LLFILE* _fsopen(const std::string& filename,const char* accessmode,int sharingFlag);
+ /// open a file with the specified access mode
+ static LLFILE* fopen(const std::string& filename, const char* accessmode); /* Flawfinder: ignore */
+ ///< 'accessmode' follows the rules of the Posix fopen() mode parameter
+ /// "r" open the file for reading only and positions the stream at the beginning
+ /// "r+" open the file for reading and writing and positions the stream at the beginning
+ /// "w" open the file for reading and writing and truncate it to zero length
+ /// "w+" open or create the file for reading and writing and truncate to zero length if it existed
+ /// "a" open the file for reading and writing and position the stream at the end of the file
+ /// "a+" open or create the file for reading and writing and position the stream at the end of the file
+ ///
+ /// in addition to these values, "b" can be appended to indicate binary stream access, but on Linux and Mac
+ /// this is strictly for compatibility and has no effect. On Windows this makes the file functions not
+ /// try to translate line endings. Windows also allows to append "t" to indicate text mode. If neither
+ /// "b" or "t" is defined, Windows uses the value set by _fmode which by default is _O_TEXT.
+ /// This means that it is always a good idea to append "b" specifically for binary file access to
+ /// avoid corruption of the binary consistency of the data stream when reading or writing
+ /// Other characters in 'accessmode' will usually cause an error as fopen will verify this parameter
+ /// @returns a valid LLFILE* pointer on success or NULL on failure
static int close(LLFILE * file);
+ /// retrieve the content of a file into a string
static std::string getContents(const std::string& filename);
+ ///< @returns the content of the file or an empty string on failure
- // perms is a permissions mask like 0777 or 0700. In most cases it will
- // be overridden by the user's umask. It is ignored on Windows.
- // mkdir() considers "directory already exists" to be SUCCESS.
+ /// create a directory
static int mkdir(const std::string& filename, int perms = 0700);
+ ///< perms is a permissions mask like 0777 or 0700. In most cases it will be
+ /// overridden by the user's umask. It is ignored on Windows.
+ /// mkdir() considers "directory already exists" to be not an error.
+ /// @returns 0 on success and -1 on failure.
+
+ //// remove a directory
+ static int rmdir(const std::string& filename, int suppress_error = 0);
+ ///< pass ENOENT in the optional 'suppress_error' parameter
+ /// if you don't want a warning in the log when the directory does not exist
+ /// @returns 0 on success and -1 on failure.
+
+ /// remove a file or directory
+ static int remove(const std::string& filename, int suppress_error = 0);
+ ///< pass ENOENT in the optional 'suppress_error' parameter
+ /// if you don't want a warning in the log when the directory does not exist
+ /// @returns 0 on success and -1 on failure.
- static int rmdir(const std::string& filename);
- static int remove(const std::string& filename, int supress_error = 0);
- static int rename(const std::string& filename,const std::string& newname, int supress_error = 0);
+ /// rename a file
+ static int rename(const std::string& filename, const std::string& newname, int suppress_error = 0);
+ ///< it will silently overwrite newname if it exists without returning an error
+ /// Posix guarantees that if newname already exists, then there will be no moment
+ /// in which for other processes newname does not exist. There is no such guarantee
+ /// under Windows at this time. It may do it in the same way but the used Windows API
+ /// does not make such guarantees.
+ /// @returns 0 on success and -1 on failure.
+
+
+ /// copy the contents of file from 'from' to 'to' filename
static bool copy(const std::string& from, const std::string& to);
+ ///< @returns true on success and false on failure.
+
+ /// return the file stat structure for filename
+ static int stat(const std::string& filename, llstat* file_status, int suppress_error = ENOENT);
+ ///< for compatibility with existing uses of LL_File::stat() we use ENOENT as default in the
+ /// optional 'suppress_error' parameter to avoid spamming the log with warnings when the API
+ /// is used to detect if a file exists
+ /// @returns 0 on success and -1 on failure.
+
+ /// get the file or directory attributes for filename
+ static unsigned short getattr(const std::string& filename, bool dontFollowSymLink = false, int suppress_error = ENOENT);
+ ///< a more lightweight function on Windows to stat, that just returns the file attribute flags
+ /// dontFollowSymLinks set to true returns the attributes of the symlink if it is one, rather than resolving it
+ /// we pass by default ENOENT in the optional 'suppress_error' parameter to not spam the log with
+ /// warnings when the file or directory does not exist
+ /// @returns 0 on failure and a st_mode value with either S_IFDIR or S_IFREG set otherwise
+ /// together with the three access bits which under Windows only the write bit is relevant.
+
+ /// check if filename is an existing directory
+ static bool isdir(const std::string& filename);
+ ///< @returns true if the path is for an existing directory
+
+ /// check if filename is an existing file
+ static bool isfile(const std::string& filename);
+ ///< @returns true if the path is for an existing file
- static int stat(const std::string& filename,llstat* file_status);
- static bool isdir(const std::string& filename);
- static bool isfile(const std::string& filename);
- static LLFILE * _Fiopen(const std::string& filename,
- std::ios::openmode mode);
+ /// check if filename is a symlink
+ static bool islink(const std::string& filename);
+ ///< @returns true if the path is pointing at a symlink
+ /// return a path to the temporary directory on the system
static const char * tmpdir();
};
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index 662a2511cd..ada6b9519e 100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -188,6 +188,17 @@ public:
<< childout.peek(0, peeklen) << "..." << LL_ENDL;
}
+ // Handle any remaining stderr data (partial lines) the same way as we do
+ // for stdout: log it.
+ LLProcess::ReadPipe& childerr(mChild->getReadPipe(LLProcess::STDERR));
+ if (childerr.size())
+ {
+ LLProcess::ReadPipe::size_type
+ peeklen((std::min)(LLProcess::ReadPipe::size_type(50), childerr.size()));
+ LL_WARNS("LLLeap") << "Final stderr " << childerr.size() << " bytes: "
+ << childerr.peek(0, peeklen) << "..." << LL_ENDL;
+ }
+
// Kill this instance. MUST BE LAST before return!
delete this;
return false;
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 0196a24b18..efeeb1340e 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -80,7 +80,7 @@ void LLQueuedThread::shutdown()
mRequestQueue.close();
}
- S32 timeout = 100;
+ S32 timeout = 50;
for ( ; timeout>0; timeout--)
{
if (isStopped())
@@ -101,19 +101,34 @@ void LLQueuedThread::shutdown()
}
QueuedRequest* req;
- S32 active_count = 0;
+ S32 queued_count = 0;
+ bool has_active = false;
+ lockData();
while ( (req = (QueuedRequest*)mRequestHash.pop_element()) )
{
- if (req->getStatus() == STATUS_QUEUED || req->getStatus() == STATUS_INPROGRESS)
+ if (req->getStatus() == STATUS_INPROGRESS)
+ {
+ has_active = true;
+ req->setFlags(FLAG_ABORT | FLAG_AUTO_COMPLETE);
+ continue;
+ }
+ if (req->getStatus() == STATUS_QUEUED)
{
- ++active_count;
+ ++queued_count;
req->setStatus(STATUS_ABORTED); // avoid assert in deleteRequest
}
req->deleteRequest();
}
- if (active_count)
+ unlockData();
+ if (queued_count)
+ {
+ LL_WARNS() << "~LLQueuedThread() called with unpocessed requests: " << queued_count << LL_ENDL;
+ }
+ if (has_active)
{
- LL_WARNS() << "~LLQueuedThread() called with active requests: " << active_count << LL_ENDL;
+ LL_WARNS() << "~LLQueuedThread() called with active requests!" << LL_ENDL;
+ ms_sleep(100); // last chance for request to finish
+ printQueueStats();
}
mRequestQueue.close();
@@ -570,7 +585,12 @@ LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U3
LLQueuedThread::QueuedRequest::~QueuedRequest()
{
- llassert_always(mStatus == STATUS_DELETE);
+ if (mStatus != STATUS_DELETE)
+ {
+ // The only method to delete a request is deleteRequest(),
+ // it should have set the status to STATUS_DELETE
+ LL_ERRS() << "LLQueuedThread::QueuedRequest deleted with status " << mStatus << LL_ENDL;
+ }
}
//virtual
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 2c46c59aa5..edc891f5ec 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -1357,10 +1357,6 @@ bool gunzip_file(const std::string& srcfile, const std::string& dstfile)
} while(gzeof(src) == 0);
fclose(dst);
dst = NULL;
-#if LL_WINDOWS
- // Rename in windows needs the dstfile to not exist.
- LLFile::remove(dstfile, ENOENT);
-#endif
if (LLFile::rename(tmpfile, dstfile) == -1) goto err; /* Flawfinder: ignore */
retval = true;
err:
@@ -1408,10 +1404,6 @@ bool gzip_file(const std::string& srcfile, const std::string& dstfile)
gzclose(dst);
dst = NULL;
-#if LL_WINDOWS
- // Rename in windows needs the dstfile to not exist.
- LLFile::remove(dstfile);
-#endif
if (LLFile::rename(tmpfile, dstfile) == -1) goto err; /* Flawfinder: ignore */
retval = true;
err:
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index b63cc52bec..13422612d6 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -54,14 +54,29 @@ std::string apr_strerror_helper(apr_status_t rv)
*****************************************************************************/
#define ensure_equals_(left, right) \
- ensure_equals(STRINGIZE(#left << " != " << #right), (left), (right))
+do { \
+ auto _left_val = (left); \
+ auto _right_val = (right); \
+ if (_left_val != _right_val) { \
+ std::string _msg = std::string(#left) + " != " + std::string(#right); \
+ tut::ensure_equals(_msg, _left_val, _right_val); \
+ } else { \
+ tut::ensure_equals("", _left_val, _right_val); \
+ } \
+} while(0)
#define aprchk(expr) aprchk_(#expr, (expr))
static void aprchk_(const char* call, apr_status_t rv, apr_status_t expected=APR_SUCCESS)
{
- tut::ensure_equals(STRINGIZE(call << " => " << rv << ": " << apr_strerror_helper
- (rv)),
- rv, expected);
+ if (rv != expected)
+ {
+ std::string msg = std::string(call) + " => " + std::to_string(rv) + ": " + apr_strerror_helper(rv);
+ tut::ensure_equals(msg, rv, expected);
+ }
+ else
+ {
+ tut::ensure_equals("", rv, expected);
+ }
}
/**
@@ -78,11 +93,14 @@ static std::string readfile(const std::string& pathname, const std::string& desc
std::string use_desc(desc);
if (use_desc.empty())
{
- use_desc = STRINGIZE("in " << pathname);
+ use_desc = "in " + pathname;
}
std::ifstream inf(pathname.c_str());
std::string output;
- tut::ensure(STRINGIZE("No output " << use_desc), bool(std::getline(inf, output)));
+ if (!std::getline(inf, output))
+ {
+ tut::ensure("No output " + use_desc, false);
+ }
std::string more;
while (std::getline(inf, more))
{
@@ -108,8 +126,8 @@ void waitfor(LLProcess& proc, int timeout=60)
{
yield();
}
- tut::ensure(STRINGIZE("process took longer than " << timeout << " seconds to terminate"),
- i < timeout);
+ std::string msg = "process took longer than " + std::to_string(timeout) + " seconds to terminate";
+ tut::ensure(msg, i < timeout);
}
void waitfor(LLProcess::handle h, const std::string& desc, int timeout=60)
@@ -119,8 +137,8 @@ void waitfor(LLProcess::handle h, const std::string& desc, int timeout=60)
{
yield();
}
- tut::ensure(STRINGIZE("process took longer than " << timeout << " seconds to terminate"),
- i < timeout);
+ std::string msg = "process took longer than " + std::to_string(timeout) + " seconds to terminate";
+ tut::ensure(msg, i < timeout);
}
/**
@@ -153,7 +171,8 @@ struct PythonProcessLauncher
try
{
mPy = LLProcess::create(mParams);
- tut::ensure(STRINGIZE("Couldn't launch " << mDesc << " script"), bool(mPy));
+ std::string msg = "Couldn't launch " + mDesc + " script";
+ tut::ensure(msg, bool(mPy));
}
catch (const tut::failure&)
{
@@ -214,7 +233,8 @@ struct PythonProcessLauncher
mParams.args.add(out.getName());
run();
// assuming the script wrote to that file, read it
- return readfile(out.getName(), STRINGIZE("from " << mDesc << " script"));
+ std::string desc = "from " + mDesc + " script";
+ return readfile(out.getName(), desc);
}
LLProcess::Params mParams;
diff --git a/indra/llcorehttp/llhttpconstants.cpp b/indra/llcorehttp/llhttpconstants.cpp
index 40d6c7506c..7a671543d9 100755
--- a/indra/llcorehttp/llhttpconstants.cpp
+++ b/indra/llcorehttp/llhttpconstants.cpp
@@ -100,6 +100,7 @@ const std::string HTTP_IN_HEADER_LOCATION("location");
const std::string HTTP_IN_HEADER_RETRY_AFTER("retry-after");
const std::string HTTP_IN_HEADER_SET_COOKIE("set-cookie");
const std::string HTTP_IN_HEADER_USER_AGENT("user-agent");
+const std::string HTTP_IN_HEADER_X_CONTENT_TYPE_OPTIONS("x-content-type-options");
const std::string HTTP_IN_HEADER_X_FORWARDED_FOR("x-forwarded-for");
const std::string HTTP_CONTENT_LLSD_XML("application/llsd+xml");
@@ -122,6 +123,7 @@ const std::string HTTP_CONTENT_IMAGE_BMP("image/bmp");
const std::string HTTP_NO_CACHE("no-cache");
const std::string HTTP_NO_CACHE_CONTROL("no-cache, max-age=0");
+const std::string HTTP_NOSNIFF("nosniff");
const std::string HTTP_VERB_INVALID("(invalid)");
const std::string HTTP_VERB_HEAD("HEAD");
diff --git a/indra/llcorehttp/llhttpconstants.h b/indra/llcorehttp/llhttpconstants.h
index 583f9fbcb7..71c1dfa173 100755
--- a/indra/llcorehttp/llhttpconstants.h
+++ b/indra/llcorehttp/llhttpconstants.h
@@ -190,6 +190,7 @@ extern const std::string HTTP_IN_HEADER_LOCATION;
extern const std::string HTTP_IN_HEADER_RETRY_AFTER;
extern const std::string HTTP_IN_HEADER_SET_COOKIE;
extern const std::string HTTP_IN_HEADER_USER_AGENT;
+extern const std::string HTTP_IN_HEADER_X_CONTENT_TYPE_OPTIONS;
extern const std::string HTTP_IN_HEADER_X_FORWARDED_FOR;
//// HTTP Content Types ////
@@ -215,5 +216,6 @@ extern const std::string HTTP_CONTENT_IMAGE_BMP;
//// HTTP Cache Settings ////
extern const std::string HTTP_NO_CACHE;
extern const std::string HTTP_NO_CACHE_CONTROL;
+extern const std::string HTTP_NOSNIFF;
#endif
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index b1b698375a..d5c585b45e 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -576,10 +576,6 @@ bool LLCrashLogger::init()
std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old");
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log");
-#if LL_WINDOWS
- LLAPRFile::remove(old_log_file);
-#endif
-
LLFile::rename(log_file.c_str(), old_log_file.c_str());
// Set the log file to crashreport.log
diff --git a/indra/llfilesystem/lldir_utils_objc.mm b/indra/llfilesystem/lldir_utils_objc.mm
index 01fe9e1f2c..35513d5647 100644
--- a/indra/llfilesystem/lldir_utils_objc.mm
+++ b/indra/llfilesystem/lldir_utils_objc.mm
@@ -1,28 +1,28 @@
-/**
+/**
* @file lldir_utils_objc.mm
* @brief Cocoa implementation of directory utilities for macOS
*
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, 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$
- */
+ */
#if LL_DARWIN
//WARNING: This file CANNOT use standard linden includes due to conflicts between definitions of BOOL
@@ -39,18 +39,18 @@ std::string getSystemTempFolder()
tempDir = @"/tmp";
result = std::string([tempDir UTF8String]);
}
-
+
return result;
}
-//findSystemDirectory scoped exclusively to this file.
+//findSystemDirectory scoped exclusively to this file.
std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory,
NSSearchPathDomainMask domainMask)
{
std::string result;
@autoreleasepool {
NSString *path = nil;
-
+
// Search for the path
NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory,
domainMask,
@@ -60,10 +60,10 @@ std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory,
path = [paths objectAtIndex:0];
//HACK: Always attempt to create directory, ignore errors.
NSError *error = nil;
-
+
[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
-
-
+
+
result = std::string([path UTF8String]);
}
}
@@ -88,7 +88,7 @@ std::string getSystemResourceFolder()
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
result = std::string([bundlePath UTF8String]);
}
-
+
return result;
}
@@ -102,7 +102,7 @@ std::string getSystemApplicationSupportFolder()
{
return findSystemDirectory (NSApplicationSupportDirectory,
NSUserDomainMask);
-
+
}
#endif // LL_DARWIN
diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp
index 5ce5244107..541266af4f 100644
--- a/indra/llfilesystem/llfilesystem.cpp
+++ b/indra/llfilesystem/llfilesystem.cpp
@@ -103,9 +103,6 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp
const std::string old_filename = LLDiskCache::metaDataToFilepath(old_file_id, old_file_type);
const std::string new_filename = LLDiskCache::metaDataToFilepath(new_file_id, new_file_type);
- // Rename needs the new file to not exist.
- LLFileSystem::removeFile(new_file_id, new_file_type, ENOENT);
-
if (LLFile::rename(old_filename, new_filename) != 0)
{
// We would like to return false here indicating the operation
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index 5b672bf171..9350901324 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -554,11 +554,6 @@ public:
}
- if (!opj_setup_encoder(encoder, &parameters, image))
- {
- return false;
- }
-
U32 width_tiles = (rawImageIn.getWidth() >> 6);
U32 height_tiles = (rawImageIn.getHeight() >> 6);
@@ -572,6 +567,19 @@ public:
height_tiles = 1;
}
+ if (width_tiles == 1 || height_tiles == 1)
+ {
+ // Images with either dimension less than 32 need less number of resolutions otherwise they error
+ int min_dim = rawImageIn.getWidth() < rawImageIn.getHeight() ? rawImageIn.getWidth() : rawImageIn.getHeight();
+ int max_res = 1 + (int)floor(log2(min_dim));
+ parameters.numresolution = max_res;
+ }
+
+ if (!opj_setup_encoder(encoder, &parameters, image))
+ {
+ return false;
+ }
+
U32 tile_count = width_tiles * height_tiles;
U32 data_size_guess = tile_count * TILE_SIZE;
diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp
index ebf7445c65..b17e22e465 100644
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
@@ -774,6 +774,7 @@ void LLPermissions::importLLSD(const LLSD& sd_perm)
}
}
+ fixOwnership();
fix();
}
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index e5521e0ffc..0cf5ecd3d0 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -5713,6 +5713,8 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
{
try
{
+ // providing mIndices should help avoid unused vertices
+ // but those should have been filtered out on upload
vert_count = static_cast<S32>(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count));
}
catch (std::bad_alloc&)
@@ -5722,10 +5724,16 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
}
}
- if (vert_count < 65535 && vert_count != 0)
+ // Probably should be using meshopt_remapVertexBuffer instead of remaping manually
+ if (vert_count < 65535 && vert_count > 0)
{
//copy results back into volume
resizeVertices(vert_count);
+ if (mNumVertices == 0)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLCoros") << "Failed to allocate memory for resizeVertices(" << vert_count << ")" << LL_ENDL;
+ }
if (!data.w.empty())
{
@@ -5738,13 +5746,27 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
{
U32 src_idx = i;
U32 dst_idx = remap[i];
- if (dst_idx >= (U32)mNumVertices)
+ if (dst_idx == U32_MAX)
+ {
+ // Unused indices? Probably need to resize mIndices
+ dst_idx = mNumVertices - 1;
+ llassert(false);
+ LL_DEBUGS_ONCE("LLVOLUME") << "U32_MAX destination index, substituting" << LL_ENDL;
+ }
+ else if (dst_idx >= (U32)mNumVertices)
{
dst_idx = mNumVertices - 1;
// Shouldn't happen, figure out what gets returned in remap and why.
llassert(false);
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid destination index, substituting" << LL_ENDL;
}
+ if (src_idx >= (U32)data.p.size())
+ {
+ // data.p.size() is supposed to be equal to mNumIndices
+ src_idx = (U32)(data.p.size() - 1);
+ llassert(false);
+ LL_DEBUGS_ONCE("LLVOLUME") << "Invalid source index, substituting" << LL_ENDL;
+ }
mIndices[i] = dst_idx;
mPositions[dst_idx].load3(data.p[src_idx].mV);
@@ -5778,7 +5800,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
}
else
{
- if (vert_count == 0)
+ if (vert_count <= 0)
{
LL_WARNS_ONCE("LLVOLUME") << "meshopt_generateVertexRemapMulti failed to process a model or model was invalid" << LL_ENDL;
}
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index 563dd9459c..5c7b1c4235 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -138,7 +138,22 @@ LLCoprocedureManager::LLCoprocedureManager()
LLCoprocedureManager::~LLCoprocedureManager()
{
- close();
+ try
+ {
+ close();
+ }
+ catch (const boost::fibers::fiber_error&)
+ {
+ LL_WARNS() << "Fiber error during ~LLCoprocedureManager()" << LL_ENDL;
+ }
+ catch (const std::exception& e)
+ {
+ // Shutting down, just log it
+ LL_WARNS() << "Exception during ~LLCoprocedureManager(): " << e.what() << LL_ENDL;
+ }
+ mPropertyQueryFn.clear();
+ mPropertyDefineFn.clear();
+ mPoolMap.clear();
}
void LLCoprocedureManager::initializePool(const std::string &poolName, size_t queue_size)
@@ -365,6 +380,22 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size, s
LLCoprocedurePool::~LLCoprocedurePool()
{
+ try
+ {
+ close(); // should have been closed already, but shouldn't hurt
+ mStatusListener.disconnect();
+ mPendingCoprocs.reset();
+ mCoroMapping.clear();
+ }
+ catch (const boost::fibers::fiber_error&)
+ {
+ LL_WARNS() << "Fiber error during ~LLCoprocedurePool() " << mPoolName << LL_ENDL;
+ }
+ catch (const std::exception& e)
+ {
+ // Shutting down, just log it
+ LL_WARNS() << "Exception " << e.what() << " during ~LLCoprocedurePool() in " << mPoolName << LL_ENDL;
+ }
}
//-------------------------------------------------------------------------
diff --git a/indra/llphysicsextensionsos/CMakeLists.txt b/indra/llphysicsextensionsos/CMakeLists.txt
new file mode 100644
index 0000000000..c04115ef26
--- /dev/null
+++ b/indra/llphysicsextensionsos/CMakeLists.txt
@@ -0,0 +1,47 @@
+# -*- cmake -*-
+
+project(llphysicsextensionsos)
+
+include(00-Common)
+include(LLCommon)
+include(LLMath)
+include(VHACD)
+
+set(llphysicsextensionsos_SOURCE_FILES
+ llconvexdecomposition.cpp
+ llconvexdecompositionvhacd.cpp
+ llpathinglib.cpp
+ LLPathingLibStubImpl.cpp
+ llphysicsextensions.cpp
+ LLPhysicsExtensionsStubImpl.cpp
+ )
+
+set(llphysicsextensionsos_HEADER_FILES
+ CMakeLists.txt
+ llconvexdecomposition.h
+ llconvexdecompositionvhacd.h
+ llpathinglib.h
+ LLPathingLibStubImpl.h
+ llphysicsextensions.h
+ LLPhysicsExtensionsStubImpl.h
+ )
+
+set_source_files_properties(${llphysicsextensionsos_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llphysicsextensionsos_SOURCE_FILES ${llphysicsextensionsos_HEADER_FILES})
+
+add_library (llphysicsextensionsos ${llphysicsextensionsos_SOURCE_FILES})
+target_include_directories(llphysicsextensionsos INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+
+target_link_libraries(llphysicsextensionsos
+ llcommon
+ llmath
+ ll::vhacd)
+
+if(WINDOWS)
+ target_compile_options(llphysicsextensionsos PRIVATE /bigobj)
+endif()
+
+# Add tests
+
diff --git a/indra/llphysicsextensionsos/LLPathingLibStubImpl.cpp b/indra/llphysicsextensionsos/LLPathingLibStubImpl.cpp
new file mode 100644
index 0000000000..9830fd1ad0
--- /dev/null
+++ b/indra/llphysicsextensionsos/LLPathingLibStubImpl.cpp
@@ -0,0 +1,109 @@
+/**
+* @file LLPathingLibStubImpl.cpp
+* @author prep@lindenlab.com
+* @brief A stubbed implementation of LLPathingLib
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 20112010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+
+#include "llpathinglib.h"
+#include "LLPathingLibStubImpl.h"
+
+#include "llsd.h"
+
+//=============================================================================
+LLPathingLibImpl::LLPathingLibImpl()
+{
+}
+
+LLPathingLibImpl::~LLPathingLibImpl()
+{
+
+}
+
+LLPathingLib* LLPathingLibImpl::getInstance()
+{
+ return NULL;
+}
+
+
+LLPathingLib::LLPLResult LLPathingLibImpl::initSystem()
+{
+ return LLPL_NOT_IMPLEMENTED;
+}
+
+LLPathingLib::LLPLResult LLPathingLibImpl::quitSystem()
+{
+ return LLPL_NOT_IMPLEMENTED;
+}
+
+LLPathingLib::LLPLResult LLPathingLibImpl::extractNavMeshSrcFromLLSD( const LLSD::Binary& dataBlock, int dir )
+{
+ return LLPL_NOT_IMPLEMENTED;
+}
+
+void LLPathingLibImpl::processNavMeshData()
+{
+}
+
+LLPathingLibImpl::LLPLResult LLPathingLibImpl::generatePath( const PathingPacket& pathingPacket )
+{
+ return LLPL_NOT_IMPLEMENTED;
+}
+
+void LLPathingLibImpl::setNavMeshMaterialType( LLPLCharacterType materialType )
+{
+}
+
+void LLPathingLibImpl::setNavMeshColors( const NavMeshColors& color )
+{
+}
+
+void LLPathingLibImpl::renderNavMesh()
+{
+}
+
+void LLPathingLibImpl::renderNavMeshEdges()
+{
+}
+
+void LLPathingLibImpl::renderNavMeshShapesVBO( U32 shapeRenderFlags )
+{
+}
+
+void LLPathingLibImpl::renderPath()
+{
+}
+
+void LLPathingLibImpl::renderPathBookend( LLRender& gl, LLPathingLib::LLPLPathBookEnd type )
+{
+}
+
+void LLPathingLibImpl::cleanupVBOManager()
+{
+}
+
+void LLPathingLibImpl::cleanupResidual()
+{
+}
diff --git a/indra/llphysicsextensionsos/LLPathingLibStubImpl.h b/indra/llphysicsextensionsos/LLPathingLibStubImpl.h
new file mode 100644
index 0000000000..8a97566e8c
--- /dev/null
+++ b/indra/llphysicsextensionsos/LLPathingLibStubImpl.h
@@ -0,0 +1,78 @@
+/**
+* @file LLPathingLibSubImpl.h
+* @author prep@lindenlab.com
+* @brief A stubbed implementation of LLPathingLib
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_PATHING_LIB_H
+#define LL_PATHING_LIB_H
+
+#include "llpathinglib.h"
+
+class LLSD;
+
+//=============================================================================
+class LLPathingLibImpl : public LLPathingLib
+{
+public:
+ LLPathingLibImpl();
+ virtual ~LLPathingLibImpl();
+
+ // Obtain a pointer to the actual implementation
+ static LLPathingLib* getInstance();
+ static LLPathingLib::LLPLResult initSystem();
+ static LLPathingLib::LLPLResult quitSystem();
+
+ //Extract and store navmesh data from the llsd datablock sent down by the server
+ virtual LLPLResult extractNavMeshSrcFromLLSD( const LLSD::Binary& dataBlock, int dir );
+ //Stitch any stored navmeshes together
+ virtual void processNavMeshData();
+
+ //Method used to generate and visualize a path on the viewers navmesh
+ virtual LLPLResult generatePath( const PathingPacket& pathingPacket );
+
+ //Set the material type for the heatmap type
+ virtual void setNavMeshMaterialType( LLPLCharacterType materialType );
+ //Set the various navmesh colors
+ virtual void setNavMeshColors( const NavMeshColors& color );
+
+ //The entry method to rendering the client side navmesh
+ virtual void renderNavMesh();
+ //The entry method to rendering the client side navmesh edges
+ virtual void renderNavMeshEdges();
+ //The entry method to render the client navmesh shapes VBO
+ virtual void renderNavMeshShapesVBO( U32 shapeRenderFlags );
+ //The entry method to render the clients designated path
+ virtual void renderPath();
+ //The entry method to render the capsule bookends for the clients designated path
+ virtual void renderPathBookend( LLRender& gl, LLPathingLib::LLPLPathBookEnd type );
+
+ //Method to delete any vbo's that are currently being managed by the pathing library
+ virtual void cleanupVBOManager();
+ //Method to cleanup any allocations within the implementation
+ virtual void cleanupResidual();
+};
+
+#endif //LL_PATHING_LIB_H
+
diff --git a/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.cpp b/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.cpp
new file mode 100644
index 0000000000..8401e16e9c
--- /dev/null
+++ b/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.cpp
@@ -0,0 +1,51 @@
+/**
+* @file LLPhysicsExtensionsStubImpl.cpp
+* @author prep@lindenlab.com
+* @brief A stubbed implementation of LLPhysicsExtensions
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+
+#include "llphysicsextensions.h"
+#include "LLPhysicsExtensionsStubImpl.h"
+
+//=============================================================================
+LLPhysicsExtensionsImpl::LLPhysicsExtensionsImpl()
+{
+}
+
+LLPhysicsExtensionsImpl::~LLPhysicsExtensionsImpl()
+{
+}
+
+bool LLPhysicsExtensionsImpl::initSystem()
+{
+ return false;
+}
+
+bool LLPhysicsExtensionsImpl::quitSystem()
+{
+ return false;
+}
+
diff --git a/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.h b/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.h
new file mode 100644
index 0000000000..135f92bb88
--- /dev/null
+++ b/indra/llphysicsextensionsos/LLPhysicsExtensionsStubImpl.h
@@ -0,0 +1,46 @@
+/**
+* @file LLPhysicsExtensionsSubImpl.h
+* @author prep@lindenlab.com
+* @brief A stubbed implementation of LLPhysicsExtensions
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_PHYSICS_EXTENSIONS_STUB_IMPL_H
+#define LL_PHYSICS_EXTENSIONS_STUB_IMPL_H
+
+#include "llphysicsextensions.h"
+
+//=============================================================================
+class LLPhysicsExtensionsImpl : public LLPhysicsExtensions
+{
+ public:
+
+ LLPhysicsExtensionsImpl();
+ virtual ~LLPhysicsExtensionsImpl();
+
+ static bool initSystem();
+ static bool quitSystem();
+};
+
+#endif //LL_PHYSICS_EXTENSIONS_STUB_IMPL_H
+
diff --git a/indra/llphysicsextensionsos/llconvexdecomposition.cpp b/indra/llphysicsextensionsos/llconvexdecomposition.cpp
new file mode 100644
index 0000000000..d58c0fec54
--- /dev/null
+++ b/indra/llphysicsextensionsos/llconvexdecomposition.cpp
@@ -0,0 +1,84 @@
+/**
+* @file llconvexdecomposition.cpp
+* @author falcon@lindenlab.com
+* @brief Inner implementation of LLConvexDecomposition interface
+*
+* $LicenseInfo:firstyear=2011&license=lgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include <unordered_map>
+#include "linden_common.h"
+
+#include "llconvexdecompositionvhacd.h"
+#include "llconvexdecomposition.h"
+
+bool LLConvexDecomposition::s_isInitialized = false;
+
+// static
+bool LLConvexDecomposition::isFunctional()
+{
+ return LLConvexDecompositionVHACD::isFunctional();
+}
+
+// static
+LLConvexDecomposition* LLConvexDecomposition::getInstance()
+{
+ if ( !s_isInitialized )
+ {
+ return nullptr;
+ }
+ else
+ {
+ return LLConvexDecompositionVHACD::getInstance();
+ }
+}
+
+// static
+LLCDResult LLConvexDecomposition::initSystem()
+{
+ LLCDResult result = LLConvexDecompositionVHACD::initSystem();
+ if ( result == LLCD_OK )
+ {
+ s_isInitialized = true;
+ }
+ return result;
+}
+
+// static
+LLCDResult LLConvexDecomposition::initThread()
+{
+ return LLConvexDecompositionVHACD::initThread();
+}
+
+// static
+LLCDResult LLConvexDecomposition::quitThread()
+{
+ return LLConvexDecompositionVHACD::quitThread();
+}
+
+// static
+LLCDResult LLConvexDecomposition::quitSystem()
+{
+ return LLConvexDecompositionVHACD::quitSystem();
+}
+
+
diff --git a/indra/llphysicsextensionsos/llconvexdecomposition.h b/indra/llphysicsextensionsos/llconvexdecomposition.h
new file mode 100644
index 0000000000..8008bc6e12
--- /dev/null
+++ b/indra/llphysicsextensionsos/llconvexdecomposition.h
@@ -0,0 +1,231 @@
+/**
+ * @file llconvexdecomposition.cpp
+ * @brief LLConvexDecomposition interface definition
+ *
+ * $LicenseInfo:firstyear=2011&license=lgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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_CONVEX_DECOMPOSITION
+#define LL_CONVEX_DECOMPOSITION
+
+typedef int bool32;
+
+#if defined(_WIN32) || defined(_WIN64)
+#define LLCD_CALL __cdecl
+#else
+#define LLCD_CALL
+#endif
+
+struct LLCDParam
+{
+ enum LLCDParamType
+ {
+ LLCD_INVALID = 0,
+ LLCD_INTEGER,
+ LLCD_FLOAT,
+ LLCD_BOOLEAN,
+ LLCD_ENUM
+ };
+
+ struct LLCDEnumItem
+ {
+ const char* mName;
+ int mValue;
+ };
+
+ union LLCDValue
+ {
+ float mFloat;
+ int mIntOrEnumValue;
+ bool32 mBool;
+ };
+
+ union LLCDParamDetails
+ {
+ struct {
+ LLCDValue mLow;
+ LLCDValue mHigh;
+ LLCDValue mDelta;
+ } mRange;
+
+ struct {
+ int mNumEnums;
+ LLCDEnumItem* mEnumsArray;
+ } mEnumValues;
+ };
+
+ const char* mName;
+ const char* mDescription;
+ LLCDParamType mType;
+ LLCDParamDetails mDetails;
+ LLCDValue mDefault;
+ int mStage;
+
+ // WARNING: Only the LLConvexDecomposition implementation
+ // should change this value
+ int mReserved;
+};
+
+struct LLCDStageData
+{
+ const char* mName;
+ const char* mDescription;
+ bool32 mSupportsCallback;
+};
+
+struct LLCDMeshData
+{
+ enum IndexType
+ {
+ INT_16,
+ INT_32
+ };
+
+ const float* mVertexBase;
+ int mVertexStrideBytes;
+ int mNumVertices;
+ const void* mIndexBase;
+ IndexType mIndexType;
+ int mIndexStrideBytes;
+ int mNumTriangles;
+};
+
+struct LLCDHull
+{
+ const float* mVertexBase;
+ int mVertexStrideBytes;
+ int mNumVertices;
+};
+
+enum LLCDResult
+{
+ LLCD_OK = 0,
+ LLCD_UNKOWN_ERROR,
+ LLCD_NULL_PTR,
+ LLCD_INVALID_STAGE,
+ LLCD_UNKNOWN_PARAM,
+ LLCD_BAD_VALUE,
+ LLCD_REQUEST_OUT_OF_RANGE,
+ LLCD_INVALID_MESH_DATA,
+ LLCD_INVALID_HULL_DATA,
+ LLCD_STAGE_NOT_READY,
+ LLCD_INVALID_THREAD,
+ LLCD_NOT_IMPLEMENTED
+};
+
+// This callback will receive a string describing the current subtask being performed
+// as well as a pair of numbers indicating progress. (The values should not be interpreted
+// as a completion percentage as 'current' may be greater than 'final'.)
+// If the callback returns zero, the decomposition will be terminated
+typedef int (LLCD_CALL *llcdCallbackFunc)(const char* description, int current_progress, int final_progress);
+
+class LLConvexDecomposition
+{
+public:
+ // Obtain a pointer to the actual implementation
+ static LLConvexDecomposition* getInstance();
+
+ /// @returns false if this is the stub
+ static bool isFunctional();
+
+ static LLCDResult initSystem();
+ static LLCDResult initThread();
+ static LLCDResult quitThread();
+ static LLCDResult quitSystem();
+
+ // Generate a decomposition object handle
+ virtual void genDecomposition(int& decomp) = 0;
+ // Delete decomposition object handle
+ virtual void deleteDecomposition(int decomp) = 0;
+ // Bind given decomposition handle
+ // Commands operate on currently bound decomposition
+ virtual void bindDecomposition(int decomp) = 0;
+
+ // Sets *paramsOut to the address of the LLCDParam array and returns
+ // the number of parameters
+ virtual int getParameters(const LLCDParam** paramsOut) = 0;
+
+
+ // Sets *stagesOut to the address of the LLCDStageData array and returns
+ // the number of stages
+ virtual int getStages(const LLCDStageData** stagesOut) = 0;
+
+
+ // Set a parameter by name. Pass enum values as integers.
+ virtual LLCDResult setParam(const char* name, float val) = 0;
+ virtual LLCDResult setParam(const char* name, int val) = 0;
+ virtual LLCDResult setParam(const char* name, bool val) = 0;
+
+
+ // Set incoming mesh data. Data is copied to local buffers and will
+ // persist until the next setMeshData call
+ virtual LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based ) = 0;
+
+
+ // Register a callback to be called periodically during the specified stage
+ // See the typedef above for more information
+ virtual LLCDResult registerCallback( int stage, llcdCallbackFunc callback ) = 0;
+
+
+ // Execute the specified decomposition stage
+ virtual LLCDResult executeStage(int stage) = 0;
+ virtual LLCDResult buildSingleHull() = 0 ;
+
+
+ // Gets the number of hulls generated by the specified decompositions stage
+ virtual int getNumHullsFromStage(int stage) = 0;
+
+
+ // Populates hullOut to reference the internal copy of the requested hull
+ // The data will persist only until the next executeStage call for that stage.
+ virtual LLCDResult getHullFromStage( int stage, int hull, LLCDHull* hullOut ) = 0;
+
+ virtual LLCDResult getSingleHull( LLCDHull* hullOut ) = 0 ;
+
+
+ // TODO: Implement lock of some kind to disallow this call if data not yet ready
+ // Populates the meshDataOut to reference the utility's copy of the mesh geometry
+ // for the hull and stage specified.
+ // You must copy this data if you want to continue using it after the next executeStage
+ // call
+ virtual LLCDResult getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut) = 0;
+
+
+ // Creates a mesh from hullIn and temporarily stores it internally in the utility.
+ // The mesh data persists only until the next call to getMeshFromHull
+ virtual LLCDResult getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut ) = 0;
+
+ // Takes meshIn, generates a single convex hull from it, converts that to a mesh
+ // stored internally, and populates meshOut to reference the internally stored data.
+ // The data is persistent only until the next call to generateSingleHullMeshFromMesh
+ virtual LLCDResult generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut) = 0;
+
+ //
+ /// Debug
+ virtual void loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut) = 0;
+
+private:
+ static bool s_isInitialized;
+};
+
+#endif //LL_CONVEX_DECOMPOSITION
+
diff --git a/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp
new file mode 100644
index 0000000000..78876f9f36
--- /dev/null
+++ b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.cpp
@@ -0,0 +1,492 @@
+/**
+* @file llconvexdecompositionvhacd.cpp
+* @author rye@alchemyviewer.org
+* @brief A VHACD based implementation of LLConvexDecomposition
+*
+* $LicenseInfo:firstyear=2025&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2025, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+
+#include "llmath.h"
+#include "v3math.h"
+
+#include <string.h>
+#include <memory>
+
+#define ENABLE_VHACD_IMPLEMENTATION 1
+#include "VHACD.h"
+
+#include "llconvexdecompositionvhacd.h"
+
+constexpr S32 MAX_HULLS = 256;
+constexpr S32 MAX_VERTICES_PER_HULL = 256;
+
+bool LLConvexDecompositionVHACD::isFunctional()
+{
+ return true;
+}
+
+LLConvexDecomposition* LLConvexDecompositionVHACD::getInstance()
+{
+ return LLSimpleton::getInstance();
+}
+
+LLCDResult LLConvexDecompositionVHACD::initSystem()
+{
+ createInstance();
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::initThread()
+{
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::quitThread()
+{
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::quitSystem()
+{
+ deleteSingleton();
+ return LLCD_OK;
+}
+
+LLConvexDecompositionVHACD::LLConvexDecompositionVHACD()
+{
+ //Create our vhacd instance and setup default parameters
+ mVHACD = VHACD::CreateVHACD();
+
+ mVHACDParameters.m_callback = &mVHACDCallback;
+ mVHACDParameters.m_logger = &mVHACDLogger;
+
+ mDecompStages[0].mName = "Analyze";
+ mDecompStages[0].mDescription = nullptr;
+
+ LLCDParam param;
+ param.mName = "Fill Mode";
+ param.mDescription = nullptr;
+ param.mType = LLCDParam::LLCD_ENUM;
+ param.mDetails.mEnumValues.mNumEnums = 3;
+
+ static LLCDParam::LLCDEnumItem fill_enums[3];
+ fill_enums[(size_t)VHACD::FillMode::FLOOD_FILL].mName = "Flood";
+ fill_enums[(size_t)VHACD::FillMode::FLOOD_FILL].mValue = (int)VHACD::FillMode::FLOOD_FILL;
+ fill_enums[(size_t)VHACD::FillMode::SURFACE_ONLY].mName = "Surface Only";
+ fill_enums[(size_t)VHACD::FillMode::SURFACE_ONLY].mValue = (int)VHACD::FillMode::SURFACE_ONLY;
+ fill_enums[(size_t)VHACD::FillMode::RAYCAST_FILL].mName = "Raycast";
+ fill_enums[(size_t)VHACD::FillMode::RAYCAST_FILL].mValue = (int)VHACD::FillMode::RAYCAST_FILL;
+
+ param.mDetails.mEnumValues.mEnumsArray = fill_enums;
+ param.mDefault.mIntOrEnumValue = (int)VHACD::FillMode::FLOOD_FILL;
+ param.mStage = 0;
+ param.mReserved = -1;
+ mDecompParams.push_back(param);
+
+ enum EVoxelQualityLevels
+ {
+ E_LOW_QUALITY = 0,
+ E_NORMAL_QUALITY,
+ E_HIGH_QUALITY,
+ E_VERY_HIGH_QUALITY,
+ E_ULTRA_QUALITY,
+ E_MAX_QUALITY,
+ E_NUM_QUALITY_LEVELS
+ };
+
+ param.mName = "Voxel Resolution";
+ param.mDescription = nullptr;
+ param.mType = LLCDParam::LLCD_ENUM;
+ param.mDetails.mEnumValues.mNumEnums = E_NUM_QUALITY_LEVELS;
+
+ static LLCDParam::LLCDEnumItem voxel_quality_enums[E_NUM_QUALITY_LEVELS];
+ voxel_quality_enums[E_LOW_QUALITY].mName = "Low";
+ voxel_quality_enums[E_LOW_QUALITY].mValue = 200000;
+ voxel_quality_enums[E_NORMAL_QUALITY].mName = "Normal";
+ voxel_quality_enums[E_NORMAL_QUALITY].mValue = 400000;
+ voxel_quality_enums[E_HIGH_QUALITY].mName = "High";
+ voxel_quality_enums[E_HIGH_QUALITY].mValue = 800000;
+ voxel_quality_enums[E_VERY_HIGH_QUALITY].mName = "Very High";
+ voxel_quality_enums[E_VERY_HIGH_QUALITY].mValue = 1200000;
+ voxel_quality_enums[E_ULTRA_QUALITY].mName = "Ultra";
+ voxel_quality_enums[E_ULTRA_QUALITY].mValue = 1600000;
+ voxel_quality_enums[E_MAX_QUALITY].mName = "Maximum";
+ voxel_quality_enums[E_MAX_QUALITY].mValue = 2000000;
+
+ param.mDetails.mEnumValues.mEnumsArray = voxel_quality_enums;
+ param.mDefault.mIntOrEnumValue = 400000;
+ param.mStage = 0;
+ param.mReserved = -1;
+ mDecompParams.push_back(param);
+
+ param.mName = "Num Hulls";
+ param.mDescription = nullptr;
+ param.mType = LLCDParam::LLCD_FLOAT;
+ param.mDetails.mRange.mLow.mFloat = 1.f;
+ param.mDetails.mRange.mHigh.mFloat = MAX_HULLS;
+ param.mDetails.mRange.mDelta.mFloat = 1.f;
+ param.mDefault.mFloat = 8.f;
+ param.mStage = 0;
+ param.mReserved = -1;
+ mDecompParams.push_back(param);
+
+ param.mName = "Num Vertices";
+ param.mDescription = nullptr;
+ param.mType = LLCDParam::LLCD_FLOAT;
+ param.mDetails.mRange.mLow.mFloat = 3.f;
+ param.mDetails.mRange.mHigh.mFloat = MAX_VERTICES_PER_HULL;
+ param.mDetails.mRange.mDelta.mFloat = 1.f;
+ param.mDefault.mFloat = 32.f;
+ param.mStage = 0;
+ param.mReserved = -1;
+ mDecompParams.push_back(param);
+
+ param.mName = "Error Tolerance";
+ param.mDescription = nullptr;
+ param.mType = LLCDParam::LLCD_FLOAT;
+ param.mDetails.mRange.mLow.mFloat = 0.0001f;
+ param.mDetails.mRange.mHigh.mFloat = 99.f;
+ param.mDetails.mRange.mDelta.mFloat = 0.001f;
+ param.mDefault.mFloat = 1.f;
+ param.mStage = 0;
+ param.mReserved = -1;
+ mDecompParams.push_back(param);
+
+ for (const LLCDParam& param : mDecompParams)
+ {
+ const char* const name = param.mName;
+
+ switch (param.mType)
+ {
+ case LLCDParam::LLCD_FLOAT:
+ {
+ setParam(name, param.mDefault.mFloat);
+ break;
+ }
+ case LLCDParam::LLCD_ENUM:
+ case LLCDParam::LLCD_INTEGER:
+ {
+ setParam(name, param.mDefault.mIntOrEnumValue);
+ break;
+ }
+ case LLCDParam::LLCD_BOOLEAN:
+ {
+ setParam(name, (param.mDefault.mBool != 0));
+ break;
+ }
+ case LLCDParam::LLCD_INVALID:
+ default:
+ {
+ break;
+ }
+ }
+ }
+}
+
+LLConvexDecompositionVHACD::~LLConvexDecompositionVHACD()
+{
+ mBoundDecomp = nullptr;
+ mDecompData.clear();
+
+ mVHACD->Release();
+}
+
+void LLConvexDecompositionVHACD::genDecomposition(int& decomp)
+{
+ int new_decomp_id = static_cast<int>(mDecompData.size()) + 1;
+ mDecompData[new_decomp_id] = LLDecompData();
+ decomp = new_decomp_id;
+}
+
+void LLConvexDecompositionVHACD::deleteDecomposition(int decomp)
+{
+ auto iter = mDecompData.find(decomp);
+ if (iter != mDecompData.end())
+ {
+ if (mBoundDecomp == &iter->second)
+ {
+ mBoundDecomp = nullptr;
+ }
+ mDecompData.erase(iter);
+ }
+}
+
+void LLConvexDecompositionVHACD::bindDecomposition(int decomp)
+{
+ auto iter = mDecompData.find(decomp);
+ if (iter != mDecompData.end())
+ {
+ mBoundDecomp = &iter->second;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to bind unknown decomposition: " << decomp << LL_ENDL;
+ mBoundDecomp = nullptr;
+ }
+}
+
+LLCDResult LLConvexDecompositionVHACD::setParam(const char* name, float val)
+{
+ if (name == std::string("Num Hulls"))
+ {
+ mVHACDParameters.m_maxConvexHulls = llclamp(ll_round(val), 1, MAX_HULLS);
+ }
+ else if (name == std::string("Num Vertices"))
+ {
+ mVHACDParameters.m_maxNumVerticesPerCH = llclamp(ll_round(val), 3, MAX_VERTICES_PER_HULL);
+ }
+ else if (name == std::string("Error Tolerance"))
+ {
+ mVHACDParameters.m_minimumVolumePercentErrorAllowed = val;
+ }
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::setParam(const char* name, bool val)
+{
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::setParam(const char* name, int val)
+{
+ if (name == std::string("Fill Mode"))
+ {
+ mVHACDParameters.m_fillMode = (VHACD::FillMode)val;
+ }
+ else if (name == std::string("Voxel Resolution"))
+ {
+ mVHACDParameters.m_resolution = val;
+ }
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::setMeshData( const LLCDMeshData* data, bool vertex_based )
+{
+ if (!mBoundDecomp)
+ {
+ return LLCD_NULL_PTR;
+ }
+
+ return mBoundDecomp->mSourceMesh.from(data, vertex_based);
+}
+
+LLCDResult LLConvexDecompositionVHACD::registerCallback(int stage, llcdCallbackFunc callback )
+{
+ if (stage == 0)
+ {
+ mVHACDCallback.setCallbackFunc(callback);
+ return LLCD_OK;
+ }
+ else
+ {
+ return LLCD_INVALID_STAGE;
+ }
+}
+
+LLCDResult LLConvexDecompositionVHACD::executeStage(int stage)
+{
+ if (!mBoundDecomp)
+ {
+ return LLCD_NULL_PTR;
+ }
+
+ if (stage != 0)
+ {
+ return LLCD_INVALID_STAGE;
+ }
+
+ mBoundDecomp->mDecomposedHulls.clear();
+
+ const auto& decomp_mesh = mBoundDecomp->mSourceMesh;
+ if (!mVHACD->Compute((const double* const)decomp_mesh.mVertices.data(), static_cast<uint32_t>(decomp_mesh.mVertices.size()), (const uint32_t* const)decomp_mesh.mIndices.data(), static_cast<uint32_t>(decomp_mesh.mIndices.size()), mVHACDParameters))
+ {
+ return LLCD_INVALID_HULL_DATA;
+ }
+
+ uint32_t num_nulls = mVHACD->GetNConvexHulls();
+ if (num_nulls == 0)
+ {
+ return LLCD_INVALID_HULL_DATA;
+ }
+
+ for (uint32_t i = 0; num_nulls > i; ++i)
+ {
+ VHACD::IVHACD::ConvexHull ch;
+ if (!mVHACD->GetConvexHull(i, ch))
+ continue;
+
+ LLConvexMesh out_mesh;
+ out_mesh.setVertices(ch.m_points);
+ out_mesh.setIndices(ch.m_triangles);
+
+ mBoundDecomp->mDecomposedHulls.push_back(std::move(out_mesh));
+ }
+
+ mVHACD->Clean();
+
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::buildSingleHull()
+{
+ LL_INFOS() << "Building single hull mesh" << LL_ENDL;
+ if (!mBoundDecomp || mBoundDecomp->mSourceMesh.mVertices.empty())
+ {
+ return LLCD_NULL_PTR;
+ }
+
+ mBoundDecomp->mSingleHullMesh.clear();
+
+ VHACD::QuickHull quickhull;
+ uint32_t num_tris = quickhull.ComputeConvexHull(mBoundDecomp->mSourceMesh.mVertices, MAX_VERTICES_PER_HULL);
+ if (num_tris > 0)
+ {
+ mBoundDecomp->mSingleHullMesh.setVertices(quickhull.GetVertices());
+ mBoundDecomp->mSingleHullMesh.setIndices(quickhull.GetIndices());
+
+ return LLCD_OK;
+ }
+
+ return LLCD_INVALID_MESH_DATA;
+}
+
+int LLConvexDecompositionVHACD::getNumHullsFromStage(int stage)
+{
+ if (!mBoundDecomp || stage != 0)
+ {
+ return 0;
+ }
+
+ return narrow(mBoundDecomp->mDecomposedHulls.size());
+}
+
+LLCDResult LLConvexDecompositionVHACD::getSingleHull( LLCDHull* hullOut )
+{
+ memset( hullOut, 0, sizeof(LLCDHull) );
+
+ if (!mBoundDecomp)
+ {
+ return LLCD_NULL_PTR;
+ }
+
+ if (mBoundDecomp->mSingleHullMesh.vertices.empty())
+ {
+ return LLCD_INVALID_HULL_DATA;
+ }
+
+ mBoundDecomp->mSingleHullMesh.to(hullOut);
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::getHullFromStage( int stage, int hull, LLCDHull* hullOut )
+{
+ memset( hullOut, 0, sizeof(LLCDHull) );
+
+ if (!mBoundDecomp)
+ {
+ return LLCD_NULL_PTR;
+ }
+
+ if (stage != 0)
+ {
+ return LLCD_INVALID_STAGE;
+ }
+
+ if (mBoundDecomp->mDecomposedHulls.empty() || mBoundDecomp->mDecomposedHulls.size() <= hull)
+ {
+ return LLCD_REQUEST_OUT_OF_RANGE;
+ }
+
+ mBoundDecomp->mDecomposedHulls[hull].to(hullOut);
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut )
+{
+ memset( meshDataOut, 0, sizeof(LLCDMeshData));
+ if (!mBoundDecomp)
+ {
+ return LLCD_NULL_PTR;
+ }
+
+ if (stage != 0)
+ {
+ return LLCD_INVALID_STAGE;
+ }
+
+ if (mBoundDecomp->mDecomposedHulls.empty() || mBoundDecomp->mDecomposedHulls.size() <= hull)
+ {
+ return LLCD_REQUEST_OUT_OF_RANGE;
+ }
+
+ mBoundDecomp->mDecomposedHulls[hull].to(meshDataOut);
+ return LLCD_OK;
+}
+
+LLCDResult LLConvexDecompositionVHACD::getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut )
+{
+ memset(meshOut, 0, sizeof(LLCDMeshData));
+
+ LLVHACDMesh inMesh(hullIn);
+
+ VHACD::QuickHull quickhull;
+ uint32_t num_tris = quickhull.ComputeConvexHull(inMesh.mVertices, MAX_VERTICES_PER_HULL);
+ if (num_tris > 0)
+ {
+ mMeshFromHullData.setVertices(quickhull.GetVertices());
+ mMeshFromHullData.setIndices(quickhull.GetIndices());
+
+ mMeshFromHullData.to(meshOut);
+ return LLCD_OK;
+ }
+
+ return LLCD_INVALID_HULL_DATA;
+}
+
+LLCDResult LLConvexDecompositionVHACD::generateSingleHullMeshFromMesh(LLCDMeshData* meshIn, LLCDMeshData* meshOut)
+{
+ memset( meshOut, 0, sizeof(LLCDMeshData) );
+
+ LLVHACDMesh inMesh(meshIn, true);
+
+ VHACD::QuickHull quickhull;
+ uint32_t num_tris = quickhull.ComputeConvexHull(inMesh.mVertices, MAX_VERTICES_PER_HULL);
+ if (num_tris > 0)
+ {
+ mSingleHullMeshFromMeshData.setVertices(quickhull.GetVertices());
+ mSingleHullMeshFromMeshData.setIndices(quickhull.GetIndices());
+
+ mSingleHullMeshFromMeshData.to(meshOut);
+ return LLCD_OK;
+ }
+
+ return LLCD_INVALID_MESH_DATA;
+}
+
+void LLConvexDecompositionVHACD::loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut)
+{
+ static LLCDMeshData meshData;
+ memset( &meshData, 0, sizeof(LLCDMeshData) );
+ *meshDataOut = &meshData;
+}
diff --git a/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h
new file mode 100644
index 0000000000..675356629c
--- /dev/null
+++ b/indra/llphysicsextensionsos/llconvexdecompositionvhacd.h
@@ -0,0 +1,339 @@
+/**
+* @file llconvexdecompositionvhacd.h
+* @author rye@alchemyviewer.org
+* @brief A VHACD based implementation of LLConvexDecomposition
+*
+* $LicenseInfo:firstyear=2025&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2025, 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_CONVEX_DECOMP_UTIL_VHACD_H
+#define LL_CONVEX_DECOMP_UTIL_VHACD_H
+
+#include "llconvexdecomposition.h"
+#include "llsingleton.h"
+#include "llmath.h"
+
+#include <vector>
+
+#include "VHACD.h"
+
+class LLDecompDataVHACD;
+
+class LLConvexDecompositionVHACD : public LLSimpleton<LLConvexDecompositionVHACD>, public LLConvexDecomposition
+{
+ class VHACDCallback : public VHACD::IVHACD::IUserCallback
+ {
+ public:
+ void Update(const double overallProgress, const double stageProgress, const char* const stage, const char* operation) override
+ {
+ std::string out_msg = llformat("Stage: %s Operation: %s", stage, operation);
+ if (mCurrentStage != stage && mCurrentOperation != operation)
+ {
+ mCurrentStage = stage;
+ mCurrentOperation = operation;
+ LL_INFOS("VHACD") << out_msg << LL_ENDL;
+ }
+
+ if(mCallbackFunc)
+ {
+ mCallbackFunc(out_msg.c_str(), ll_round(static_cast<F32>(stageProgress)), ll_round(static_cast<F32>(overallProgress)));
+ }
+ }
+
+ void setCallbackFunc(llcdCallbackFunc func)
+ {
+ mCallbackFunc = func;
+ }
+
+ private:
+ std::string mCurrentStage;
+ std::string mCurrentOperation;
+ llcdCallbackFunc mCallbackFunc = nullptr;
+ };
+
+ class VHACDLogger : public VHACD::IVHACD::IUserLogger
+ {
+ void Log(const char* const msg) override
+ {
+ LL_INFOS("VHACD") << msg << LL_ENDL;
+ }
+ };
+
+public:
+
+ LLConvexDecompositionVHACD();
+ virtual ~LLConvexDecompositionVHACD();
+
+ static bool isFunctional();
+ static LLConvexDecomposition* getInstance();
+ static LLCDResult initSystem();
+ static LLCDResult initThread();
+ static LLCDResult quitThread();
+ static LLCDResult quitSystem();
+
+ void genDecomposition(int& decomp);
+ void deleteDecomposition(int decomp);
+ void bindDecomposition(int decomp);
+
+ // Sets *paramsOut to the address of the LLCDParam array and returns
+ // the length of the array
+ int getParameters(const LLCDParam** paramsOut)
+ {
+ *paramsOut = mDecompParams.data();
+ return narrow(mDecompParams.size());
+ }
+
+ int getStages(const LLCDStageData** stagesOut)
+ {
+ *stagesOut = mDecompStages.data();
+ return narrow(mDecompStages.size());
+ }
+
+ // Set a parameter by name. Returns false if out of bounds or unsupported parameter
+ LLCDResult setParam(const char* name, float val);
+ LLCDResult setParam(const char* name, int val);
+ LLCDResult setParam(const char* name, bool val);
+ LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based );
+ LLCDResult registerCallback(int stage, llcdCallbackFunc callback );
+
+ LLCDResult executeStage(int stage);
+ LLCDResult buildSingleHull();
+
+ int getNumHullsFromStage(int stage);
+
+ LLCDResult getHullFromStage( int stage, int hull, LLCDHull* hullOut );
+ LLCDResult getSingleHull( LLCDHull* hullOut ) ;
+
+ // TODO: Implement lock of some kind to disallow this call if data not yet ready
+ LLCDResult getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut);
+ LLCDResult getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut );
+
+ // For visualizing convex hull shapes in the viewer physics shape display
+ LLCDResult generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut);
+
+ /// Debug
+ void loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut);
+
+private:
+ std::vector<LLCDParam> mDecompParams;
+ std::array<LLCDStageData, 1> mDecompStages;
+
+ struct LLVHACDMesh
+ {
+ using vertex_type = VHACD::Vertex;
+ using index_type = VHACD::Triangle;
+ using vertex_array_type = std::vector<vertex_type>;
+ using index_array_type = std::vector<index_type>;
+
+ LLVHACDMesh() = default;
+ LLVHACDMesh(const LLCDHull* hullIn)
+ {
+ if (hullIn)
+ {
+ from(hullIn);
+ }
+ };
+
+ LLVHACDMesh(const LLCDMeshData* meshIn, bool vertex_based)
+ {
+ if (meshIn)
+ {
+ from(meshIn, vertex_based);
+ }
+ };
+
+ void clear()
+ {
+ mVertices.clear();
+ mIndices.clear();
+ }
+
+ void setVertices(const float* data, int num_vertices, int vertex_stride_bytes)
+ {
+ vertex_array_type vertices;
+ vertices.reserve(num_vertices);
+
+ const int stride = vertex_stride_bytes / sizeof(float);
+ for (int i = 0; i < num_vertices; ++i)
+ {
+ vertices.emplace_back(data[i * stride + 0],
+ data[i * stride + 1],
+ data[i * stride + 2]);
+ }
+
+ mVertices = std::move(vertices);
+ }
+
+ void setIndices(const void* data, int num_indices, int index_stride_bytes, LLCDMeshData::IndexType type)
+ {
+ index_array_type indices;
+ indices.reserve(num_indices);
+
+ if (type == LLCDMeshData::INT_16)
+ {
+ const U16* index_data = static_cast<const U16*>(data);
+ const int stride = index_stride_bytes / sizeof(U16);
+ for (int i = 0; i < num_indices; ++i)
+ {
+ indices.emplace_back(index_data[i * stride + 0],
+ index_data[i * stride + 1],
+ index_data[i * stride + 2]);
+ }
+ }
+ else
+ {
+ const U32* index_data = static_cast<const U32*>(data);
+ const int stride = index_stride_bytes / sizeof(U32);
+ for (int i = 0; i < num_indices; ++i)
+ {
+ indices.emplace_back(index_data[i * stride + 0],
+ index_data[i * stride + 1],
+ index_data[i * stride + 2]);
+ }
+ }
+
+ mIndices = std::move(indices);
+ }
+
+ LLCDResult from(const LLCDHull* hullIn)
+ {
+ clear();
+
+ if (!hullIn || !hullIn->mVertexBase || (hullIn->mNumVertices < 3) || (hullIn->mVertexStrideBytes != 12 && hullIn->mVertexStrideBytes != 16))
+ {
+ return LLCD_INVALID_HULL_DATA;
+ }
+
+ setVertices(hullIn->mVertexBase, hullIn->mNumVertices, hullIn->mVertexStrideBytes);
+
+ return LLCD_OK;
+ }
+
+ LLCDResult from(const LLCDMeshData* meshIn, bool vertex_based)
+ {
+ clear();
+
+ if (!meshIn || !meshIn->mVertexBase || (meshIn->mNumVertices < 3) || (meshIn->mVertexStrideBytes != 12 && meshIn->mVertexStrideBytes != 16))
+ {
+ return LLCD_INVALID_MESH_DATA;
+ }
+
+ if (!vertex_based && ((meshIn->mNumTriangles < 1) || !meshIn->mIndexBase))
+ {
+ return LLCD_INVALID_MESH_DATA;
+ }
+
+ setVertices(meshIn->mVertexBase, meshIn->mNumVertices, meshIn->mVertexStrideBytes);
+ if(!vertex_based)
+ {
+ setIndices(meshIn->mIndexBase, meshIn->mNumTriangles, meshIn->mIndexStrideBytes, meshIn->mIndexType);
+ }
+
+ return LLCD_OK;
+ }
+
+ vertex_array_type mVertices;
+ index_array_type mIndices;
+ };
+
+ struct LLConvexMesh
+ {
+ using vertex_type = glm::vec3;
+ using index_type = glm::u32vec3;
+ using vertex_array_type = std::vector<vertex_type>;
+ using index_array_type = std::vector<index_type>;
+
+ LLConvexMesh() = default;
+
+ void clear()
+ {
+ vertices.clear();
+ indices.clear();
+ }
+
+ void setVertices(const std::vector<VHACD::Vertex>& in_vertices)
+ {
+ vertices.clear();
+ vertices.reserve(in_vertices.size());
+
+ for (const auto& vertex : in_vertices)
+ {
+ vertices.emplace_back(narrow(vertex.mX), narrow(vertex.mY), narrow(vertex.mZ));
+ }
+ }
+
+ void setIndices(const std::vector<VHACD::Triangle>& in_indices)
+ {
+ indices.clear();
+ indices.reserve(in_indices.size());
+
+ for (const auto& triangle : in_indices)
+ {
+ indices.emplace_back(narrow(triangle.mI0), narrow(triangle.mI1), narrow(triangle.mI2));
+ }
+ }
+
+ void to(LLCDHull* meshOut) const
+ {
+ meshOut->mVertexBase = (float*)vertices.data();
+ meshOut->mVertexStrideBytes = sizeof(vertex_type);
+ meshOut->mNumVertices = (int)vertices.size();
+ }
+
+ void to(LLCDMeshData* meshOut) const
+ {
+ meshOut->mVertexBase = (float*)vertices.data();
+ meshOut->mVertexStrideBytes = sizeof(vertex_type);
+ meshOut->mNumVertices = (int)vertices.size();
+
+ meshOut->mIndexType = LLCDMeshData::INT_32;
+ meshOut->mIndexBase = indices.data();
+ meshOut->mIndexStrideBytes = sizeof(index_type);
+ meshOut->mNumTriangles = (int)indices.size();
+ }
+
+ vertex_array_type vertices;
+ index_array_type indices;
+ };
+
+ struct LLDecompData
+ {
+ LLVHACDMesh mSourceMesh;
+ LLConvexMesh mSingleHullMesh;
+
+ std::vector<LLConvexMesh> mDecomposedHulls;
+ };
+
+ std::unordered_map<int, LLDecompData> mDecompData;
+
+ LLDecompData* mBoundDecomp = nullptr;
+
+ VHACD::IVHACD* mVHACD = nullptr;
+ VHACDCallback mVHACDCallback;
+ VHACDLogger mVHACDLogger;
+ VHACD::IVHACD::Parameters mVHACDParameters;
+
+ LLConvexMesh mMeshFromHullData;
+ LLConvexMesh mSingleHullMeshFromMeshData;
+};
+
+#endif //LL_CONVEX_DECOMP_UTIL_VHACD_H
diff --git a/indra/llphysicsextensionsos/llpathinglib.cpp b/indra/llphysicsextensionsos/llpathinglib.cpp
new file mode 100644
index 0000000000..f41cb9c45f
--- /dev/null
+++ b/indra/llphysicsextensionsos/llpathinglib.cpp
@@ -0,0 +1,83 @@
+/**
+* @file llpathinglib.cpp
+* @author prep@lindenlab.com
+* @brief LLPathingLib core creation methods
+*
+* $LicenseInfo:firstyear=2012&license=lgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+
+#include "LLPathingLibStubImpl.h"
+
+#include "llpathinglib.h"
+
+//=============================================================================
+
+/*static */bool LLPathingLib::s_isInitialized = false;
+
+//=============================================================================
+
+
+/*static*/bool LLPathingLib::isFunctional()
+{
+ return false;
+}
+
+/*static*/LLPathingLib* LLPathingLib::getInstance()
+{
+ if ( !s_isInitialized )
+ {
+ return NULL;
+ }
+ else
+ {
+ return LLPathingLibImpl::getInstance();
+ }
+}
+
+//=============================================================================
+
+/*static */LLPathingLib::LLPLResult LLPathingLib::initSystem()
+{
+ if ( LLPathingLibImpl::initSystem() == LLPL_OK )
+ {
+ s_isInitialized = true;
+ return LLPL_OK;
+ }
+ return LLPL_UNKOWN_ERROR;
+}
+//=============================================================================
+/*static */LLPathingLib::LLPLResult LLPathingLib::quitSystem()
+{
+ LLPLResult quitResult = LLPL_UNKOWN_ERROR;
+
+ if (s_isInitialized)
+ {
+ quitResult = LLPathingLibImpl::quitSystem();
+ s_isInitialized = false;
+ }
+
+ return quitResult;
+}
+//=============================================================================
+
diff --git a/indra/llphysicsextensionsos/llpathinglib.h b/indra/llphysicsextensionsos/llpathinglib.h
new file mode 100644
index 0000000000..41583f1fd1
--- /dev/null
+++ b/indra/llphysicsextensionsos/llpathinglib.h
@@ -0,0 +1,187 @@
+/**
+ * @file llpathinglib.cpp
+ * @author prep@lindenlab.com
+ * @brief LLPathingLib interface definition
+ *
+ * $LicenseInfo:firstyear=2012&license=lgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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_PATHING_LIBRARY
+#define LL_PATHING_LIBRARY
+
+#include "llpreprocessor.h"
+#include "llsd.h"
+#include "v3dmath.h"
+#include "v4math.h"
+
+#include "v4color.h"
+#include "v4coloru.h"
+#include "llphysicsextensions.h"
+
+typedef int bool32;
+
+#if defined(_WIN32) || defined(_WIN64)
+#define LLCD_CALL __cdecl
+#else
+#define LLCD_CALL
+#endif
+
+class LLRender;
+
+//=============================================================================
+class LLPathingLib
+{
+
+public:
+ enum LLShapeType
+ {
+ LLST_WalkableObjects = 0,
+ LLST_ObstacleObjects,
+ LLST_MaterialPhantoms,
+ LLST_ExclusionPhantoms,
+ LLST_MaxShapeTypes = LLST_ExclusionPhantoms+1,
+ LLST_None = LLST_MaxShapeTypes+2,
+ LLST_SimpleBox = LLST_None+1,
+ LLST_SimpleCapsule = LLST_SimpleBox+1,
+ };
+
+ enum LLShapeTypeFlag
+ {
+ LLSTB_WalkableObjects = 0x1 << 1,
+ LLSTB_ObstacleObjects = 0x1 << 2,
+ LLSTB_MaterialPhantoms = 0x1 << 3,
+ LLSTB_ExclusionPhantoms = 0x1 << 4,
+ LLSTB_None = 0x1 << 5
+ };
+
+ enum LLPLPathBookEnd
+ {
+ LLPL_START = 0,
+ LLPL_END,
+ };
+
+ enum LLPLResult
+ {
+ LLPL_OK = 0,
+ LLPL_NOTSET,
+ LLPL_ERROR,
+ LLPL_NO_NAVMESH,
+ LLPL_UNKOWN_ERROR,
+ LLPL_NO_PATH,
+ LLPL_PATH_GENERATED_OK,
+ LLPL_NOT_IMPLEMENTED,
+ };
+
+ enum LLPLCharacterType
+ {
+ LLPL_CHARACTER_TYPE_A = 4,
+ LLPL_CHARACTER_TYPE_B = 3,
+ LLPL_CHARACTER_TYPE_C = 2,
+ LLPL_CHARACTER_TYPE_D = 1,
+ LLPL_CHARACTER_TYPE_NONE = 0
+ };
+
+ struct PathingPacket
+ {
+ PathingPacket() : mHasPointA(false), mHasPointB(false), mCharacterWidth(0.0f), mCharacterType(LLPL_CHARACTER_TYPE_NONE) {}
+ bool mHasPointA;
+ LLVector3 mStartPointA;
+ LLVector3 mEndPointA;
+ bool mHasPointB;
+ LLVector3 mStartPointB;
+ LLVector3 mEndPointB;
+ F32 mCharacterWidth;
+ LLPLCharacterType mCharacterType;
+ };
+
+ struct NavMeshColors
+ {
+ LLColor4U mWalkable;
+ LLColor4U mObstacle;
+ LLColor4U mMaterial;
+ LLColor4U mExclusion;
+ LLColor4U mConnectedEdge;
+ LLColor4U mBoundaryEdge;
+ LLColor4 mHeatColorBase;
+ LLColor4 mHeatColorMax;
+ LLColor4U mFaceColor;
+ LLColor4U mStarValid;
+ LLColor4U mStarInvalid;
+ LLColor4U mTestPath;
+ LLColor4U mWaterColor;
+ };
+
+public:
+ //Ctor
+ LLPathingLib() {}
+ virtual ~LLPathingLib() {}
+
+ /// @returns false if this is the stub
+ static bool isFunctional();
+
+ // Obtain a pointer to the actual implementation
+ static LLPathingLib* getInstance();
+ static LLPathingLib::LLPLResult initSystem();
+ static LLPathingLib::LLPLResult quitSystem();
+
+ //Extract and store navmesh data from the llsd datablock sent down by the server
+ virtual LLPLResult extractNavMeshSrcFromLLSD( const LLSD::Binary& dataBlock, int dir ) = 0;
+ //Stitch any stored navmeshes together
+ virtual void processNavMeshData( ) = 0;
+
+ //Method used to generate and visualize a path on the viewers navmesh
+ virtual LLPLResult generatePath( const PathingPacket& pathingPacket ) = 0;
+
+ //Set the material type for the heatmap type
+ virtual void setNavMeshMaterialType( LLPLCharacterType materialType ) = 0;
+ //Set the various navmesh colors
+ virtual void setNavMeshColors( const NavMeshColors& color ) = 0;
+
+ //The entry method to rendering the client side navmesh
+ virtual void renderNavMesh() = 0;
+ //The entry method to rendering the client side navmesh edges
+ virtual void renderNavMeshEdges() = 0;
+ //The entry method to render the client navmesh shapes VBO
+ virtual void renderNavMeshShapesVBO( U32 shapeRenderFlags ) = 0;
+ //The entry method to render the clients designated path
+ virtual void renderPath() = 0;
+ //The entry method to render the capsule bookends for the clients designated path
+ virtual void renderPathBookend( LLRender& gl, LLPathingLib::LLPLPathBookEnd type ) = 0;
+ //Renders all of the generated simple shapes (using their default transforms)
+ virtual void renderSimpleShapes( LLRender& gl, F32 regionsWaterHeight ) = 0;
+
+ //Method called from second life to create a capsule from properties of a character
+ virtual void createPhysicsCapsuleRep( F32 length, F32 radius, BOOL horizontal, const LLUUID& id ) = 0;
+ //Removes any cached physics capsule using a list of cached uuids
+ virtual void cleanupPhysicsCapsuleRepResiduals() = 0;
+ //Renders a selected uuids physics rep
+ virtual void renderSimpleShapeCapsuleID( LLRender& gl, const LLUUID& id, const LLVector3& pos, const LLQuaternion& rot ) = 0;
+
+ //Method to delete any vbo's that are currently being managed by the pathing library
+ virtual void cleanupVBOManager( ) = 0;
+ //Method to cleanup any allocations within the implementation
+ virtual void cleanupResidual( ) = 0;
+private:
+ static bool s_isInitialized;
+};
+
+#endif //LL_PATHING_LIBRARY
diff --git a/indra/llphysicsextensionsos/llphysicsextensions.cpp b/indra/llphysicsextensionsos/llphysicsextensions.cpp
new file mode 100644
index 0000000000..3bb8ffbf1a
--- /dev/null
+++ b/indra/llphysicsextensionsos/llphysicsextensions.cpp
@@ -0,0 +1,78 @@
+/**
+* @file llphysicsextensions.cpp
+* @author nyx@lindenlab.com
+* @brief LLPhysicsExtensions core initialization methods
+*
+* $LicenseInfo:firstyear=2012&license=lgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+
+#include "llphysicsextensions.h"
+#include "LLPhysicsExtensionsStubImpl.h"
+
+
+//disable the undefined symbol optimization
+//#pragma warning (disable : 4221)
+
+//=============================================================================
+
+/*static */bool LLPhysicsExtensions::s_isInitialized = false;
+
+
+/*static*/bool LLPhysicsExtensions::isFunctional()
+{
+ return false;
+}
+
+//=============================================================================
+
+/*static*/LLPhysicsExtensions* LLPhysicsExtensions::getInstance()
+{
+ if ( !s_isInitialized )
+ {
+ return NULL;
+ }
+ else
+ {
+ return LLPhysicsExtensionsImpl::getInstance();
+ }
+}
+
+//=============================================================================
+
+/*static */bool LLPhysicsExtensions::initSystem()
+{
+ bool result = LLPhysicsExtensionsImpl::initSystem();
+ if ( result )
+ {
+ s_isInitialized = true;
+ }
+ return result;
+}
+//=============================================================================
+/*static */bool LLPhysicsExtensions::quitSystem()
+{
+ return LLPhysicsExtensionsImpl::quitSystem();
+}
+//=============================================================================
+
diff --git a/indra/llphysicsextensionsos/llphysicsextensions.h b/indra/llphysicsextensionsos/llphysicsextensions.h
new file mode 100644
index 0000000000..fa23ebd725
--- /dev/null
+++ b/indra/llphysicsextensionsos/llphysicsextensions.h
@@ -0,0 +1,59 @@
+/**
+* @file llphysicsextensions.h
+* @author nyx@lindenlab.com
+* @brief LLPhysicsExtensions core shared initialization
+* routines
+*
+* $LicenseInfo:firstyear=2012&license=lgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, 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_PHYSICS_EXTENSIONS
+#define LL_PHYSICS_EXTENSIONS
+
+#include "llpreprocessor.h"
+#include "llsd.h"
+#include "v3dmath.h"
+
+#define LLPHYSICSEXTENSIONS_VERSION "1.0"
+
+typedef int bool32;
+
+class LLPhysicsExtensions
+{
+
+public:
+ // Obtain a pointer to the actual implementation
+ static LLPhysicsExtensions* getInstance();
+
+ /// @returns false if this is the stub
+ static bool isFunctional();
+
+ static bool initSystem();
+ static bool quitSystem();
+
+private:
+ static bool s_isInitialized;
+};
+
+#endif //LL_PATHING_LIBRARY
+
+
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 63f1de8d6a..3deee2fb3e 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -985,14 +985,18 @@ void LLPluginProcessParent::poll(F64 timeout)
}
}
- // Remove instances in the done state from the sInstances map.
- mapInstances_t::iterator itClean = sInstances.begin();
- while (itClean != sInstances.end())
+ if (sInstancesMutex)
{
- if ((*itClean).second->isDone())
- itClean = sInstances.erase(itClean);
- else
- ++itClean;
+ // Remove instances in the done state from the sInstances map.
+ LLCoros::LockType lock(*sInstancesMutex);
+ mapInstances_t::iterator itClean = sInstances.begin();
+ while (itClean != sInstances.end())
+ {
+ if ((*itClean).second->isDone())
+ itClean = sInstances.erase(itClean);
+ else
+ ++itClean;
+ }
}
}
diff --git a/indra/llplugin/slplugin/slplugin-objc.mm b/indra/llplugin/slplugin/slplugin-objc.mm
index 68ff196eaf..adde594b59 100644
--- a/indra/llplugin/slplugin/slplugin-objc.mm
+++ b/indra/llplugin/slplugin/slplugin-objc.mm
@@ -7,21 +7,21 @@
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
@@ -38,51 +38,51 @@
void LLCocoaPlugin::setupCocoa()
{
- static bool inited = false;
-
- if(!inited)
- {
- createAutoReleasePool();
-
- // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
- // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
- // when init'ing the Cocoa App window.
- [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
-
- // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
- // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
-
- // Needed for Carbon based applications which call into Cocoa
- NSApplicationLoad();
+ static bool inited = false;
+
+ if(!inited)
+ {
+ createAutoReleasePool();
+
+ // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
+ // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
+ // when init'ing the Cocoa App window.
+ [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
+
+ // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
+ // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
+
+ // Needed for Carbon based applications which call into Cocoa
+ NSApplicationLoad();
+
+ // Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
+ [[[NSWindow alloc] init] release];
- // Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
- [[[NSWindow alloc] init] release];
-
mPluginWindow = [NSApp mainWindow];
-
- deleteAutoReleasePool();
-
- inited = true;
- }
+
+ deleteAutoReleasePool();
+
+ inited = true;
+ }
}
static NSAutoreleasePool *sPool = NULL;
void LLCocoaPlugin::createAutoReleasePool()
{
- if(!sPool)
- {
- sPool = [[NSAutoreleasePool alloc] init];
- }
+ if(!sPool)
+ {
+ sPool = [[NSAutoreleasePool alloc] init];
+ }
}
void LLCocoaPlugin::deleteAutoReleasePool()
{
- if(sPool)
- {
- [sPool release];
- sPool = NULL;
- }
+ if(sPool)
+ {
+ [sPool release];
+ sPool = NULL;
+ }
}
LLCocoaPlugin::LLCocoaPlugin():mHackState(0)
@@ -110,12 +110,12 @@ void LLCocoaPlugin::setupGroup()
// {
// // Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube)
// SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer"));
- // SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel);
+ // SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel);
// }
-
+
}
-void LLCocoaPlugin::updateWindows()
+void LLCocoaPlugin::updateWindows()
{
// NSArray* window_list = [NSApp orderedWindows];
// NSWindow* current_window = [window_list objectAtIndex:0];
@@ -123,38 +123,38 @@ void LLCocoaPlugin::updateWindows()
// bool this_is_front_process = false;
// bool parent_is_front_process = false;
//
-//
+//
// // Check for a change in this process's frontmost window.
// if ( current_window != mFrontWindow )
// {
// // and figure out whether this process or its parent are currently frontmost
// if ( current_window == parent_window ) parent_is_front_process = true;
// if ( current_window == mPluginWindow ) this_is_front_process = true;
-//
+//
// if (current_window != NULL && mFrontWindow == NULL)
// {
// // Opening the first window
-//
+//
// if(mHackState == 0)
// {
// // Next time through the event loop, lower the window group layer
// mHackState = 1;
// }
-//
+//
// if(parent_is_front_process)
// {
// // Bring this process's windows to the front.
// [mPluginWindow makeKeyAndOrderFront:NSApp];
// [mPluginWindow setOrderedIndex:0];
// }
-//
+//
// [NSApp activateIgnoringOtherApps:YES];
// }
-//
+//
// else if (( current_window == NULL) && (mFrontWindow != NULL))
// {
// // Closing the last window
-//
+//
// if(this_is_front_process)
// {
// // Try to bring this process's parent to the front
@@ -171,7 +171,7 @@ void LLCocoaPlugin::updateWindows()
//// }
// mHackState = 2;
// }
-//
+//
// mFrontWindow = [window_list objectAtIndex:0];
// }
}
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 82b3b37824..e8a0601852 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -65,11 +65,20 @@ target_link_libraries(llprimitive
llxml
llcharacter
llrender
- llphysicsextensions_impl
ll::colladadom
ll::glm
)
+if (HAVOK OR HAVOK_TPV)
+ target_link_libraries(llprimitive
+ llphysicsextensions_impl
+ )
+else()
+ target_link_libraries(llprimitive
+ llphysicsextensionsos
+ )
+endif ()
+
include(LibraryInstall)
#add unit tests
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index cc4921416f..930222e3db 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -923,3 +923,34 @@ void LLGLTFMaterial::updateTextureTracking()
// setTEGLTFMaterialOverride is responsible for tracking
// for material overrides editor will set it
}
+
+void LLGLTFMaterial::convertTextureTransformToPBR(
+ F32 tex_scale_s,
+ F32 tex_scale_t,
+ F32 tex_offset_s,
+ F32 tex_offset_t,
+ F32 tex_rotation,
+ LLVector2& pbr_scale,
+ LLVector2& pbr_offset,
+ F32& pbr_rotation)
+{
+ pbr_scale.set(tex_scale_s, tex_scale_t);
+ pbr_rotation = -(tex_rotation) / 2.f;
+ const F32 adjusted_offset_s = tex_offset_s;
+ const F32 adjusted_offset_t = -tex_offset_t;
+ F32 center_adjust_s = 0.5f * (1.0f - tex_scale_s);
+ F32 center_adjust_t = 0.5f * (1.0f - tex_scale_t);
+
+ if (pbr_rotation != 0.0f)
+ {
+ const F32 c = cosf(pbr_rotation);
+ const F32 s = sinf(pbr_rotation);
+ const F32 tmp_s = center_adjust_s * c - center_adjust_t * s;
+ const F32 tmp_t = center_adjust_s * s + center_adjust_t * c;
+ center_adjust_s = tmp_s;
+ center_adjust_t = tmp_t;
+ }
+
+ pbr_offset.set(adjusted_offset_s + center_adjust_s,
+ adjusted_offset_t + center_adjust_t);
+}
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index b89853c9fd..6bb021254b 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -215,6 +215,14 @@ public:
bool hasLocalTextures() { return !mTrackingIdToLocalTexture.empty(); }
virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id);
virtual void updateTextureTracking();
+
+ // Convert legacy TE transform values to PBR transform values.
+ static void convertTextureTransformToPBR(F32 tex_scale_s, F32 tex_scale_t,
+ F32 tex_offset_s, F32 tex_offset_t,
+ F32 tex_rotation,
+ LLVector2& pbr_scale,
+ LLVector2& pbr_offset,
+ F32& pbr_rotation);
protected:
static LLVector2 vec2FromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const LLVector2& default_value);
static F32 floatFromJson(const std::map<std::string, tinygltf::Value>& object, const char* key, const F32 default_value);
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 98faa88968..db752411fc 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1296,10 +1296,10 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
}
void LLModel::setConvexHullDecomposition(
- const LLModel::convex_hull_decomposition& decomp)
+ const LLModel::convex_hull_decomposition& decomp, const std::vector<LLModel::PhysicsMesh>& decomp_mesh)
{
mPhysics.mHull = decomp;
- mPhysics.mMesh.clear();
+ mPhysics.mMesh = decomp_mesh;
updateHullCenters();
}
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index a4ba6acd7e..854c77e63a 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -307,7 +307,8 @@ public:
S32 mDecompID;
void setConvexHullDecomposition(
- const convex_hull_decomposition& decomp);
+ const convex_hull_decomposition& decomp,
+ const std::vector<LLModel::PhysicsMesh>& decomp_mesh);
void updateHullCenters();
LLVector3 mCenterOfHullCenters;
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 53691bafe2..c52f68d298 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -86,7 +86,10 @@ void LLCubeMap::initGL()
#endif
mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
mRawImages[i] = new LLImageRaw(RESOLUTION, RESOLUTION, 4);
- mImages[i]->createGLTexture(0, mRawImages[i], texname);
+ if (!mImages[i]->createGLTexture(0, mRawImages[i], texname))
+ {
+ LL_WARNS() << "Failed to create GL texture for environment cubemap face " << i << LL_ENDL;
+ }
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -203,7 +206,10 @@ void LLCubeMap::initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& ra
mImages[i] = new LLImageGL(resolution, resolution, components, true);
mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
mRawImages[i] = rawimages[i];
- mImages[i]->createGLTexture(0, mRawImages[i], texname);
+ if (!mImages[i]->createGLTexture(0, mRawImages[i], texname))
+ {
+ LL_WARNS() << "Failed to create GL texture for environment cubemap face " << i << LL_ENDL;
+ }
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 5a0281eeb5..39bd9cbfed 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -57,6 +57,7 @@ S32 LLGLSLShader::sIndexedTextureChannels = 0;
U32 LLGLSLShader::sMaxGLTFMaterials = 0;
U32 LLGLSLShader::sMaxGLTFNodes = 0;
bool LLGLSLShader::sProfileEnabled = false;
+bool LLGLSLShader::sCanProfile = true;
std::set<LLGLSLShader*> LLGLSLShader::sInstances;
LLGLSLShader::defines_map_t LLGLSLShader::sGlobalDefines;
U64 LLGLSLShader::sTotalTimeElapsed = 0;
@@ -273,7 +274,7 @@ void LLGLSLShader::placeProfileQuery(bool for_runtime)
bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read)
{
- if (sProfileEnabled || for_runtime)
+ if ((sProfileEnabled || for_runtime) && sCanProfile)
{
if (!mProfilePending)
{
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 4702a27cc5..272a99aaa5 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -160,6 +160,7 @@ public:
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
+ static bool sCanProfile;
LLGLSLShader();
~LLGLSLShader();
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 9ff483b92b..bc80bd9556 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1152,6 +1152,8 @@ void sub_image_lines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 w
// full width texture, do 32 lines at a time
for (U32 y_pos = y_offset; y_pos < y_offset_end; y_pos += batch_size)
{
+ // If this keeps crashing, pass down data_size, looks like it is using
+ // imageraw->getData(); for data, but goes way over allocated size limit
glTexSubImage2D(target, miplevel, x_offset, y_pos, width, batch_size, pixformat, pixtype, src);
src += line_width * batch_size;
}
@@ -1161,6 +1163,8 @@ void sub_image_lines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 w
// partial width or strange height
for (U32 y_pos = y_offset; y_pos < y_offset_end; y_pos += 1)
{
+ // If this keeps crashing, pass down data_size, looks like it is using
+ // imageraw->getData(); for data, but goes way over allocated size limit
glTexSubImage2D(target, miplevel, x_offset, y_pos, width, 1, pixformat, pixtype, src);
src += line_width;
}
@@ -1635,6 +1639,7 @@ bool LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
llassert(mCurrentDiscardLevel >= 0);
discard_level = mCurrentDiscardLevel;
}
+ discard_level = llmin(discard_level, MAX_DISCARD_LEVEL);
// Actual image width/height = raw image width/height * 2^discard_level
S32 raw_w = imageraw->getWidth() ;
@@ -1741,6 +1746,7 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_
discard_level = mCurrentDiscardLevel;
}
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
+ discard_level = llmin(discard_level, MAX_DISCARD_LEVEL);
if (main_thread // <--- always force creation of new_texname when not on main thread ...
&& !defer_copy // <--- ... or defer copy is set
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 6dd3634309..ea8530f282 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1050,6 +1050,7 @@ void LLShaderMgr::clearShaderCache()
LL_INFOS("ShaderMgr") << "Removing shader cache at " << shader_cache << LL_ENDL;
const std::string mask = "*";
gDirUtilp->deleteFilesInDir(shader_cache, mask);
+ LLFile::rmdir(shader_cache);
mShaderBinaryCache.clear();
}
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 495ba2f40f..2cd394476e 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -494,6 +494,7 @@ void LLAccordionCtrl::arrangeMultiple()
void LLAccordionCtrl::arrange()
{
+ LL_PROFILE_ZONE_SCOPED;
updateNoTabsHelpTextVisibility();
if (mAccordionTabs.empty())
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index ac66525030..828bfb289b 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -248,10 +248,22 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::reshape(S32 width, S32 height, bool called_from_parent /* = true */)
{
S32 header_height = mHeaderTextbox->getTextPixelHeight();
+ LLRect old_header_rect = mHeaderTextbox->getRect();
LLRect textboxRect(HEADER_TEXT_LEFT_OFFSET, (height + header_height) / 2, width, (height - header_height) / 2);
- mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight());
- mHeaderTextbox->setRect(textboxRect);
+ if (old_header_rect.getHeight() != textboxRect.getHeight()
+ || old_header_rect.mLeft != textboxRect.mLeft
+ || old_header_rect.mTop != textboxRect.mTop
+ || old_header_rect.getWidth() > textboxRect.getWidth() // reducing header's width
+ || (old_header_rect.getWidth() < textboxRect.getWidth() && old_header_rect.getWidth() < mHeaderTextbox->getTextPixelWidth()))
+ {
+ // Expensive text reflow
+ // Update if position or height changes
+ // Update if width reduces
+ // But do not update if text already fits and width increases (arguably LLTextBox::reshape should be smarter, not Accordion)
+ mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight());
+ mHeaderTextbox->setRect(textboxRect);
+ }
if (mHeaderTextbox->getTextPixelWidth() > mHeaderTextbox->getRect().getWidth())
{
@@ -416,8 +428,11 @@ void LLAccordionCtrlTab::reshape(S32 width, S32 height, bool called_from_parent
LLRect headerRect;
headerRect.setLeftTopAndSize(0, height, width, HEADER_HEIGHT);
- mHeader->setRect(headerRect);
- mHeader->reshape(headerRect.getWidth(), headerRect.getHeight());
+ if (mHeader->getRect() != headerRect)
+ {
+ mHeader->setRect(headerRect);
+ mHeader->reshape(headerRect.getWidth(), headerRect.getHeight());
+ }
if (!mDisplayChildren)
return;
@@ -464,7 +479,34 @@ void LLAccordionCtrlTab::onUpdateScrollToChild(const LLUICtrl *cntrl)
// Translate to parent coordinatess to check if we are in visible rectangle
rect.translate(getRect().mLeft, getRect().mBottom);
- if (!getRect().contains(rect))
+ bool needs_to_scroll = false;
+ const LLRect &acc_rect = getRect();
+ if (!acc_rect.contains(rect))
+ {
+ if (acc_rect.mTop < rect.mBottom || acc_rect.mBottom > rect.mTop)
+ {
+ // Content fully not in view
+ needs_to_scroll = true;
+ }
+ else if (acc_rect.getHeight() >= rect.getHeight())
+ {
+ // Content can be displayed fully, but only partially in view
+ needs_to_scroll = true;
+ }
+ else if (acc_rect.mTop <= rect.mTop || acc_rect.mBottom >= rect.mBottom)
+ {
+ // Intersects, but too big to be displayed fully
+ S32 covered_height = acc_rect.mTop > rect.mTop ? rect.mTop - acc_rect.mBottom : acc_rect.mTop - rect.mBottom;
+ constexpr F32 covered_ratio = 0.7f;
+ if (covered_height < covered_ratio * acc_rect.getHeight())
+ {
+ // Try to show bigger portion of the content
+ needs_to_scroll = true;
+ }
+ }
+ // else too big and in the middle of the view as is
+ }
+ if (needs_to_scroll)
{
// for accordition's scroll, height is in pixels
// Back to local coords and calculate position for scroller
@@ -932,7 +974,7 @@ void LLAccordionCtrlTab::adjustContainerPanel(const LLRect& child_rect)
show_hide_scrollbar(child_rect);
updateLayout(child_rect);
}
- else
+ else if (mContainerPanel->getRect() != child_rect)
{
mContainerPanel->reshape(child_rect.getWidth(), child_rect.getHeight());
mContainerPanel->setRect(child_rect);
diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp
index 925608e47e..16e6f0591a 100644
--- a/indra/llui/llemojidictionary.cpp
+++ b/indra/llui/llemojidictionary.cpp
@@ -390,14 +390,17 @@ void LLEmojiDictionary::loadEmojis()
continue;
}
+ std::string category;
std::list<std::string> categories = loadCategories(sd);
if (categories.empty())
{
- LL_WARNS() << "Skipping invalid emoji descriptor (no categories)" << LL_ENDL;
- continue;
+ // Should already have a localization for "other symbols"
+ category = "other symbols";
+ }
+ else
+ {
+ category = categories.front();
}
-
- std::string category = categories.front();
if (std::find(mSkipCategories.begin(), mSkipCategories.end(), category) != mSkipCategories.end())
{
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index b2c59ce775..7cdd19bebc 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -117,7 +117,17 @@ void LLEmojiHelper::showHelper(LLUICtrl* hostctrl_p, S32 local_x, S32 local_y, c
S32 top = floater_y - HELPER_FLOATER_OFFSET_Y + rect.getHeight();
rect.setLeftTopAndSize(left, top, rect.getWidth(), rect.getHeight());
pHelperFloater->setRect(rect);
+
+ // Hack: Trying to open floater, search for a match,
+ // and hide floater immediately if no match found,
+ // instead of checking prior to opening
+ //
+ // Supress sounds in case floater won't be shown.
+ // Todo: add some kind of shouldShow(short_code)
+ U8 sound_flags = pHelperFloater->getSoundFlags();
+ pHelperFloater->setSoundFlags(LLView::SILENT);
pHelperFloater->openFloater(LLSD().with("hint", short_code));
+ pHelperFloater->setSoundFlags(sound_flags);
}
void LLEmojiHelper::hideHelper(const LLUICtrl* ctrl_p, bool strict)
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index fd07b2ec5d..52a5e3dbd6 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2274,7 +2274,7 @@ void LLFloater::drawConeToOwner(F32 &context_cone_opacity,
LLRect local_rect = getLocalRect();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLEnable(GL_CULL_FACE);
+ LLGLEnable cull_face(GL_CULL_FACE);
gGL.begin(LLRender::TRIANGLE_STRIP);
{
gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity);
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index b664065532..db4ab8487e 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1510,6 +1510,7 @@ bool LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
&& ( count > 0 && (hasVisibleChildren()) ))) && // show menu only if selected items are visible
!hide_folder_menu)
{
+ LL_INFOS("Inventory") << "Opening inventory menu from path: " << getPathname() << LL_ENDL;
if (mCallbackRegistrar)
{
mCallbackRegistrar->pushScope();
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 9ca77dbe46..878f1cb856 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1884,10 +1884,18 @@ void LLFolderViewFolder::updateHasFavorites(bool new_childs_value)
void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
{
LLFolderViewFolder* self = reinterpret_cast<LLFolderViewFolder*>(data);
+ if (self->mFavoritesDirtyFlags == FAVORITE_CLEANUP)
+ {
+ // parent or child already processed the update, clean the callback
+ self->mFavoritesDirtyFlags = 0;
+ gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, data);
+ return;
+ }
+
if (self->mFavoritesDirtyFlags == 0)
{
- // already processed either on previous run or by a different callback
- gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
+ llassert(false); // should not happen, everything that sets to 0 should clean callback
+ gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, data);
return;
}
@@ -1915,7 +1923,7 @@ void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
// Parent will remove onIdleUpdateFavorites later, don't remove now,
// We are inside gIdleCallbacks. Removing 'self' callback is safe,
// but removing 'parent' can invalidate following iterator
- parent->mFavoritesDirtyFlags = 0;
+ parent->mFavoritesDirtyFlags = FAVORITE_CLEANUP;
}
parent = parent->getParentFolder();
}
@@ -1981,7 +1989,7 @@ void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
// Parent will remove onIdleUpdateFavorites later, don't remove now,
// We are inside gIdleCallbacks. Removing 'self' callback is safe,
// but removing 'parent' can invalidate following iterator
- parent->mFavoritesDirtyFlags = 0;
+ parent->mFavoritesDirtyFlags = FAVORITE_CLEANUP;
}
parent = parent->getParentFolder();
}
@@ -1992,7 +2000,7 @@ void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
// Parent will remove onIdleUpdateFavorites later, don't remove now.
// We are inside gIdleCallbacks. Removing 'self' callback is safe,
// but removing 'parent' can invalidate following iterator
- parent->mFavoritesDirtyFlags = 0;
+ parent->mFavoritesDirtyFlags = FAVORITE_CLEANUP;
}
parent = parent->getParentFolder();
}
@@ -2106,10 +2114,14 @@ void LLFolderViewFolder::setOpen(bool openitem)
{
// navigateToFolder can destroy this view
// delay it in case setOpen was called from click or key processing
- doOnIdleOneTime([this]()
- {
- getViewModelItem()->navigateToFolder();
- });
+ LLPointer<LLFolderViewModelItem> view_model_item = mViewModelItem;
+ doOnIdleOneTime([view_model_item]()
+ {
+ if (view_model_item.notNull())
+ {
+ view_model_item.get()->navigateToFolder();
+ }
+ });
}
else
{
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index c9b003b892..23d794bf26 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -421,6 +421,7 @@ private:
constexpr static S32 FAVORITE_ADDED = 1;
constexpr static S32 FAVORITE_REMOVED = 2;
+ constexpr static S32 FAVORITE_CLEANUP = 4;
S32 mFavoritesDirtyFlags { 0 };
public:
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 3fe0df1848..44151a4355 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -185,6 +185,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mURLClickSignal(NULL),
mIsFriendSignal(NULL),
mIsObjectBlockedSignal(NULL),
+ mIsObjectReachableSignal(NULL),
mMaxTextByteLength( p.max_text_length ),
mFont(p.font),
mFontShadow(p.font_shadow),
@@ -290,6 +291,7 @@ LLTextBase::~LLTextBase()
delete mURLClickSignal;
delete mIsFriendSignal;
delete mIsObjectBlockedSignal;
+ delete mIsObjectReachableSignal;
}
void LLTextBase::initFromParams(const LLTextBase::Params& p)
@@ -1036,8 +1038,37 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
{
LLStyleSP emoji_style;
LLEmojiDictionary* ed = LLEmojiDictionary::instanceExists() ? LLEmojiDictionary::getInstance() : NULL;
+ LLTextSegment* segmentp = nullptr;
+ segment_vec_t::iterator seg_iter;
+ if (segments && segments->size() > 0)
+ {
+ seg_iter = segments->begin();
+ segmentp = *seg_iter;
+ }
for (S32 text_kitty = 0, text_len = static_cast<S32>(wstr.size()); text_kitty < text_len; text_kitty++)
{
+ if (segmentp)
+ {
+ if (segmentp->getEnd() <= pos + text_kitty)
+ {
+ seg_iter++;
+ if (seg_iter != segments->end())
+ {
+ segmentp = *seg_iter;
+ }
+ else
+ {
+ segmentp = nullptr;
+ }
+ }
+ if (segmentp && !segmentp->getPermitsEmoji())
+ {
+ // Some segments, like LLInlineViewSegment do not permit splitting
+ // and should not be interrupted by emoji segments
+ continue;
+ }
+ }
+
llwchar code = wstr[text_kitty];
bool isEmoji = ed ? ed->isEmoji(code) : LLStringOps::isEmoji(code);
if (isEmoji)
@@ -1446,6 +1477,8 @@ void LLTextBase::reshape(S32 width, S32 height, bool called_from_parent)
// up-to-date mVisibleTextRect
updateRects();
+ // Todo: This might be wrong. updateRects already sets needsReflow conditionaly.
+ // Reflow is expensive and doing it at any twith can be too much.
needsReflow();
}
}
@@ -2281,6 +2314,15 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
unblockButton->setVisible(is_blocked);
}
}
+
+ if (mIsObjectReachableSignal)
+ {
+ bool is_reachable = *(*mIsObjectReachableSignal)(LLUUID(LLUrlAction::getObjectId(url)));
+ if (LLView* zoom_btn = menu->getChild<LLView>("zoom_in"))
+ {
+ zoom_btn->setEnabled(is_reachable);
+ }
+ }
menu->show(x, y);
LLMenuGL::showPopup(this, menu, x, y);
}
@@ -3387,6 +3429,15 @@ boost::signals2::connection LLTextBase::setIsObjectBlockedCallback(const is_bloc
return mIsObjectBlockedSignal->connect(cb);
}
+boost::signals2::connection LLTextBase::setIsObjectReachableCallback(const is_obj_reachable_signal_t::slot_type& cb)
+{
+ if (!mIsObjectReachableSignal)
+ {
+ mIsObjectReachableSignal = new is_obj_reachable_signal_t();
+ }
+ return mIsObjectReachableSignal->connect(cb);
+}
+
//
// LLTextSegment
//
@@ -3426,6 +3477,7 @@ S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offs
void LLTextSegment::updateLayout(const LLTextBase& editor) {}
F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { return draw_rect.mLeft; }
bool LLTextSegment::canEdit() const { return false; }
+bool LLTextSegment::getPermitsEmoji() const { return true; }
void LLTextSegment::unlinkFromDocument(LLTextBase*) {}
void LLTextSegment::linkToDocument(LLTextBase*) {}
const LLUIColor& LLTextSegment::getColor() const { static const LLUIColor white = LLUIColorTable::instance().getColor("White", LLColor4::white); return white; }
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 8ca653acb9..50767a35b3 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -87,6 +87,7 @@ public:
virtual void updateLayout(const class LLTextBase& editor);
virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
virtual bool canEdit() const;
+ virtual bool getPermitsEmoji() const;
virtual void unlinkFromDocument(class LLTextBase* editor);
virtual void linkToDocument(class LLTextBase* editor);
@@ -255,6 +256,7 @@ public:
/*virtual*/ void updateLayout(const class LLTextBase& editor);
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
/*virtual*/ bool canEdit() const { return false; }
+ /*virtual*/ bool getPermitsEmoji() const { return false; }
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
/*virtual*/ void linkToDocument(class LLTextBase* editor);
@@ -325,6 +327,7 @@ public:
typedef boost::signals2::signal<bool (const LLUUID& user_id)> is_friend_signal_t;
typedef boost::signals2::signal<bool (const LLUUID& blocked_id, const std::string from)> is_blocked_signal_t;
+ typedef boost::signals2::signal<bool (const LLUUID& obj_id)> is_obj_reachable_signal_t;
struct LineSpacingParams : public LLInitParam::ChoiceBlock<LineSpacingParams>
{
@@ -535,6 +538,7 @@ public:
boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb);
boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb);
boost::signals2::connection setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb);
+ boost::signals2::connection setIsObjectReachableCallback(const is_obj_reachable_signal_t::slot_type& cb);
void setWordWrap(bool wrap);
LLScrollContainer* getScrollContainer() const { return mScroller; }
@@ -783,6 +787,7 @@ protected:
// Used to check if user with given ID is avatar's friend
is_friend_signal_t* mIsFriendSignal;
is_blocked_signal_t* mIsObjectBlockedSignal;
+ is_obj_reachable_signal_t* mIsObjectReachableSignal;
LLUIString mLabel; // text label that is visible when no user text provided
};
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 5955a28fa3..56ab6e9bae 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -1054,7 +1054,7 @@ bool LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
// if drop is set, it's time to call the callback to get the operation done
if (handled && drop)
{
- handled = mHandleDropCallback(cargo_data, x, y, this);
+ handled = mHandleDropCallback(cargo_data, cargo_type, x, y, this);
}
// We accept only single tool drop on toolbars
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 5556406fbd..a3f044c256 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -41,7 +41,7 @@ class LLIconCtrl;
typedef boost::function<void (S32 x, S32 y, LLToolBarButton* button)> tool_startdrag_callback_t;
typedef boost::function<bool (S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)> tool_handledrag_callback_t;
-typedef boost::function<bool (void* data, S32 x, S32 y, LLToolBar* toolbar)> tool_handledrop_callback_t;
+typedef boost::function<bool (void* data, EDragAndDropType cargo_type, S32 x, S32 y, LLToolBar* toolbar)> tool_handledrop_callback_t;
class LLToolBarButton : public LLButton
{
diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp
index 6d907d7e45..9eefba1390 100644
--- a/indra/llui/llviewereventrecorder.cpp
+++ b/indra/llui/llviewereventrecorder.cpp
@@ -34,8 +34,6 @@ LLViewerEventRecorder::LLViewerEventRecorder() {
logEvents = false;
// Remove any previous event log file
std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old");
- LLFile::remove(old_log_ui_events_to_llsd_file, ENOENT);
-
mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd");
LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file, ENOENT);
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index 7e2b5d2741..7c2481a94c 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -390,8 +390,6 @@ void LLWebRTCImpl::terminate()
mSignalingThread->BlockingCall([this]() { mPeerConnectionFactory = nullptr; });
- mPeerConnections.clear();
-
mWorkerThread->BlockingCall(
[this]()
{
@@ -402,6 +400,14 @@ void LLWebRTCImpl::terminate()
mDeviceModule = nullptr;
mTaskQueueFactory = nullptr;
});
+
+ // In case peer connections still somehow have jobs in workers,
+ // only clear connections up after clearing workers.
+ mNetworkThread = nullptr;
+ mWorkerThread = nullptr;
+ mSignalingThread = nullptr;
+
+ mPeerConnections.clear();
webrtc::LogMessage::RemoveLogToStream(mLogSink);
}
@@ -582,14 +588,20 @@ void LLWebRTCImpl::workerDeployDevices()
void LLWebRTCImpl::setCaptureDevice(const std::string &id)
{
- mRecordingDevice = id;
- deployDevices();
+ if (mRecordingDevice != id)
+ {
+ mRecordingDevice = id;
+ deployDevices();
+ }
}
void LLWebRTCImpl::setRenderDevice(const std::string &id)
{
- mPlayoutDevice = id;
- deployDevices();
+ if (mPlayoutDevice != id)
+ {
+ mPlayoutDevice = id;
+ deployDevices();
+ }
}
// updateDevices needs to happen on the worker thread.
@@ -651,6 +663,13 @@ void LLWebRTCImpl::OnDevicesUpdated()
void LLWebRTCImpl::setTuningMode(bool enable)
{
mTuningMode = enable;
+ if (!mTuningMode
+ && !mMute
+ && mPeerCustomProcessor
+ && mPeerCustomProcessor->getGain() != mGain)
+ {
+ mPeerCustomProcessor->setGain(mGain);
+ }
mWorkerThread->PostTask(
[this]
{
@@ -782,6 +801,7 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn
std::find(mPeerConnections.begin(), mPeerConnections.end(), peer_connection);
if (it != mPeerConnections.end())
{
+ // Todo: make sure conection had no jobs in workers
mPeerConnections.erase(it);
if (mPeerConnections.empty())
{
@@ -801,7 +821,8 @@ LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() :
mWebRTCImpl(nullptr),
mPeerConnection(nullptr),
mMute(MUTE_INITIAL),
- mAnswerReceived(false)
+ mAnswerReceived(false),
+ mPendingJobs(0)
{
}
@@ -809,6 +830,10 @@ LLWebRTCPeerConnectionImpl::~LLWebRTCPeerConnectionImpl()
{
mSignalingObserverList.clear();
mDataObserverList.clear();
+ if (mPendingJobs > 0)
+ {
+ RTC_LOG(LS_ERROR) << __FUNCTION__ << "Destroying a connection that has " << std::to_string(mPendingJobs) << " unfinished jobs that might cause workers to crash";
+ }
}
//
@@ -820,8 +845,10 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl)
mWebRTCImpl = webrtc_impl;
mPeerConnectionFactory = mWebRTCImpl->getPeerConnectionFactory();
}
+
void LLWebRTCPeerConnectionImpl::terminate()
{
+ mPendingJobs++;
mWebRTCImpl->PostSignalingTask(
[this]()
{
@@ -864,7 +891,9 @@ void LLWebRTCPeerConnectionImpl::terminate()
observer->OnPeerConnectionClosed();
}
}
+ mPendingJobs--;
});
+ mPeerConnectionFactory.release();
}
void LLWebRTCPeerConnectionImpl::setSignalingObserver(LLWebRTCSignalingObserver *observer) { mSignalingObserverList.emplace_back(observer); }
@@ -885,6 +914,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
RTC_DCHECK(!mPeerConnection);
mAnswerReceived = false;
+ mPendingJobs++;
mWebRTCImpl->PostSignalingTask(
[this,options]()
{
@@ -906,6 +936,13 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
config.set_max_port(60100);
webrtc::PeerConnectionDependencies pc_dependencies(this);
+ if (mPeerConnectionFactory == nullptr)
+ {
+ RTC_LOG(LS_ERROR) << __FUNCTION__ << "Error creating peer connection, factory doesn't exist";
+ // Too early?
+ mPendingJobs--;
+ return;
+ }
auto error_or_peer_connection = mPeerConnectionFactory->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
if (error_or_peer_connection.ok())
{
@@ -918,6 +955,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
{
observer->OnRenegotiationNeeded();
}
+ mPendingJobs--;
return;
}
@@ -980,6 +1018,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions offerOptions;
mPeerConnection->CreateOffer(this, offerOptions);
+ mPendingJobs--;
});
return true;
@@ -1022,6 +1061,7 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp)
{
RTC_LOG(LS_INFO) << __FUNCTION__ << " Remote SDP: " << sdp;
+ mPendingJobs++;
mWebRTCImpl->PostSignalingTask(
[this, sdp]()
{
@@ -1031,6 +1071,7 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp)
mPeerConnection->SetRemoteDescription(webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, sdp),
webrtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>(this));
}
+ mPendingJobs--;
});
}
@@ -1053,6 +1094,7 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
mMute = new_state;
+ mPendingJobs++;
mWebRTCImpl->PostSignalingTask(
[this, force_reset, enable]()
{
@@ -1076,6 +1118,7 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
track->set_enabled(enable);
}
}
+ mPendingJobs--;
}
});
}
@@ -1097,6 +1140,7 @@ void LLWebRTCPeerConnectionImpl::resetMute()
void LLWebRTCPeerConnectionImpl::setReceiveVolume(float volume)
{
+ mPendingJobs++;
mWebRTCImpl->PostSignalingTask(
[this, volume]()
{
@@ -1115,11 +1159,13 @@ void LLWebRTCPeerConnectionImpl::setReceiveVolume(float volume)
}
}
}
+ mPendingJobs--;
});
}
void LLWebRTCPeerConnectionImpl::setSendVolume(float volume)
{
+ mPendingJobs++;
mWebRTCImpl->PostSignalingTask(
[this, volume]()
{
@@ -1130,6 +1176,7 @@ void LLWebRTCPeerConnectionImpl::setSendVolume(float volume)
track->GetSource()->SetVolume(volume*5.0);
}
}
+ mPendingJobs--;
});
}
@@ -1206,11 +1253,13 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf
{
case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
{
+ mPendingJobs++;
mWebRTCImpl->PostWorkerTask([this]() {
for (auto &observer : mSignalingObserverList)
{
observer->OnAudioEstablished(this);
}
+ mPendingJobs--;
});
break;
}
@@ -1468,11 +1517,13 @@ void LLWebRTCPeerConnectionImpl::sendData(const std::string& data, bool binary)
{
webrtc::CopyOnWriteBuffer cowBuffer(data.data(), data.length());
webrtc::DataBuffer buffer(cowBuffer, binary);
+ mPendingJobs++;
mWebRTCImpl->PostNetworkTask([this, buffer]() {
if (mDataChannel)
{
mDataChannel->Send(buffer);
}
+ mPendingJobs--;
});
}
}
diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h
index fbc60d48e3..9d3af985ef 100644
--- a/indra/llwebrtc/llwebrtc_impl.h
+++ b/indra/llwebrtc/llwebrtc_impl.h
@@ -428,6 +428,9 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceO
~LLWebRTCImpl()
{
delete mLogSink;
+
+ // Explicit cleanup for the sake of debugging and crash stacks
+ mPeerCustomProcessor = nullptr;
}
void init();
@@ -679,6 +682,8 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
// data
std::vector<LLWebRTCDataObserver *> mDataObserverList;
webrtc::scoped_refptr<webrtc::DataChannelInterface> mDataChannel;
+
+ std::atomic<int> mPendingJobs;
};
}
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 268afe843d..bdb5d8def0 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -125,7 +125,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (unsigned long)getVramSize
{
CGLRendererInfoObj info = 0;
- GLint vram_megabytes = 0;
+ GLint vram_megabytes = 0;
int num_renderers = 0;
CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);
if(0 == the_err)
@@ -143,7 +143,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
vram_megabytes = 256;
}
- return (unsigned long)vram_megabytes; // return value is in megabytes.
+ return (unsigned long)vram_megabytes; // return value is in megabytes.
}
- (void)viewWillMoveToWindow:(nullable NSWindow *)newWindow
@@ -164,24 +164,24 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void)viewDidMoveToWindow
{
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(windowResized:) name:NSWindowDidResizeNotification
- object:[self window]];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(windowResized:) name:NSWindowDidResizeNotification
+ object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification
- object:[self window]];
+ selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification
+ object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification
- object:[self window]];
+ selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification
+ object:[self window]];
[[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification
- object:[self window]];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification
- object:[self window]];
+ selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification
+ object:[self window]];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification
+ object:[self window]];
NSRect wnd_rect = [[self window] frame];
@@ -215,28 +215,28 @@ attributedStringInfo getSegments(NSAttributedString *str)
-(void)windowDidChangeScreen:(NSNotification *)notification;
{
- callWindowDidChangeScreen();
+ callWindowDidChangeScreen();
}
- (void)dealloc
{
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [super dealloc];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [super dealloc];
}
- (id) init
{
- return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
+ return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
}
- (id) initWithSamples:(NSUInteger)samples
{
- return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE];
+ return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE];
}
- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync
{
- return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync];
+ return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync];
}
#if LL_DARWIN
@@ -248,21 +248,21 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
{
[self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeURL]];
- [self initWithFrame:frame];
+ [self initWithFrame:frame];
- // Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
- // Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat.
- // 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons).
+ // Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
+ // Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat.
+ // 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons).
- NSOpenGLPixelFormatAttribute SDRAttrs[] = {
+ NSOpenGLPixelFormatAttribute SDRAttrs[] = {
NSOpenGLPFANoRecovery,
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAClosestPolicy,
- NSOpenGLPFAAccelerated,
- NSOpenGLPFADepthSize, 24,
- NSOpenGLPFAColorSize, 32,
- NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core,
- 0
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAClosestPolicy,
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAColorSize, 32,
+ NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core,
+ 0
};
NSOpenGLPixelFormatAttribute HDRAttrs[] = {
@@ -298,21 +298,21 @@ attributedStringInfo getSegments(NSAttributedString *str)
pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:SDRAttrs] autorelease];
}
- if (pixelFormat == nil)
- {
- NSLog(@"Failed to create pixel format!", nil);
- return nil;
- }
+ if (pixelFormat == nil)
+ {
+ NSLog(@"Failed to create pixel format!", nil);
+ return nil;
+ }
- glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
+ glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
- if (glContext == nil)
- {
- NSLog(@"Failed to create OpenGL context!", nil);
- return nil;
- }
+ if (glContext == nil)
+ {
+ NSLog(@"Failed to create OpenGL context!", nil);
+ return nil;
+ }
- [self setPixelFormat:pixelFormat];
+ [self setPixelFormat:pixelFormat];
if(mHDRDisplay)
{
@@ -327,55 +327,55 @@ attributedStringInfo getSegments(NSAttributedString *str)
NSLog(@"Extended color space applied for HDR Display", nil);
}
- //for retina support
- [self setWantsBestResolutionOpenGLSurface:gHiDPISupport];
+ //for retina support
+ [self setWantsBestResolutionOpenGLSurface:gHiDPISupport];
- [self setOpenGLContext:glContext];
+ [self setOpenGLContext:glContext];
- [glContext setView:self];
+ [glContext setView:self];
- [glContext makeCurrentContext];
+ [glContext makeCurrentContext];
- if (vsync)
- {
- GLint value = 1;
+ if (vsync)
+ {
+ GLint value = 1;
[glContext setValues:&value forParameter:NSOpenGLContextParameterSwapInterval];
- } else {
- // supress this error after move to Xcode 7:
- // error: null passed to a callee that requires a non-null argument [-Werror,-Wnonnull]
- // Tried using ObjC 'nonnull' keyword as per SO article but didn't build
- GLint swapInterval=0;
+ } else {
+ // supress this error after move to Xcode 7:
+ // error: null passed to a callee that requires a non-null argument [-Werror,-Wnonnull]
+ // Tried using ObjC 'nonnull' keyword as per SO article but didn't build
+ GLint swapInterval=0;
[glContext setValues:&swapInterval forParameter:NSOpenGLContextParameterSwapInterval];
- }
+ }
GLint opacity = 1;
[glContext setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity];
- return self;
+ return self;
}
- (BOOL) rebuildContext
{
- return [self rebuildContextWithFormat:[self pixelFormat]];
+ return [self rebuildContextWithFormat:[self pixelFormat]];
}
- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format
{
- NSOpenGLContext *ctx = [self openGLContext];
+ NSOpenGLContext *ctx = [self openGLContext];
- [ctx clearDrawable];
- [ctx initWithFormat:format shareContext:nil];
+ [ctx clearDrawable];
+ [ctx initWithFormat:format shareContext:nil];
- if (ctx == nil)
- {
- NSLog(@"Failed to create OpenGL context!", nil);
- return false;
- }
+ if (ctx == nil)
+ {
+ NSLog(@"Failed to create OpenGL context!", nil);
+ return false;
+ }
- [self setOpenGLContext:ctx];
- [ctx setView:self];
- [ctx makeCurrentContext];
- return true;
+ [self setOpenGLContext:ctx];
+ [ctx setView:self];
+ [ctx makeCurrentContext];
+ return true;
}
#if LL_DARWIN
@@ -384,14 +384,14 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (CGLContextObj)getCGLContextObj
{
- NSOpenGLContext *ctx = [self openGLContext];
- return (CGLContextObj)[ctx CGLContextObj];
+ NSOpenGLContext *ctx = [self openGLContext];
+ return (CGLContextObj)[ctx CGLContextObj];
}
- (CGLPixelFormatObj*)getCGLPixelFormatObj
{
- NSOpenGLPixelFormat *fmt = [self pixelFormat];
- return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj];
+ NSOpenGLPixelFormat *fmt = [self pixelFormat];
+ return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj];
}
// Various events can be intercepted by our view, thus not reaching our window.
@@ -436,29 +436,29 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) rightMouseDown:(NSEvent *)theEvent
{
- callRightMouseDown(mMousePos, [theEvent modifierFlags]);
+ callRightMouseDown(mMousePos, [theEvent modifierFlags]);
}
- (void) rightMouseUp:(NSEvent *)theEvent
{
- callRightMouseUp(mMousePos, [theEvent modifierFlags]);
+ callRightMouseUp(mMousePos, [theEvent modifierFlags]);
}
- (void)mouseMoved:(NSEvent *)theEvent
{
NSPoint dev_delta = [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])];
- float mouseDeltas[] = {
- float(dev_delta.x),
- float(dev_delta.y)
- };
+ float mouseDeltas[] = {
+ float(dev_delta.x),
+ float(dev_delta.y)
+ };
- callDeltaUpdate(mouseDeltas, 0);
+ callDeltaUpdate(mouseDeltas, 0);
NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]];
- mMousePos[0] = mPoint.x;
- mMousePos[1] = mPoint.y;
- callMouseMoved(mMousePos, 0);
+ mMousePos[0] = mPoint.x;
+ mMousePos[1] = mPoint.y;
+ callMouseMoved(mMousePos, 0);
}
// NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged.
@@ -466,23 +466,23 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) mouseDragged:(NSEvent *)theEvent
{
- // Trust the deltas supplied by NSEvent.
- // The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
- // NSEvent isn't obsolete, and provides us with the correct deltas.
+ // Trust the deltas supplied by NSEvent.
+ // The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
+ // NSEvent isn't obsolete, and provides us with the correct deltas.
NSPoint dev_delta = [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])];
- float mouseDeltas[] = {
- float(dev_delta.x),
- float(dev_delta.y)
- };
+ float mouseDeltas[] = {
+ float(dev_delta.x),
+ float(dev_delta.y)
+ };
- callDeltaUpdate(mouseDeltas, 0);
+ callDeltaUpdate(mouseDeltas, 0);
- NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]];
- mMousePos[0] = mPoint.x;
- mMousePos[1] = mPoint.y;
- callMouseDragged(mMousePos, 0);
+ NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]];
+ mMousePos[0] = mPoint.x;
+ mMousePos[1] = mPoint.y;
+ callMouseDragged(mMousePos, 0);
}
- (void) otherMouseDown:(NSEvent *)theEvent
@@ -497,29 +497,29 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) rightMouseDragged:(NSEvent *)theEvent
{
- [self mouseDragged:theEvent];
+ [self mouseDragged:theEvent];
}
- (void) otherMouseDragged:(NSEvent *)theEvent
{
- [self mouseDragged:theEvent];
+ [self mouseDragged:theEvent];
}
- (void) scrollWheel:(NSEvent *)theEvent
{
- callScrollMoved(-[theEvent deltaX], -[theEvent deltaY]);
+ callScrollMoved(-[theEvent deltaX], -[theEvent deltaY]);
}
- (void) mouseExited:(NSEvent *)theEvent
{
- callMouseExit();
+ callMouseExit();
}
- (void) keyUp:(NSEvent *)theEvent
{
NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent);
eventData.mKeyEvent = NativeKeyEventData::KEYUP;
- callKeyUp(&eventData, [theEvent keyCode], [theEvent modifierFlags]);
+ callKeyUp(&eventData, [theEvent keyCode], [theEvent modifierFlags]);
}
- (void) keyDown:(NSEvent *)theEvent
@@ -533,7 +533,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
// Because flagsChange event handler misses event when other window is activated,
// 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];
+ mModifiers = [theEvent modifierFlags];
NSString *str_no_modifiers = [theEvent charactersIgnoringModifiers];
unichar ch = 0;
if (str_no_modifiers.length)
@@ -561,8 +561,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
{
NativeKeyEventData eventData = extractKeyDataFromModifierEvent(theEvent);
- mModifiers = [theEvent modifierFlags];
- callModifier([theEvent modifierFlags]);
+ mModifiers = [theEvent modifierFlags];
+ callModifier([theEvent modifierFlags]);
NSInteger mask = 0;
switch([theEvent keyCode])
@@ -603,69 +603,69 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (BOOL) acceptsFirstResponder
{
- return YES;
+ return YES;
}
- (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
{
- NSPasteboard *pboard;
+ NSPasteboard *pboard;
NSDragOperation sourceDragMask;
- sourceDragMask = [sender draggingSourceOperationMask];
+ sourceDragMask = [sender draggingSourceOperationMask];
- pboard = [sender draggingPasteboard];
+ pboard = [sender draggingPasteboard];
if ([[pboard types] containsObject:NSPasteboardTypeURL])
- {
- if (sourceDragMask & NSDragOperationLink) {
- NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0];
- mLastDraggedUrl = [[fileUrl absoluteString] UTF8String];
+ {
+ if (sourceDragMask & NSDragOperationLink) {
+ NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0];
+ mLastDraggedUrl = [[fileUrl absoluteString] UTF8String];
return NSDragOperationLink;
}
- }
- return NSDragOperationNone;
+ }
+ return NSDragOperationNone;
}
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
{
- callHandleDragUpdated(mLastDraggedUrl);
+ callHandleDragUpdated(mLastDraggedUrl);
- return NSDragOperationLink;
+ return NSDragOperationLink;
}
- (void) draggingExited:(id<NSDraggingInfo>)sender
{
- callHandleDragExited(mLastDraggedUrl);
+ callHandleDragExited(mLastDraggedUrl);
}
- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender
{
- return YES;
+ return YES;
}
- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
{
- callHandleDragDropped(mLastDraggedUrl);
- return true;
+ callHandleDragDropped(mLastDraggedUrl);
+ return true;
}
- (BOOL)hasMarkedText
{
- return mHasMarkedText;
+ return mHasMarkedText;
}
- (NSRange)markedRange
{
- int range[2];
- getPreeditMarkedRange(&range[0], &range[1]);
- return NSMakeRange(range[0], range[1]);
+ int range[2];
+ getPreeditMarkedRange(&range[0], &range[1]);
+ return NSMakeRange(range[0], range[1]);
}
- (NSRange)selectedRange
{
- int range[2];
- getPreeditSelectionRange(&range[0], &range[1]);
- return NSMakeRange(range[0], range[1]);
+ int range[2];
+ getPreeditSelectionRange(&range[0], &range[1]);
+ return NSMakeRange(range[0], range[1]);
}
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
@@ -751,21 +751,21 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void)unmarkText
{
- [[self inputContext] discardMarkedText];
- resetPreedit();
- mHasMarkedText = FALSE;
+ [[self inputContext] discardMarkedText];
+ resetPreedit();
+ mHasMarkedText = FALSE;
}
// We don't support attributed strings.
- (NSArray *)validAttributesForMarkedText
{
- return [NSArray array];
+ return [NSArray array];
}
// See above.
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
{
- return nil;
+ return nil;
}
- (void)insertText:(id)insertString
@@ -778,9 +778,9 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
{
- // SL-19801 Special workaround for system emoji picker
- if ([aString length] == 2)
- {
+ // SL-19801 Special workaround for system emoji picker
+ if ([aString length] == 2)
+ {
@try
{
uint32_t b0 = [aString characterAtIndex:0];
@@ -798,7 +798,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
NSLog(@"Encountered an unsupported attributed character. Exception: %@ String: %@", e.name, aString);
return;
}
- }
+ }
@try
{
@@ -831,36 +831,36 @@ attributedStringInfo getSegments(NSAttributedString *str)
if (!(mModifiers & NSEventModifierFlagCommand) &&
!(mModifiers & NSEventModifierFlagShift) &&
!(mModifiers & NSEventModifierFlagOption))
- {
- callUnicodeCallback(13, 0);
- } else {
- callUnicodeCallback(13, mModifiers);
- }
+ {
+ callUnicodeCallback(13, 0);
+ } else {
+ callUnicodeCallback(13, mModifiers);
+ }
}
- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
{
- return NSNotFound;
+ return NSNotFound;
}
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
{
- float pos[4] = {0, 0, 0, 0};
- getPreeditLocation(pos, mMarkedTextLength);
- return NSMakeRect(pos[0], pos[1], pos[2], pos[3]);
+ float pos[4] = {0, 0, 0, 0};
+ getPreeditLocation(pos, mMarkedTextLength);
+ return NSMakeRect(pos[0], pos[1], pos[2], pos[3]);
}
- (void)doCommandBySelector:(SEL)aSelector
{
- if (aSelector == @selector(insertNewline:))
- {
- [self insertNewline:self];
- }
+ if (aSelector == @selector(insertNewline:))
+ {
+ [self insertNewline:self];
+ }
}
- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex
{
- return NO;
+ return NO;
}
- (void) allowMarkedTextInput:(bool)allowed
@@ -895,7 +895,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) setGLView:(LLOpenGLView *)view
{
- glview = view;
+ glview = view;
}
- (void)keyDown:(NSEvent *)theEvent
@@ -946,24 +946,24 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (id) init
{
- return self;
+ return self;
}
- (BOOL) becomeFirstResponder
{
- callFocus();
- return true;
+ callFocus();
+ return true;
}
- (BOOL) resignFirstResponder
{
- callFocusLost();
- return true;
+ callFocusLost();
+ return true;
}
- (void) close
{
- callQuitHandler();
+ callQuitHandler();
}
@end
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 8f8ea7fdb6..d63927d23d 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -95,6 +95,7 @@ public:
#if LL_WINDOWS && !LL_SDL
virtual bool getCursorDelta(LLCoordCommon* delta) = 0;
#endif
+ virtual bool isWrapMouse() const = 0;
virtual void showCursor() = 0;
virtual void hideCursor() = 0;
virtual bool isCursorHidden() = 0;
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index 195f68e08b..7331f50ba0 100644
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -68,7 +68,13 @@ void LLWindowCallbacks::handleMouseLeave(LLWindow *window)
return;
}
-bool LLWindowCallbacks::handleCloseRequest(LLWindow *window)
+bool LLWindowCallbacks::handleCloseRequest(LLWindow *window, bool from_user)
+{
+ //allow the window to close
+ return true;
+}
+
+bool LLWindowCallbacks::handleSessionExit(LLWindow* window)
{
//allow the window to close
return true;
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index d812f93524..59dcdd3ade 100644
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -42,7 +42,8 @@ public:
virtual bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
virtual void handleMouseLeave(LLWindow *window);
// return true to allow window to close, which will then cause handleQuit to be called
- virtual bool handleCloseRequest(LLWindow *window);
+ virtual bool handleCloseRequest(LLWindow *window, bool from_user);
+ virtual bool handleSessionExit(LLWindow* window);
// window is about to be destroyed, clean up your business
virtual void handleQuit(LLWindow *window);
virtual bool handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index acec401133..0a1ecb05e0 100644
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
@@ -63,6 +63,7 @@ public:
#if LL_WINDOWS && !LL_SDL
/*virtual*/ bool getCursorDelta(LLCoordCommon* delta) override { return false; }
#endif
+ /*virtual*/ bool isWrapMouse() const override { return true; }
/*virtual*/ void showCursor() override {}
/*virtual*/ void hideCursor() override {}
/*virtual*/ void showCursorFromMouseMove() override {}
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 42cd95be5d..d902a82a3c 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -41,15 +41,15 @@
int createNSApp(int argc, const char *argv[])
{
- return NSApplicationMain(argc, argv);
+ return NSApplicationMain(argc, argv);
}
void setupCocoa()
{
- static bool inited = false;
-
- if(!inited)
- {
+ static bool inited = false;
+
+ if(!inited)
+ {
@autoreleasepool {
// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
// ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
@@ -57,8 +57,8 @@ void setupCocoa()
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
}
- inited = true;
- }
+ inited = true;
+ }
}
bool copyToPBoard(const unsigned short *str, unsigned int len)
@@ -66,7 +66,7 @@ bool copyToPBoard(const unsigned short *str, unsigned int len)
@autoreleasepool {
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
[pboard clearContents];
-
+
NSArray *contentsToPaste = [[[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil] autorelease];
return [pboard writeObjects:contentsToPaste];
}
@@ -74,8 +74,8 @@ bool copyToPBoard(const unsigned short *str, unsigned int len)
bool pasteBoardAvailable()
{
- NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
- return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
+ NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
+ return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
}
unsigned short *copyFromPBoard()
@@ -111,55 +111,55 @@ CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
hotSpot:NSMakePoint(hotspotX, hotspotY)
] retain];
}
-
- return (CursorRef)cursor;
+
+ return (CursorRef)cursor;
}
void setArrowCursor()
{
- NSCursor *cursor = [NSCursor arrowCursor];
- [NSCursor unhide];
- [cursor set];
+ NSCursor *cursor = [NSCursor arrowCursor];
+ [NSCursor unhide];
+ [cursor set];
}
void setIBeamCursor()
{
- NSCursor *cursor = [NSCursor IBeamCursor];
- [cursor set];
+ NSCursor *cursor = [NSCursor IBeamCursor];
+ [cursor set];
}
void setPointingHandCursor()
{
- NSCursor *cursor = [NSCursor pointingHandCursor];
- [cursor set];
+ NSCursor *cursor = [NSCursor pointingHandCursor];
+ [cursor set];
}
void setCopyCursor()
{
- NSCursor *cursor = [NSCursor dragCopyCursor];
- [cursor set];
+ NSCursor *cursor = [NSCursor dragCopyCursor];
+ [cursor set];
}
void setCrossCursor()
{
- NSCursor *cursor = [NSCursor crosshairCursor];
- [cursor set];
+ NSCursor *cursor = [NSCursor crosshairCursor];
+ [cursor set];
}
void setNotAllowedCursor()
{
- NSCursor *cursor = [NSCursor operationNotAllowedCursor];
- [cursor set];
+ NSCursor *cursor = [NSCursor operationNotAllowedCursor];
+ [cursor set];
}
void hideNSCursor()
{
- [NSCursor hide];
+ [NSCursor hide];
}
void showNSCursor()
{
- [NSCursor unhide];
+ [NSCursor unhide];
}
#if LL_DARWIN
@@ -179,42 +179,42 @@ bool isCGCursorVisible()
void hideNSCursorTillMove(bool hide)
{
- [NSCursor setHiddenUntilMouseMoves:hide];
+ [NSCursor setHiddenUntilMouseMoves:hide];
}
// This is currently unused, since we want all our cursors to persist for the life of the app, but I've included it for completeness.
OSErr releaseImageCursor(CursorRef ref)
{
- if( ref != NULL )
- {
+ if( ref != NULL )
+ {
@autoreleasepool {
NSCursor *cursor = (NSCursor*)ref;
[cursor autorelease];
}
- }
- else
- {
- return paramErr;
- }
-
- return noErr;
+ }
+ else
+ {
+ return paramErr;
+ }
+
+ return noErr;
}
OSErr setImageCursor(CursorRef ref)
{
- if( ref != NULL )
- {
+ if( ref != NULL )
+ {
@autoreleasepool {
NSCursor *cursor = (NSCursor*)ref;
[cursor set];
}
- }
- else
- {
- return paramErr;
- }
-
- return noErr;
+ }
+ else
+ {
+ return paramErr;
+ }
+
+ return noErr;
}
// Now for some unholy juggling between generic pointers and casting them to Obj-C objects!
@@ -222,46 +222,46 @@ OSErr setImageCursor(CursorRef ref)
NSWindowRef createNSWindow(int x, int y, int width, int height)
{
- LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height)
+ LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height)
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable
backing:NSBackingStoreBuffered defer:NO];
- [window makeKeyAndOrderFront:nil];
- [window setAcceptsMouseMovedEvents:TRUE];
+ [window makeKeyAndOrderFront:nil];
+ [window setAcceptsMouseMovedEvents:TRUE];
[window setRestorable:FALSE]; // Viewer manages state from own settings
- return window;
+ return window;
}
GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync)
{
- LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync];
- [(LLNSWindow*)window setContentView:glview];
- return glview;
+ LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync];
+ [(LLNSWindow*)window setContentView:glview];
+ return glview;
}
void glSwapBuffers(void* context)
{
- [(NSOpenGLContext*)context flushBuffer];
+ [(NSOpenGLContext*)context flushBuffer];
}
CGLContextObj getCGLContextObj(GLViewRef view)
{
- return [(LLOpenGLView *)view getCGLContextObj];
+ return [(LLOpenGLView *)view getCGLContextObj];
}
CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window)
{
- LLOpenGLView *glview = [(LLNSWindow*)window contentView];
- return [glview getCGLPixelFormatObj];
+ LLOpenGLView *glview = [(LLNSWindow*)window contentView];
+ return [glview getCGLPixelFormatObj];
}
unsigned long getVramSize(GLViewRef view)
{
- return [(LLOpenGLView *)view getVramSize];
+ return [(LLOpenGLView *)view getVramSize];
}
float getDeviceUnitSize(GLViewRef view)
{
- return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width;
+ return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width;
}
CGRect getContentViewRect(NSWindowRef window)
@@ -276,48 +276,48 @@ CGRect getBackingViewRect(NSWindowRef window, GLViewRef view)
void getWindowSize(NSWindowRef window, float* size)
{
- NSRect frame = [(LLNSWindow*)window frame];
- size[0] = frame.origin.x;
- size[1] = frame.origin.y;
- size[2] = frame.size.width;
- size[3] = frame.size.height;
+ NSRect frame = [(LLNSWindow*)window frame];
+ size[0] = frame.origin.x;
+ size[1] = frame.origin.y;
+ size[2] = frame.size.width;
+ size[3] = frame.size.height;
}
void setWindowSize(NSWindowRef window, int width, int height)
{
- NSRect frame = [(LLNSWindow*)window frame];
- frame.size.width = width;
- frame.size.height = height;
- [(LLNSWindow*)window setFrame:frame display:TRUE];
+ NSRect frame = [(LLNSWindow*)window frame];
+ frame.size.width = width;
+ frame.size.height = height;
+ [(LLNSWindow*)window setFrame:frame display:TRUE];
}
void setWindowPos(NSWindowRef window, float* pos)
{
- NSPoint point;
- point.x = pos[0];
- point.y = pos[1];
- [(LLNSWindow*)window setFrameOrigin:point];
+ NSPoint point;
+ point.x = pos[0];
+ point.y = pos[1];
+ [(LLNSWindow*)window setFrameOrigin:point];
}
void getCursorPos(NSWindowRef window, float* pos)
{
- NSPoint mLoc;
- mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream];
- pos[0] = mLoc.x;
- pos[1] = mLoc.y;
+ NSPoint mLoc;
+ mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream];
+ pos[0] = mLoc.x;
+ pos[1] = mLoc.y;
}
void makeWindowOrderFront(NSWindowRef window)
{
- [(LLNSWindow*)window makeKeyAndOrderFront:nil];
+ [(LLNSWindow*)window makeKeyAndOrderFront:nil];
}
void convertScreenToWindow(NSWindowRef window, float *coord)
{
NSRect point = NSMakeRect(coord[0], coord[1], 0,0);
- point = [(LLNSWindow*)window convertRectFromScreen:point];
- coord[0] = point.origin.x;
- coord[1] = point.origin.y;
+ point = [(LLNSWindow*)window convertRectFromScreen:point];
+ coord[0] = point.origin.x;
+ coord[1] = point.origin.y;
}
void convertRectToScreen(NSWindowRef window, float *coord)
@@ -325,21 +325,21 @@ void convertRectToScreen(NSWindowRef window, float *coord)
NSRect rect = NSMakeRect(coord[0], coord[1], coord[2], coord[3]);;
rect = [(LLNSWindow*)window convertRectToScreen:rect];
- coord[0] = rect.origin.x;
- coord[1] = rect.origin.y;
- coord[2] = rect.size.width;
- coord[3] = rect.size.height;
+ coord[0] = rect.origin.x;
+ coord[1] = rect.origin.y;
+ coord[2] = rect.size.width;
+ coord[3] = rect.size.height;
}
void convertRectFromScreen(NSWindowRef window, float *coord)
{
- NSRect point = NSMakeRect(coord[0], coord[1], coord[2], coord[3]);
- point = [(LLNSWindow*)window convertRectFromScreen:point];
-
- coord[0] = point.origin.x;
- coord[1] = point.origin.y;
- coord[2] = point.size.width;
- coord[3] = point.size.height;
+ NSRect point = NSMakeRect(coord[0], coord[1], coord[2], coord[3]);
+ point = [(LLNSWindow*)window convertRectFromScreen:point];
+
+ coord[0] = point.origin.x;
+ coord[1] = point.origin.y;
+ coord[2] = point.size.width;
+ coord[3] = point.size.height;
}
void convertWindowToScreen(NSWindowRef window, float *coord)
@@ -353,24 +353,24 @@ void convertWindowToScreen(NSWindowRef window, float *coord)
void closeWindow(NSWindowRef window)
{
- [(LLNSWindow*)window close];
- [(LLNSWindow*)window release];
+ [(LLNSWindow*)window close];
+ [(LLNSWindow*)window release];
}
void removeGLView(GLViewRef view)
{
- [(LLOpenGLView*)view clearGLContext];
- [(LLOpenGLView*)view removeFromSuperview];
+ [(LLOpenGLView*)view clearGLContext];
+ [(LLOpenGLView*)view removeFromSuperview];
}
void setupInputWindow(NSWindowRef window, GLViewRef glview)
{
- [[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
+ [[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
}
void commitCurrentPreedit(GLViewRef glView)
{
- [(LLOpenGLView*)glView commitCurrentPreedit];
+ [(LLOpenGLView*)glView commitCurrentPreedit];
}
void allowDirectMarkedTextInput(bool allow, GLViewRef glView)
@@ -380,20 +380,20 @@ void allowDirectMarkedTextInput(bool allow, GLViewRef glView)
NSWindowRef getMainAppWindow()
{
- LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
-
- [winRef setAcceptsMouseMovedEvents:TRUE];
- return winRef;
+ LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
+
+ [winRef setAcceptsMouseMovedEvents:TRUE];
+ return winRef;
}
void makeFirstResponder(NSWindowRef window, GLViewRef view)
{
- [(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view];
+ [(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view];
}
void requestUserAttention()
{
- [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
+ [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
}
long showAlert(std::string text, std::string title, int type)
@@ -401,7 +401,7 @@ long showAlert(std::string text, std::string title, int type)
long ret = 0;
@autoreleasepool {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
-
+
[alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
[alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
if (type == 0)
@@ -418,7 +418,7 @@ long showAlert(std::string text, std::string title, int type)
}
ret = [alert runModal];
}
-
+
if (ret == NSAlertFirstButtonReturn)
{
if (type == 1)
@@ -438,7 +438,7 @@ long showAlert(std::string text, std::string title, int type)
ret = 1;
}
}
-
+
return ret;
}
@@ -451,5 +451,5 @@ long showAlert(std::string text, std::string title, int type)
unsigned int getModifiers()
{
- return [NSEvent modifierFlags];
+ return [NSEvent modifierFlags];
}
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 4a4b2658f6..0bf1c4b057 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -613,7 +613,7 @@ void callQuitHandler()
{
if (gWindowImplementation && gWindowImplementation->getCallbacks())
{
- if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation))
+ if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation, true))
{
gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation);
}
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 110c5756d0..d703a84d02 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -63,6 +63,7 @@ public:
bool switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync, const LLCoordScreen * const posp = NULL) override;
bool setCursorPosition(LLCoordWindow position) override;
bool getCursorPosition(LLCoordWindow *position) override;
+ bool isWrapMouse() const override { return !mCursorDecoupled; };
void showCursor() override;
void hideCursor() override;
void showCursorFromMouseMove() override;
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 0a117be1fc..ad40dea0c3 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -1722,7 +1722,7 @@ void LLWindowSDL::gatherInput()
break;
}
case SDL_QUIT:
- if(mCallbacks->handleCloseRequest(this))
+ if(mCallbacks->handleCloseRequest(this, true))
{
// Get the app to initiate cleanup.
mCallbacks->handleQuit(this);
diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h
index 076d7234bc..d9b6be5fdc 100644
--- a/indra/llwindow/llwindowsdl.h
+++ b/indra/llwindow/llwindowsdl.h
@@ -91,6 +91,8 @@ public:
bool getCursorPosition(LLCoordWindow *position) override;
+ bool isWrapMouse() const override { return true; }
+
void showCursor() override;
void hideCursor() override;
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index cfc2038be9..5471e1c87a 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -450,6 +450,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
F32 max_gl_version)
:
LLWindow(callbacks, fullscreen, flags),
+ mAbsoluteCursorPosition(false),
mMaxGLVersion(max_gl_version),
mMaxCores(max_cores)
{
@@ -2466,10 +2467,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_CLOSE:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_CLOSE");
+ // todo: WM_CLOSE can be caused by user and by task manager,
+ // distinguish these cases.
+ // For now assume it is always user.
window_imp->post([=]()
{
// Will the app allow the window to close?
- if (window_imp->mCallbacks->handleCloseRequest(window_imp))
+ if (window_imp->mCallbacks->handleCloseRequest(window_imp, true))
{
// Get the app to initiate cleanup.
window_imp->mCallbacks->handleQuit(window_imp);
@@ -2487,6 +2491,50 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
}
return 0;
}
+ case WM_QUERYENDSESSION:
+ {
+ // Generally means that OS is going to shut down or user is going to log off.
+ // Can use ShutdownBlockReasonCreate here.
+ LL_INFOS("Window") << "Received WM_QUERYENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL;
+ return TRUE; // 1 = ok to end session. 0 no longer works by itself, use ShutdownBlockReasonCreate
+ }
+ case WM_ENDSESSION:
+ {
+ // OS session is shutting down, initiate cleanup.
+ // Comes after WM_QUERYENDSESSION
+ LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ENDSESSION");
+ LL_INFOS("Window") << "Received WM_ENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL;
+ unsigned int end_session_flags = (U32)w_param;
+ if (end_session_flags == 0)
+ {
+ // session is not actually ending
+ return 0;
+ }
+
+ if ((end_session_flags & ENDSESSION_CLOSEAPP)
+ || (end_session_flags & ENDSESSION_CRITICAL)
+ || (end_session_flags & ENDSESSION_LOGOFF))
+ {
+ window_imp->post([=]()
+ {
+ // Check if app needs cleanup or can be closed immediately.
+ if (window_imp->mCallbacks->handleSessionExit(window_imp))
+ {
+ // Get the app to initiate cleanup.
+ window_imp->mCallbacks->handleQuit(window_imp);
+ // The app is responsible for calling destroyWindow when done with GL
+ }
+ });
+ // Give app a second to finish up. That's not enough for a clean exit,
+ // but better than nothing.
+ // Todo: sync this better, some kind of waitForResult? Can't wait forever,
+ // but can potentially use ShutdownBlockReasonCreate for a bigger delay.
+ ms_sleep(1000);
+ }
+ // Don't need to post quit or destroy window,
+ // if session is ending OS is going to take care of it.
+ return 0;
+ }
case WM_COMMAND:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_COMMAND");
@@ -3111,6 +3159,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
prev_absolute_x = absolute_x;
prev_absolute_y = absolute_y;
+ window_imp->mAbsoluteCursorPosition = true;
}
else
{
@@ -3127,6 +3176,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mRawMouseDelta.mX += (S32)round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED);
window_imp->mRawMouseDelta.mY -= (S32)round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED);
}
+ window_imp->mAbsoluteCursorPosition = false;
}
}
}
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 7196706f87..0fc93ad0b1 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -70,6 +70,7 @@ public:
/*virtual*/ bool setCursorPosition(LLCoordWindow position);
/*virtual*/ bool getCursorPosition(LLCoordWindow *position);
/*virtual*/ bool getCursorDelta(LLCoordCommon* delta);
+ /*virtual*/ bool isWrapMouse() const override { return !mAbsoluteCursorPosition; };
/*virtual*/ void showCursor();
/*virtual*/ void hideCursor();
/*virtual*/ void showCursorFromMouseMove();
@@ -195,6 +196,7 @@ protected:
HCURSOR mCursor[ UI_CURSOR_COUNT ]; // Array of all mouse cursors
LLCoordWindow mCursorPosition; // mouse cursor position, should only be mutated on main thread
+ bool mAbsoluteCursorPosition; // true if last position was received in absolute coordinates.
LLMutex mRawMouseMutex;
RAWINPUTDEVICE mRawMouse;
LLCoordWindow mLastCursorPosition; // mouse cursor position from previous frame
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6a15f2fd38..0970bc7d4b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -58,7 +58,7 @@ if (ENABLE_MEDIA_PLUGINS)
include(CEFPlugin)
endif ()
-if (NOT HAVOK_TPV)
+if (HAVOK)
# When using HAVOK_TPV, the library is precompiled, so no need for this
# Stub and probably havok lib itself is a hack, autobuild loads a 3p that really is a source tarball
@@ -84,7 +84,7 @@ if (NOT HAVOK_TPV)
target_compile_options( llphysicsextensions PRIVATE -Wno-unused-local-typedef)
endif (DARWIN)
endif()
-endif (NOT HAVOK_TPV)
+endif ()
set(viewer_SOURCE_FILES
gltfscenemanager.cpp
@@ -1744,10 +1744,6 @@ if (WINDOWS)
list(APPEND viewer_SOURCE_FILES ${viewer_INSTALLER_FILES})
endif (WINDOWS)
-if (HAVOK OR HAVOK_TPV)
- set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_HAVOK")
-endif (HAVOK OR HAVOK_TPV)
-
if( DEFINED LLSTARTUP_COMPILE_FLAGS )
# progress view disables/enables icons based on available packages
set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
@@ -2093,13 +2089,30 @@ elseif (DARWIN)
PROPERTIES
RESOURCE SecondLife.xib
LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip"
- # arch specific flags for universal builds: https://stackoverflow.com/a/77942065
- XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=x86_64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_FULL"
- XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=arm64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_STUB"
- # only generate the .MAP file for llphysicsextensions_tpv on x86_64
- XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=x86_64] "$(inherited) -L${CMAKE_CURRENT_BINARY_DIR}/llphysicsextensions/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensions -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP"
- XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=arm64] "$(inherited) -L${CMAKE_CURRENT_BINARY_DIR}/llphysicsextensionsstub/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensionsstub"
)
+ if(HAVOK)
+ set_target_properties(${VIEWER_BINARY_NAME}
+ PROPERTIES
+ # arch specific flags for universal builds: https://stackoverflow.com/a/77942065
+ XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=x86_64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_FULL -DLL_HAVOK=1"
+ XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=arm64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_STUB"
+ # only generate the .MAP file for llphysicsextensions_tpv on x86_64
+ XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=x86_64] "$(inherited) -L${CMAKE_CURRENT_BINARY_DIR}/llphysicsextensions/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensions -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP"
+ XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=arm64] "$(inherited) -L${CMAKE_BINARY_DIR}/llphysicsextensionsos/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensionsos"
+ )
+ elseif(HAVOK_TPV)
+ set_target_properties(${VIEWER_BINARY_NAME}
+ PROPERTIES
+ # arch specific flags for universal builds: https://stackoverflow.com/a/77942065
+ XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=x86_64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_FULL -DLL_HAVOK=1"
+ XCODE_ATTRIBUTE_OTHER_CFLAGS[arch=arm64] "$(inherited) -DLLPHYSICSEXTENSIONS_USE_STUB"
+ # only generate the .MAP file for llphysicsextensions_tpv on x86_64
+ XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=x86_64] "$(inherited) -L${ARCH_PREBUILT_DIRS}/ -lllphysicsextensions_tpv"
+ XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=arm64] "$(inherited) -L${CMAKE_BINARY_DIR}/llphysicsextensionsos/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,${CMAKE_CFG_INTDIR}>/ -lllphysicsextensionsos"
+ )
+ else()
+ target_link_libraries(${VIEWER_BINARY_NAME} llphysicsextensionsos)
+ endif()
else (WINDOWS)
# Linux
set_target_properties(${VIEWER_BINARY_NAME}
@@ -2187,6 +2200,10 @@ if( TARGET ll::nvapi )
target_link_libraries(${VIEWER_BINARY_NAME} ll::nvapi )
endif()
+if ( TARGET llconvexdecomposition )
+ target_link_libraries(${VIEWER_BINARY_NAME} llconvexdecomposition )
+endif ()
+
set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
"Path to artwork files.")
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 77f5bec5b2..429dc57af3 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.2.2
+7.2.3
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d9cf46a4af..ecea9a3238 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2491,16 +2491,16 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DisableMouseWarp</key>
+ <key>MouseWarpMode</key>
<map>
<key>Comment</key>
- <string>Disable warping of the mouse to the center of the screen during alt-zoom and mouse look. Useful with certain input devices, mouse sharing programs like Synergy, or running under Parallels.</string>
+ <string>Controls warping of the mouse to the center of the screen during alt-zoom and mouse look. Useful with certain input devices, mouse sharing programs like Synergy, or running under Parallels. 0 - automatic, 1 - on, 2 - off</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>S32</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>DisableExternalBrowser</key>
<map>
@@ -2612,7 +2612,7 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DoubleClickTeleport</key>
+ <key>DoubleClickTeleport</key>
<map>
<key>Comment</key>
<string>Enable double-click to teleport where allowed (afects minimap and people panel)</string>
@@ -4413,7 +4413,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>40.0</real>
+ <real>90.0</real>
</map>
<key>LogMessages</key>
<map>
@@ -7929,7 +7929,7 @@
<key>RenderMaxOpenGLVersion</key>
<map>
<key>Comment</key>
- <string>Maximum OpenGL version to attempt use (minimum 3.1 maximum 4.6). Requires restart.</string>
+ <string>Maximum OpenGL version to attempt use (minimum 3.1 maximum 4.6). Requires restart. Windows only.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9177,7 +9177,7 @@
<key>RenderQualityPerformance</key>
<map>
<key>Comment</key>
- <string>Which graphics settings you've chosen</string>
+ <string>Which graphics settings you've chosen. Don't use this setting to change quality directly from debug settings.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9185,6 +9185,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>DebugQualityPerformance</key>
+ <map>
+ <key>Comment</key>
+ <string>Allows to change performance quality directly from debug settings.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderReflectionDetail</key>
<map>
@@ -9274,7 +9285,7 @@
<key>Value</key>
<real>1.0</real>
</map>
-
+
<key>RenderReflectionProbeDrawDistance</key>
<map>
<key>Comment</key>
@@ -9473,7 +9484,7 @@
<key>Value</key>
<real>1.0</real>
</map>
-
+
<key>RenderReflectionProbeMaxLocalLightAmbiance</key>
<map>
<key>Comment</key>
@@ -10473,13 +10484,13 @@
<key>SceneLoadRearMaxRadiusFraction</key>
<map>
<key>Comment</key>
- <string>a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold</string>
+ <string>a fraction of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>75.0</real>
+ <real>0.75</real>
</map>
<key>SceneLoadRearPixelThreshold</key>
<map>
@@ -11074,7 +11085,7 @@
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
- </map>
+ </map>
<key>NearbyListShowMap</key>
<map>
<key>Comment</key>
@@ -13190,9 +13201,9 @@
<key>Use24HourClock</key>
<map>
<key>Comment</key>
- <string>12 vs 24. At the moment only for region restart schedule floater</string>
+ <string>12 vs 24. At the moment coverage is partial</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
diff --git a/indra/newview/gltf/accessor.cpp b/indra/newview/gltf/accessor.cpp
index 03f7331893..f0ad3fa594 100644
--- a/indra/newview/gltf/accessor.cpp
+++ b/indra/newview/gltf/accessor.cpp
@@ -158,6 +158,11 @@ bool Buffer::prep(Asset& asset)
{
std::string dir = gDirUtilp->getDirName(asset.mFilename);
std::string bin_file = dir + gDirUtilp->getDirDelimiter() + mUri;
+ if (!gDirUtilp->fileExists(bin_file))
+ {
+ // Characters might be escaped in the URI
+ bin_file = dir + gDirUtilp->getDirDelimiter() + LLURI::unescape(mUri);
+ }
llifstream file(bin_file.c_str(), std::ios::binary);
if (!file.is_open())
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp
index dd1d327683..4f8f80129d 100644
--- a/indra/newview/gltf/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -412,17 +412,14 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>
// Process this node's mesh if it has one
if (node.mMesh >= 0 && node.mMesh < mGLTFAsset.mMeshes.size())
{
- LLMatrix4 transformation;
- material_map mats;
-
- LLModel* pModel = new LLModel(volume_params, 0.f);
- const LL::GLTF::Mesh& mesh = mGLTFAsset.mMeshes[node.mMesh];
-
- // Get base mesh name and track usage
- std::string base_name = getLodlessLabel(mesh);
+ // Get base node name and track usage
+ // Potentially multiple nodes can reuse the same mesh and Collada used
+ // node name instead of mesh name, so for consistency use node name if
+ // avaliable, node index otherwise.
+ std::string base_name = getLodlessLabel(node);
if (base_name.empty())
{
- base_name = "mesh_" + std::to_string(node.mMesh);
+ base_name = "node_" + std::to_string(node_idx);
}
S32 instance_count = mesh_name_counts[base_name]++;
@@ -433,6 +430,12 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>
base_name = base_name + "_copy_" + std::to_string(instance_count);
}
+ LLMatrix4 transformation;
+ material_map mats;
+
+ LLModel* pModel = new LLModel(volume_params, 0.f);
+ const LL::GLTF::Mesh& mesh = mGLTFAsset.mMeshes[node.mMesh];
+
if (populateModelFromMesh(pModel, base_name, mesh, node, mats) &&
(LLModel::NO_ERRORS == pModel->getStatus()) &&
validate_model(pModel))
@@ -652,6 +655,14 @@ std::string LLGLTFLoader::processTexture(S32 texture_index, const std::string& t
filename = filename.substr(pos + 1);
}
+ std::string dir = gDirUtilp->getDirName(mFilename);
+ std::string full_path = dir + gDirUtilp->getDirDelimiter() + filename;
+ if (!gDirUtilp->fileExists(full_path) && filename.find("data:") == std::string::npos)
+ {
+ // Uri might be escaped
+ filename = LLURI::unescape(filename);
+ }
+
LL_INFOS("GLTF_IMPORT") << "Found texture: " << filename << " for material: " << material_name << LL_ENDL;
LLSD args;
@@ -1810,13 +1821,13 @@ size_t LLGLTFLoader::getSuffixPosition(const std::string &label)
return -1;
}
-std::string LLGLTFLoader::getLodlessLabel(const LL::GLTF::Mesh& mesh)
+std::string LLGLTFLoader::getLodlessLabel(const LL::GLTF::Node& node)
{
- size_t ext_pos = getSuffixPosition(mesh.mName);
+ size_t ext_pos = getSuffixPosition(node.mName);
if (ext_pos != -1)
{
- return mesh.mName.substr(0, ext_pos);
+ return node.mName.substr(0, ext_pos);
}
- return mesh.mName;
+ return node.mName;
}
diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h
index e8b91996c7..7aa1a94c20 100644
--- a/indra/newview/gltf/llgltfloader.h
+++ b/indra/newview/gltf/llgltfloader.h
@@ -170,7 +170,7 @@ private:
void notifyUnsupportedExtension(bool unsupported);
static size_t getSuffixPosition(const std::string& label);
- static std::string getLodlessLabel(const LL::GLTF::Mesh& mesh);
+ static std::string getLodlessLabel(const LL::GLTF::Node& mesh);
// bool mPreprocessGLTF;
diff --git a/indra/newview/licenses-linux.txt b/indra/newview/licenses-linux.txt
index 8312d73978..22b9e4b449 100644
--- a/indra/newview/licenses-linux.txt
+++ b/indra/newview/licenses-linux.txt
@@ -457,3 +457,36 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+
+======
+V-HACD
+======
+BSD 3-Clause License
+
+Copyright (c) 2011, Khaled Mamou (kmamou at gmail dot com)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/indra/newview/licenses-mac.txt b/indra/newview/licenses-mac.txt
index d8965a6954..a51bc12abf 100644
--- a/indra/newview/licenses-mac.txt
+++ b/indra/newview/licenses-mac.txt
@@ -722,3 +722,35 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+======
+V-HACD
+======
+BSD 3-Clause License
+
+Copyright (c) 2011, Khaled Mamou (kmamou at gmail dot com)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt
index 9dbc64cbec..f7b8cb74be 100644
--- a/indra/newview/licenses-win32.txt
+++ b/indra/newview/licenses-win32.txt
@@ -636,6 +636,39 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+======
+V-HACD
+======
+BSD 3-Clause License
+
+Copyright (c) 2011, Khaled Mamou (kmamou at gmail dot com)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
==============
Vulkan GLTF
==============
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 1cd58b7101..abea7926ee 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -167,7 +167,7 @@ std::map<S32, std::string> LLTeleportRequest::sTeleportStatusName = { { kPending
class LLTeleportRequestViaLandmark : public LLTeleportRequest
{
public:
- LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
+ LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId, bool log = true);
virtual ~LLTeleportRequestViaLandmark();
virtual void toOstream(std::ostream& os) const;
@@ -179,6 +179,7 @@ public:
protected:
inline const LLUUID &getLandmarkId() const {return mLandmarkId;};
+ bool mLogOnDestruction = true;
private:
LLUUID mLandmarkId;
@@ -5022,16 +5023,25 @@ void LLTeleportRequest::toOstream(std::ostream& os) const
//-----------------------------------------------------------------------------
// LLTeleportRequestViaLandmark
//-----------------------------------------------------------------------------
-LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId)
- : LLTeleportRequest(),
- mLandmarkId(pLandmarkId)
+LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId, bool log)
+ : LLTeleportRequest()
+ , mLandmarkId(pLandmarkId)
+ , mLogOnDestruction(true)
{
- LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created, " << *this << LL_ENDL;
+ if (log)
+ {
+ // Workaround to not log twice for LLTeleportRequestViaLure, besides this wouldn't have logged fully.
+ LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created, " << *this << LL_ENDL;
+ }
}
LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
{
- LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark, " << *this << LL_ENDL;
+ if (mLogOnDestruction)
+ {
+ // Workaround to not crash on toOstream for derived classes and to not log twice.
+ LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark, " << *this << LL_ENDL;
+ }
}
void LLTeleportRequestViaLandmark::toOstream(std::ostream& os) const
@@ -5061,16 +5071,20 @@ void LLTeleportRequestViaLandmark::restartTeleport()
// LLTeleportRequestViaLure
//-----------------------------------------------------------------------------
-LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID &pLureId, bool pIsLureGodLike)
- : LLTeleportRequestViaLandmark(pLureId),
+LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID& pLureId, bool pIsLureGodLike)
+ : LLTeleportRequestViaLandmark(pLureId, false),
mIsLureGodLike(pIsLureGodLike)
{
- LL_INFOS("Teleport") << "LLTeleportRequestViaLure created" << LL_ENDL;
+ LL_INFOS("Teleport") << "LLTeleportRequestViaLure created: " << *this << LL_ENDL;
}
LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
{
- LL_INFOS("Teleport") << "~LLTeleportRequestViaLure" << LL_ENDL;
+ if (mLogOnDestruction)
+ {
+ LL_INFOS("Teleport") << "~LLTeleportRequestViaLure: " << *this << LL_ENDL;
+ mLogOnDestruction = false;
+ }
}
void LLTeleportRequestViaLure::toOstream(std::ostream& os) const
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 93cc4941f1..5801ba1eb8 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -538,6 +538,27 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::ETyp
return item;
}
+const S32 LLAgentWearables::getWearableIdxFromItem(const LLViewerInventoryItem* item) const
+{
+ if (!item) return -1;
+ if (!item->isWearableType()) return -1;
+
+ LLWearableType::EType type = item->getWearableType();
+ U32 wearable_count = getWearableCount(type);
+ if (0 == wearable_count) return -1;
+
+ const LLUUID& asset_id = item->getAssetUUID();
+
+ for (U32 i = 0; i < wearable_count; ++i)
+ {
+ const LLViewerWearable* wearable = getViewerWearable(type, i);
+ if (!wearable) continue;
+ if (wearable->getAssetID() != asset_id) continue;
+ return i;
+ }
+
+ return -1;
+}
const LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
{
const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
@@ -1471,7 +1492,7 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos
LLWearableType::EType type = item->getWearableType();
U32 wearable_count = getWearableCount(type);
- if (0 == wearable_count) return false;
+ if (wearable_count < 2) return false;
const LLUUID& asset_id = item->getAssetUUID();
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 3b8ff93c76..1e118ffa98 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -87,6 +87,7 @@ public:
public:
const LLUUID getWearableItemID(LLWearableType::EType type, U32 index /*= 0*/) const;
const LLUUID getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const;
+ const S32 getWearableIdxFromItem(const LLViewerInventoryItem* item) const;
const LLViewerWearable* getWearableFromItemID(const LLUUID& item_id) const;
LLViewerWearable* getWearableFromItemID(const LLUUID& item_id);
LLViewerWearable* getWearableFromAssetID(const LLUUID& asset_id);
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index b8fd3dc189..af18dca185 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -57,42 +57,42 @@
- (void) applicationDidFinishLaunching:(NSNotification *)notification
{
- // Call constructViewer() first so our logging subsystem is in place. This
- // risks missing crashes in the LLAppViewerMacOSX constructor, but for
- // present purposes it's more important to get the startup sequence
- // properly logged.
- // Someday I would like to modify the logging system so that calls before
- // it's initialized are cached in a std::ostringstream and then, once it's
- // initialized, "played back" into whatever handlers have been set up.
- constructViewer();
+ // Call constructViewer() first so our logging subsystem is in place. This
+ // risks missing crashes in the LLAppViewerMacOSX constructor, but for
+ // present purposes it's more important to get the startup sequence
+ // properly logged.
+ // Someday I would like to modify the logging system so that calls before
+ // it's initialized are cached in a std::ostringstream and then, once it's
+ // initialized, "played back" into whatever handlers have been set up.
+ constructViewer();
#if defined(LL_BUGSPLAT)
infos("bugsplat setup");
- // Engage BugsplatStartupManager *before* calling initViewer() to handle
- // any crashes during initialization.
- // https://www.bugsplat.com/docs/platforms/os-x#initialization
- [BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
- [BugsplatStartupManager sharedManager].askUserDetails = NO;
- [BugsplatStartupManager sharedManager].delegate = self;
- [[BugsplatStartupManager sharedManager] start];
+ // Engage BugsplatStartupManager *before* calling initViewer() to handle
+ // any crashes during initialization.
+ // https://www.bugsplat.com/docs/platforms/os-x#initialization
+ [BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
+ [BugsplatStartupManager sharedManager].askUserDetails = NO;
+ [BugsplatStartupManager sharedManager].delegate = self;
+ [[BugsplatStartupManager sharedManager] start];
#endif
infos("post-bugsplat setup");
- frameTimer = nil;
+ frameTimer = nil;
- [self languageUpdated];
+ [self languageUpdated];
- if (initViewer())
- {
- // Set up recurring calls to oneFrame (repeating timer with timeout 0)
- // until applicationShouldTerminate.
- frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self
- selector:@selector(oneFrame) userInfo:nil repeats:YES];
- } else {
- exit(0);
- }
+ if (initViewer())
+ {
+ // Set up recurring calls to oneFrame (repeating timer with timeout 0)
+ // until applicationShouldTerminate.
+ frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self
+ selector:@selector(oneFrame) userInfo:nil repeats:YES];
+ } else {
+ exit(0);
+ }
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
// [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
@@ -110,74 +110,74 @@
- (void) applicationDidBecomeActive:(NSNotification *)notification
{
- callWindowFocus();
+ callWindowFocus();
}
- (void) applicationDidResignActive:(NSNotification *)notification
{
- callWindowUnfocus();
+ callWindowUnfocus();
}
- (void) applicationDidHide:(NSNotification *)notification
{
- callWindowHide();
+ callWindowHide();
}
- (void) applicationDidUnhide:(NSNotification *)notification
{
- callWindowUnhide();
+ callWindowUnhide();
}
- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender
{
- // run one frame to assess state
- if (!pumpMainLoop())
- {
- // pumpMainLoop() returns true when done, false if it wants to be
- // called again. Since it returned false, do not yet cancel
- // frameTimer.
- handleQuit();
- [[NSApplication sharedApplication] stopModal];
- return NSTerminateCancel;
- } else {
- // pumpMainLoop() returned true: it's done. Okay, done with frameTimer.
- [frameTimer release];
- cleanupViewer();
- return NSTerminateNow;
- }
+ // run one frame to assess state
+ if (!pumpMainLoop())
+ {
+ // pumpMainLoop() returns true when done, false if it wants to be
+ // called again. Since it returned false, do not yet cancel
+ // frameTimer.
+ handleQuit();
+ [[NSApplication sharedApplication] stopModal];
+ return NSTerminateCancel;
+ } else {
+ // pumpMainLoop() returned true: it's done. Okay, done with frameTimer.
+ [frameTimer release];
+ cleanupViewer();
+ return NSTerminateNow;
+ }
}
- (void) oneFrame
{
- bool appExiting = pumpMainLoop();
- if (appExiting)
- {
- // Once pumpMainLoop() reports that we're done, cancel frameTimer:
- // stop the repetitive calls.
- [frameTimer release];
- [[NSApplication sharedApplication] terminate:self];
- }
+ bool appExiting = pumpMainLoop();
+ if (appExiting)
+ {
+ // Once pumpMainLoop() reports that we're done, cancel frameTimer:
+ // stop the repetitive calls.
+ [frameTimer release];
+ [[NSApplication sharedApplication] terminate:self];
+ }
}
- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent
{
- if (![self romanScript])
- {
- if (show)
- {
- NSLog(@"Showing input window.");
- [inputWindow makeKeyAndOrderFront:inputWindow];
+ if (![self romanScript])
+ {
+ if (show)
+ {
+ NSLog(@"Showing input window.");
+ [inputWindow makeKeyAndOrderFront:inputWindow];
if (textEvent != nil)
{
[[inputView inputContext] discardMarkedText];
[[inputView inputContext] handleEvent:textEvent];
}
- } else {
- NSLog(@"Hiding input window.");
- [inputWindow orderOut:inputWindow];
- [window makeKeyAndOrderFront:window];
- }
- }
+ } else {
+ NSLog(@"Hiding input window.");
+ [inputWindow orderOut:inputWindow];
+ [window makeKeyAndOrderFront:window];
+ }
+ }
}
// This will get called multiple times by NSNotificationCenter.
@@ -187,15 +187,15 @@
- (void) languageUpdated
{
- TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource();
- CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages);
-
+ TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource();
+ CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages);
+
#if 0 // In the event of ever needing to add new language sources, change this to 1 and watch the terminal for "languages:"
- NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages));
+ NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages));
#endif
-
- // Typically the language we want is going to be the very first result in the array.
- currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0);
+
+ // Typically the language we want is going to be the very first result in the array.
+ currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0);
}
- (bool) romanScript
@@ -209,7 +209,7 @@
return false;
}
}
-
+
return true;
}
@@ -313,11 +313,11 @@ struct AttachmentInfo
// We "happen to know" that info[0].basename is "SecondLife.old" -- due to
// the fact that BugsplatMac only notices a crash during the viewer run
- // following the crash.
+ // following the crash.
// The Bugsplat service doesn't respect the MIME type above when returning
// the log data to a browser, so take this opportunity to rename the file
// from <base>.old to <base>_log.txt
- info[0].basename =
+ info[0].basename =
boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt";
infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename);
@@ -373,7 +373,7 @@ struct AttachmentInfo
{
[super sendEvent:event];
if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand))
- {
+ {
[[self keyWindow] sendEvent:event];
}
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 71dec10e01..cb352ac3e5 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1500,6 +1500,27 @@ void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false)
}
}
+bool needs_to_replace(LLViewerInventoryItem* item_to_wear, bool & first_for_object, std::vector<bool>& first_for_type, bool replace)
+{
+ bool res = false;
+ LLAssetType::EType type = item_to_wear->getType();
+ if (type == LLAssetType::AT_OBJECT)
+ {
+ res = first_for_object && replace;
+ first_for_object = false;
+ }
+ else if (type == LLAssetType::AT_CLOTHING)
+ {
+ LLWearableType::EType wtype = item_to_wear->getWearableType();
+ if (wtype >= 0 && wtype < LLWearableType::WT_COUNT)
+ {
+ res = first_for_type[wtype] && replace;
+ first_for_type[wtype] = false;
+ }
+ }
+ return res;
+}
+
void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
bool do_update,
bool replace,
@@ -1508,7 +1529,8 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
LL_DEBUGS("UIUsage") << "wearItemsOnAvatar" << LL_ENDL;
LLUIUsage::instance().logCommand("Avatar.WearItem");
- bool first = true;
+ bool first_for_object = true;
+ std::vector<bool> first_for_type(LLWearableType::WT_COUNT, true);
LLInventoryObject::const_object_list_t items_to_link;
@@ -1516,9 +1538,6 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
it != item_ids_to_wear.end();
++it)
{
- replace = first && replace;
- first = false;
-
const LLUUID& item_id_to_wear = *it;
if (item_id_to_wear.isNull())
@@ -1537,8 +1556,9 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))
{
LL_DEBUGS("Avatar") << "inventory item in library, will copy and wear "
- << item_to_wear->getName() << " id " << item_id_to_wear << LL_ENDL;
- LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace));
+ << item_to_wear->getName() << " id " << item_id_to_wear << LL_ENDL;
+ bool replace_item = needs_to_replace(item_to_wear, first_for_object, first_for_type, replace);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb, _1, replace_item));
copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(),
item_to_wear->getUUID(), LLUUID::null, std::string(), cb);
continue;
@@ -1576,7 +1596,8 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
}
LLWearableType::EType type = item_to_wear->getWearableType();
S32 wearable_count = gAgentWearables.getWearableCount(type);
- if ((replace && wearable_count != 0) || !gAgentWearables.canAddWearable(type))
+ bool replace_item = needs_to_replace(item_to_wear, first_for_object, first_for_type, replace);
+ if ((replace_item && wearable_count != 0) || !gAgentWearables.canAddWearable(type))
{
LLUUID item_id = gAgentWearables.getWearableItemID(item_to_wear->getWearableType(),
wearable_count-1);
@@ -1605,7 +1626,13 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
case LLAssetType::AT_OBJECT:
{
- rez_attachment(item_to_wear, NULL, replace);
+ // Note that this will replace only first attachment regardless of attachment point,
+ // so if user is wearing two items over other two on different attachment points,
+ // only one will be replaced.
+ // Unfortunately we have no way to determine attachment point from inventory item.
+ // We might want to forbid wearing multiple objects with replace option in future.
+ bool replace_item = needs_to_replace(item_to_wear, first_for_object, first_for_type, replace);
+ rez_attachment(item_to_wear, NULL, replace_item);
}
break;
@@ -4220,37 +4247,54 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b
if (item->getType() != LLAssetType::AT_CLOTHING) return false;
if (!gInventory.isObjectDescendentOf(item->getUUID(), getCOF())) return false;
+ S32 pos = gAgentWearables.getWearableIdxFromItem(item);
+ if (pos < 0) return false; // Not found
+
+ U32 count = gAgentWearables.getWearableCount(item->getWearableType());
+ if (count < 2) return false; // Nothing to swap with
+ if (closer_to_body)
+ {
+ if (pos == 0) return false; // already first
+ }
+ else
+ {
+ if (pos == count - 1) return false; // already last
+ }
+
+ U32 old_pos = (U32)pos;
+ U32 swap_with = closer_to_body ? old_pos - 1 : old_pos + 1;
+ LLUUID swap_item_id = gAgentWearables.getWearableItemID(item->getWearableType(), swap_with);
+
+ // Find link item from item id.
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
LLFindWearablesOfType filter_wearables_of_type(item->getWearableType());
gInventory.collectDescendentsIf(getCOF(), cats, items, true, filter_wearables_of_type);
if (items.empty()) return false;
- // We assume that the items have valid descriptions.
- std::sort(items.begin(), items.end(), WearablesOrderComparator(item->getWearableType()));
-
- if (closer_to_body && items.front() == item) return false;
- if (!closer_to_body && items.back() == item) return false;
-
- LLInventoryModel::item_array_t::iterator it = std::find(items.begin(), items.end(), item);
- if (items.end() == it) return false;
-
-
- //swapping descriptions
- closer_to_body ? --it : ++it;
- LLViewerInventoryItem* swap_item = *it;
- if (!swap_item) return false;
- std::string tmp = swap_item->getActualDescription();
- swap_item->setDescription(item->getActualDescription());
- item->setDescription(tmp);
+ LLViewerInventoryItem* swap_item = nullptr;
+ for (auto iter : items)
+ {
+ if (iter->getLinkedUUID() == swap_item_id)
+ {
+ swap_item = iter.get();
+ break;
+ }
+ }
+ if (!swap_item)
+ {
+ return false;
+ }
- // LL_DEBUGS("Inventory") << "swap, item "
- // << ll_pretty_print_sd(item->asLLSD())
- // << " swap_item "
- // << ll_pretty_print_sd(swap_item->asLLSD()) << LL_ENDL;
+ // Description is supposed to hold sort index, but user could have changed
+ // order rapidly and there might be a state mismatch between description
+ // and gAgentWearables, trust gAgentWearables over description.
+ // Generate new description.
+ std::string new_desc = build_order_string(item->getWearableType(), old_pos);
+ swap_item->setDescription(new_desc);
+ new_desc = build_order_string(item->getWearableType(), swap_with);
+ item->setDescription(new_desc);
- // FIXME switch to use AISv3 where supported.
- //items need to be updated on a dataserver
item->setComplete(true);
item->updateServer(false);
gInventory.updateItem(item);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c3dc821b13..c34441932d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1288,6 +1288,7 @@ bool LLAppViewer::init()
LLViewerCamera::createInstance();
LL::GLTFSceneManager::createInstance();
+ gSavedSettings.setU32("DebugQualityPerformance", gSavedSettings.getU32("RenderQualityPerformance"));
#if LL_WINDOWS
if (!mSecondInstance)
@@ -2458,7 +2459,6 @@ void LLAppViewer::initLoggingAndGetLastDuration()
if (gDirUtilp->fileExists(user_data_path_cef_log))
{
std::string user_data_path_cef_old = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.old");
- LLFile::remove(user_data_path_cef_old, ENOENT);
LLFile::rename(user_data_path_cef_log, user_data_path_cef_old);
}
}
@@ -4006,8 +4006,15 @@ void LLAppViewer::processMarkerFiles()
else if (marker_is_same_version)
{
// the file existed, is ours, and matched our version, so we can report on what it says
- LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL;
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed or froze" << LL_ENDL;
+#if LL_WINDOWS && LL_BUGSPLAT
+ // bugsplat will set correct state in bugsplatSendLog
+ // Might be more accurate to rename this one into 'unknown'
+ gLastExecEvent = LAST_EXEC_FROZE;
+#else
gLastExecEvent = LAST_EXEC_OTHER_CRASH;
+#endif // LL_WINDOWS
+
}
else
{
@@ -4256,7 +4263,7 @@ void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
// case where we need the viewer to exit without any need for notifications
void LLAppViewer::earlyExitNoNotify()
{
- LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL;
+ LL_WARNS() << "app_early_exit with no notification." << LL_ENDL;
gDoDisconnect = true;
finish_early_exit( LLSD(), LLSD() );
}
@@ -4535,6 +4542,7 @@ void LLAppViewer::purgeCache()
LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
LLViewerShaderMgr::instance()->clearShaderCache();
+ purgeCefStaleCaches();
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*");
}
@@ -5469,6 +5477,12 @@ void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const
}
}
+bool LLAppViewer::errorMarkerExists() const
+{
+ std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+ return LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB);
+}
+
void LLAppViewer::outOfMemorySoftQuit()
{
if (!mQuitRequested)
@@ -5600,7 +5614,10 @@ void LLAppViewer::idleNetwork()
add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
// Retransmit unacknowledged packets.
- gXferManager->retransmitUnackedPackets();
+ if (gXferManager)
+ {
+ gXferManager->retransmitUnackedPackets();
+ }
gAssetStorage->checkForTimeouts();
gViewerThrottle.setBufferLoadRate(gMessageSystem->getBufferLoadRate());
gViewerThrottle.updateDynamicThrottle();
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 3afde6b9f5..4f2583cb16 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -149,6 +149,12 @@ public:
std::string getWindowTitle() const; // The window display name.
void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user.
+
+ // sendSimpleLogoutRequest does not create a marker file.
+ // Meant for lost network case, and for forced shutdowns,
+ // to at least attempt to remove the ghost from the world.
+ void sendSimpleLogoutRequest();
+
void badNetworkHandler(); // Cause a crash state due to bad network packet.
bool hasSavedFinalSnapshot() { return mSavedFinalSnapshot; }
@@ -245,6 +251,7 @@ public:
// Writes an error code into the error_marker file for use on next startup.
void createErrorMarker(eLastExecEvent error_code) const;
+ bool errorMarkerExists() const;
// Attempt a 'soft' quit with disconnect and saving of settings/cache.
// Intended to be thread safe.
@@ -311,10 +318,6 @@ private:
void sendLogoutRequest();
void disconnectViewer();
- // Does not create a marker file. For lost network case,
- // to at least attempt to remove the ghost from the world.
- void sendSimpleLogoutRequest();
-
// *FIX: the app viewer class should be some sort of singleton, no?
// Perhaps its child class is the singleton and this should be an abstract base.
static LLAppViewer* sInstance;
diff --git a/indra/newview/llappviewermacosx-objc.mm b/indra/newview/llappviewermacosx-objc.mm
index 2ea3f2f171..96a6bc6edc 100644
--- a/indra/newview/llappviewermacosx-objc.mm
+++ b/indra/newview/llappviewermacosx-objc.mm
@@ -5,27 +5,27 @@
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
- */
+ */
#if !defined LL_DARWIN
- #error "Use only with macOS"
+ #error "Use only with macOS"
#endif
#import <Cocoa/Cocoa.h>
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index f612495953..bd1a08798b 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -176,6 +176,22 @@ namespace
<< '/' << loc.mV[1]
<< '/' << loc.mV[2])));
}
+
+ LLAppViewer* app = LLAppViewer::instance();
+ if (!app->isSecondInstance() && !app->errorMarkerExists())
+ {
+ // If marker doesn't exist, create a marker with 'other' code for next launch
+ // otherwise don't override existing file
+ // Any unmarked crashes will be considered as freezes
+ if (app->logoutRequestSent())
+ {
+ app->createErrorMarker(LAST_EXEC_LOGOUT_CRASH);
+ }
+ else
+ {
+ app->createErrorMarker(LAST_EXEC_OTHER_CRASH);
+ }
+ }
} // MDSCB_EXCEPTIONCODE
return false;
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 21a29bb1bb..8617183840 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -215,7 +215,8 @@ public:
LLUUID obj_id = mObjectData["object_id"];
if (obj_id.notNull())
{
- return nullptr != gObjectList.findObject(mAvatarID);
+ LLViewerObject* object = gObjectList.findObject(obj_id);
+ return object && object->isReachable();
}
return false;
}
@@ -441,6 +442,7 @@ public:
time_t current_time = time_corrected();
time_t message_time = (time_t)(current_time - LLFrameTimer::getElapsedSeconds() + mTime);
+ // Report abuse shouldn't use AM/PM, use 24-hour time
time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ LLTrans::getString("TimeDay") + "]/["
+ LLTrans::getString("TimeYear") + "] ["
@@ -1117,7 +1119,11 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
mEditor->setIsFriendCallback(LLAvatarActions::isFriend);
mEditor->setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0));
-
+ mEditor->setIsObjectReachableCallback([](const LLUUID& obj_id)
+ {
+ LLViewerObject* object = gObjectList.findObject(obj_id);
+ return object && object->isReachable();
+ });
}
LLSD LLChatHistory::getValue() const
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index cea68c1779..65a068e08d 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -118,11 +118,21 @@ const std::string LLConversation::createTimestamp(const U64Seconds& utc_time)
LLSD substitution;
substitution["datetime"] = (S32)utc_time.value();
- timeStr = "["+LLTrans::getString ("TimeMonth")+"]/["
- +LLTrans::getString ("TimeDay")+"]/["
- +LLTrans::getString ("TimeYear")+"] ["
- +LLTrans::getString ("TimeHour")+"]:["
- +LLTrans::getString ("TimeMin")+"]";
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ timeStr = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] [";
+ if (use_24h)
+ {
+ timeStr += LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]";
+ }
+ else
+ {
+ timeStr += LLTrans::getString("TimeHour12") + "]:["
+ + LLTrans::getString("TimeMin") + "] ["
+ + LLTrans::getString("TimeAMPM") + "]";
+ }
LLStringUtil::format (timeStr, substitution);
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index c9470fe977..ea2bc74daa 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -802,7 +802,10 @@ void LLBumpImageList::onSourceStandardLoaded( bool success, LLViewerFetchedTextu
}
src_vi->setExplicitFormat(GL_RGBA, GL_RGBA);
{
- src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image);
+ if (!src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image))
+ {
+ LL_WARNS() << "Failed to create bump image texture for image " << src_vi->getID() << LL_ENDL;
+ }
}
}
}
@@ -896,7 +899,10 @@ void LLBumpImageList::onSourceUpdated(LLViewerTexture* src, EBumpEffect bump_cod
LLImageGL* src_img = src->getGLTexture();
LLImageGL* dst_img = bump->getGLTexture();
- dst_img->setSize(src->getWidth(), src->getHeight(), 4, 0);
+ if (!dst_img->setSize(src->getWidth(), src->getHeight(), 4, 0))
+ {
+ LL_WARNS() << "Failed to setSize for image " << bump->getID() << LL_ENDL;
+ }
dst_img->setUseMipMaps(true);
dst_img->setDiscardLevel(0);
dst_img->createGLTexture();
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index c6fea1ba82..86c58a3497 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -54,13 +54,6 @@ namespace Details
void stop();
private:
- // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
- // This means we attempt to recover relatively quickly but back off giving more time to recover
- // until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts.
- static const F32 EVENT_POLL_ERROR_RETRY_SECONDS;
- static const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC;
- static const S32 MAX_EVENT_POLL_HTTP_ERRORS;
-
void eventPollCoro(std::string url);
void handleMessage(const LLSD &content);
@@ -76,9 +69,13 @@ namespace Details
};
- const F32 LLEventPollImpl::EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout.
- const F32 LLEventPollImpl::EVENT_POLL_ERROR_RETRY_SECONDS_INC = 5.f; // ~ half of a normal timeout.
- const S32 LLEventPollImpl::MAX_EVENT_POLL_HTTP_ERRORS = 10; // ~5 minutes, by the above rules.
+ // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
+ // This means we attempt to recover relatively quickly but back off giving more time to recover
+ // until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts.
+ constexpr F32 EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout.
+ constexpr F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC = 5.f; // ~ half of a normal timeout.
+ constexpr S32 MAX_EVENT_POLL_HTTP_ERRORS = 10; // ~5 minutes, by the above rules.
+ constexpr F64 MIN_SECONDS_PASSED = 10.0; // Minimum time we expect the server to hold the request.
int LLEventPollImpl::sNextCounter = 1;
@@ -151,11 +148,17 @@ namespace Details
LLSD acknowledge;
int errorCount = 0;
int counter = mCounter; // saved on the stack for logging.
+ LLTimer message_time;
LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL;
mAdapter = httpAdapter;
+ // This is a loop with its own waitToRetry implementation,
+ // so disable retries.
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setRetries(0);
+
LL::WorkQueue::ptr_t main_queue = nullptr;
// HACK -- grab the mainloop workqueue to move execution of the handler
@@ -172,11 +175,13 @@ namespace Details
request["ack"] = acknowledge;
request["done"] = mDone;
+ message_time.reset();
+
// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> request = "
// << LLSDXMLStreamer(request) << LL_ENDL;
LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> posting and yielding." << LL_ENDL;
- LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request);
+ LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request, httpOpts);
// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = "
// << LLSDXMLStreamer(result) << LL_ENDL;
@@ -194,11 +199,30 @@ namespace Details
if (!status)
{
- if (status == LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT))
- { // A standard timeout response we get this when there are no events.
- LL_DEBUGS("LLEventPollImpl") << "All is very quiet on target server. It may have gone idle?" << LL_ENDL;
- errorCount = 0;
- continue;
+ if (status == LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT) // A standard timeout, no events.
+ || status == LLCore::HttpStatus(HTTP_BAD_GATEWAY) // An expected 'No events' case.
+ || status == LLCore::HttpStatus(HTTP_INTERNAL_ERROR)
+ || status == LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE)
+ || status == LLCore::HttpStatus(HTTP_GATEWAY_TIME_OUT))
+ {
+ if (message_time.getElapsedSeconds() < MIN_SECONDS_PASSED)
+ {
+ // Server is supposed to hold request for 20 to 30 seconds.
+ // If it didn't hold the request at least for 10s, treat as an error.
+ LL_WARNS("LLEventPollImpl") << "Response arrived too early, status: " << status.toTerseString()
+ << ", time passed: " << message_time.getElapsedSeconds() << LL_ENDL;
+ }
+ else
+ {
+ // Timeout, expected and means 'no events'. Request is to be re-issued immediately.
+ // Current definition of a timeout is any of :
+ // - libcurl easy 28 status code
+ // - Linden 499 special http status code
+ // - RFC - standard 502 - 504 http status codes
+ LL_DEBUGS("LLEventPollImpl") << "No events, from: " << mSenderIp <<" status: " << (S32)status.getStatus() << LL_ENDL;
+ errorCount = 0;
+ continue;
+ }
}
else if ((status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_OP_CANCELED)) ||
(status == LLCore::HttpStatus(HTTP_NOT_FOUND)))
@@ -206,13 +230,13 @@ namespace Details
// some cases the server gets ahead of the viewer and will
// return a 404 error (Not Found) before the cancel event
// comes back in the queue
- LL_WARNS("LLEventPollImpl") << "Canceling coroutine" << LL_ENDL;
+ LL_WARNS("LLEventPollImpl") << "<" << counter << "> Canceling coroutine, status: " << status.toTerseString() << LL_ENDL;
break;
}
else if (!status.isHttpStatus())
{
/// Some LLCore or LIBCurl error was returned. This is unlikely to be recoverable
- LL_WARNS("LLEventPollImpl") << "Critical error from poll request returned from libraries. Canceling coroutine." << LL_ENDL;
+ LL_WARNS("LLEventPollImpl") << "<" << counter << "> Critical error from poll request returned from libraries. Canceling coroutine." << LL_ENDL;
break;
}
LL_WARNS("LLEventPollImpl") << "<" << counter << "> Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
@@ -255,6 +279,10 @@ namespace Details
LL_WARNS("LLEventPollImpl") << "< " << counter << "> Forcing disconnect due to stalled main region event poll." << LL_ENDL;
LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
}
+ else
+ {
+ LL_WARNS("LLEventPollImpl") << "< " << counter << "> Stopping event poll for " << mSenderIp << " due to failures." << LL_ENDL;
+ }
break;
}
}
diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h
index bb407b3799..ea186aa803 100644
--- a/indra/newview/lleventpoll.h
+++ b/indra/newview/lleventpoll.h
@@ -40,7 +40,30 @@ namespace Details
class LLEventPoll
- ///< implements the viewer side of server-to-viewer pushed events.
+ ///< Implements the viewer side of server-to-viewer pushed events.
+ ///
+ /// This class implements the sole consumer of the EventQueueGet capability
+ /// and delivers data, including llsd-encoded llmessage payloads, from
+ /// simulator to viewer.
+ ///
+ /// https://wiki.secondlife.com/wiki/EventQueueGet
+ /// The wiki page is neither complete nor entirely correct. Request timeouts
+ /// became the de facto method of returning an empty event set to the viewer.
+ /// But the timeout behavior was never defined. It was simply whatever
+ /// behavior a given grid implementation implemented.
+ ///
+ /// In SL's case, the path may include reverse proxies, http caches, http and
+ /// socks proxies, transparent hijacking, and other horrors. A pitfall for
+ /// implementors.
+ ///
+ /// Current definition of a timeout is any of :
+ /// - libcurl easy 28 status code
+ /// - Linden 499 special http status code
+ /// - RFC - standard 502 - 504 http status codes
+ /// If requests are failing too quickly with the above errors, they are treated
+ /// as actual errors and not an empty payload. These will count towards a final
+ /// error declaration and can lead to disconnection from a simulator or the
+ /// entire grid.
{
public:
LLEventPoll(const std::string& pollURL, const LLHost& sender);
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 2bbe5e90c6..9e69fcef29 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -404,8 +404,53 @@ F32 logExceptionBenchmark()
}
#endif
+bool checkRDNA35()
+{
+ // This checks if we're running on an RDNA3.5 GPU. You're only going to see these on AMD's APUs.
+ // As of driver version 25, we're seeing stalls in some of our queries.
+ // This appears to be a driver bug, and appears to be specific RDNA3.5 APUs.
+ // There's multiples of these guys, so we just use this function to check if that GPU is on the list of known RDNA3.5 APUs.
+ // - Geenz 11/12/2025
+ std::array<std::string, 7> rdna35GPUs = {
+ "8060S",
+ "8050S",
+ "8040S",
+ "860M",
+ "840M",
+ "890M",
+ "880M"
+ };
+
+ for (const auto& gpu_name : rdna35GPUs)
+ {
+ if (gGLManager.getRawGLString().find(gpu_name) != std::string::npos)
+ {
+ LL_WARNS("RenderInit") << "Detected AMD RDNA3.5 GPU (" << gpu_name << ")." << LL_ENDL;
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool LLFeatureManager::loadGPUClass()
{
+ // This is a hack for certain AMD GPUs in newer driver versions on certain APUs.
+ // These GPUs will show inconsistent freezes when attempting to run shader profiles against them.
+ // This is extremely problematic as it can lead to:
+ // - Login freezes
+ // - Inability to start the client
+ // - Completely random avatars triggering a freeze
+ // As a result, we filter out these GPUs for shader profiling.
+ // - Geenz 11/11/2025
+
+ if (gGLManager.getRawGLString().find("Radeon") != std::string::npos && checkRDNA35() && gGLManager.mDriverVersionVendorString.find("25.") != std::string::npos)
+ {
+ LL_WARNS("RenderInit") << "Detected AMD RDNA3.5 GPU on a known bad driver; disabling benchmark and occlusion culling to prevent freezes." << LL_ENDL;
+ gSavedSettings.setBOOL("SkipBenchmark", true);
+ gSavedSettings.setBOOL("UseOcclusion", false);
+ }
+
if (!gSavedSettings.getBOOL("SkipBenchmark"))
{
F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth");
@@ -465,7 +510,7 @@ bool LLFeatureManager::loadGPUClass()
}
#if LL_WINDOWS
- const F32Gigabytes MIN_PHYSICAL_MEMORY(2);
+ const F32Gigabytes MIN_PHYSICAL_MEMORY(8);
LLMemory::updateMemoryInfo();
F32Gigabytes physical_mem = LLMemory::getMaxMemKB();
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 22de6afbae..d04b89cb60 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -123,6 +123,7 @@ public:
S32 getVersion() const { return mTableVersion; }
void setSafe(const bool safe) { mSafe = safe; }
bool isSafe() const { return mSafe; }
+ bool skipProfiling() const { return mSkipProfiling; }
LLFeatureList *findMask(const std::string& name);
bool maskFeatures(const std::string& name);
@@ -170,6 +171,7 @@ protected:
F32 mExpectedGLVersion; //expected GL version according to gpu table
std::string mGPUString;
bool mGPUSupported;
+ bool mSkipProfiling = false;
};
inline
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index 558fc92018..a05f725673 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -222,6 +222,14 @@ void LLFetchedGLTFMaterial::updateTextureTracking()
}
}
+void LLFetchedGLTFMaterial::clearFetchedTextures()
+{
+ mBaseColorTexture = nullptr;
+ mNormalTexture = nullptr;
+ mMetallicRoughnessTexture = nullptr;
+ mEmissiveTexture = nullptr;
+}
+
void LLFetchedGLTFMaterial::materialBegin()
{
llassert(!mFetching);
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
index 4a33b9f05f..074e3fef41 100644
--- a/indra/newview/llfetchedgltfmaterial.h
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -67,6 +67,7 @@ public:
LLPointer<LLViewerFetchedTexture> mNormalTexture;
LLPointer<LLViewerFetchedTexture> mMetallicRoughnessTexture;
LLPointer<LLViewerFetchedTexture> mEmissiveTexture;
+ void clearFetchedTextures();
std::set<LLTextureEntry*> mTextureEntires;
diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm
index 978069457c..6cb7c4ad51 100644
--- a/indra/newview/llfilepicker_mac.mm
+++ b/indra/newview/llfilepicker_mac.mm
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfilepicker_mac.cpp
* @brief OS-specific file picker
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -32,15 +32,15 @@
NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned int flags)
{
int i;
-
+
NSOpenPanel *panel = [NSOpenPanel openPanel];
NSMutableArray *fileTypes = nil;
-
-
+
+
if ( allowed_types && !allowed_types->empty())
{
fileTypes = [[NSMutableArray alloc] init];
-
+
for (i=0;i<allowed_types->size();++i)
{
[fileTypes addObject:
@@ -48,7 +48,7 @@ NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned
encoding:[NSString defaultCStringEncoding]]];
}
}
-
+
//[panel setMessage:@"Import one or more files or directories."];
[panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
[panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
@@ -56,7 +56,7 @@ NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned
[panel setResolvesAliases: true];
[panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
-
+
if (fileTypes)
{
[panel setAllowedFileTypes:fileTypes];
@@ -77,7 +77,7 @@ std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::st
std::unique_ptr<std::vector<std::string>> outfiles;
@autoreleasepool
- {
+ {
int result;
//Aura TODO: We could init a small window and release it at the end of this routine
//for a modeless interface.
@@ -85,17 +85,17 @@ std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::st
NSOpenPanel *panel = init_panel(allowed_types,flags);
result = [panel runModal];
-
+
if (result == NSModalResponseOK)
{
NSArray *filesToOpen = [panel URLs];
int i, count = [filesToOpen count];
-
+
if (count > 0)
{
outfiles.reset(new std::vector<std::string>);
}
-
+
for (i=0; i<count; i++) {
NSString *aFile = [[filesToOpen objectAtIndex:i] path];
std::string afilestr = std::string([aFile UTF8String]);
@@ -113,11 +113,11 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types,
{
@autoreleasepool
- {
+ {
// Note: might need to return and save this panel
// so that it does not close immediately
NSOpenPanel *panel = init_panel(allowed_types,flags);
-
+
[panel beginWithCompletionHandler:^(NSModalResponse result)
{
std::vector<std::string> outfiles;
@@ -125,10 +125,10 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types,
{
NSArray *filesToOpen = [panel URLs];
int i, count = [filesToOpen count];
-
+
if (count > 0)
{
-
+
for (i=0; i<count; i++) {
NSString *aFile = [[filesToOpen objectAtIndex:i] path];
std::string *afilestr = new std::string([aFile UTF8String]);
@@ -149,7 +149,7 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types,
}
}
-std::unique_ptr<std::string> doSaveDialog(const std::string* file,
+std::unique_ptr<std::string> doSaveDialog(const std::string* file,
const std::string* type,
const std::string* creator,
const std::string* extension,
@@ -157,18 +157,18 @@ std::unique_ptr<std::string> doSaveDialog(const std::string* file,
{
std::unique_ptr<std::string> outfile;
@autoreleasepool
- {
+ {
NSSavePanel *panel = [NSSavePanel savePanel];
-
+
NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
NSArray *fileType = [extensionns componentsSeparatedByString:@","];
-
+
//[panel setMessage:@"Save Image File"];
[panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
[panel setCanSelectHiddenExtension:true];
[panel setAllowedFileTypes:fileType];
NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
-
+
NSURL* url = [NSURL fileURLWithPath:fileName];
[panel setNameFieldStringValue: fileName];
[panel setDirectoryURL: url];
@@ -193,39 +193,39 @@ void doSaveDialogModeless(const std::string* file,
void *userdata)
{
@autoreleasepool {
- NSSavePanel *panel = [NSSavePanel savePanel];
-
- NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
- NSArray *fileType = [extensionns componentsSeparatedByString:@","];
-
- //[panel setMessage:@"Save Image File"];
- [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
- [panel setCanSelectHiddenExtension:true];
- [panel setAllowedFileTypes:fileType];
- NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
-
- NSURL* url = [NSURL fileURLWithPath:fileName];
- [panel setNameFieldStringValue: fileName];
- [panel setDirectoryURL: url];
-
-
- [panel beginWithCompletionHandler:^(NSModalResponse result)
- {
+ NSSavePanel *panel = [NSSavePanel savePanel];
+
+ NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
+ NSArray *fileType = [extensionns componentsSeparatedByString:@","];
+
+ //[panel setMessage:@"Save Image File"];
+ [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
+ [panel setCanSelectHiddenExtension:true];
+ [panel setAllowedFileTypes:fileType];
+ NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
+
+ NSURL* url = [NSURL fileURLWithPath:fileName];
+ [panel setNameFieldStringValue: fileName];
+ [panel setDirectoryURL: url];
+
+
+ [panel beginWithCompletionHandler:^(NSModalResponse result)
+ {
if (result == NSModalResponseOK)
- {
- NSURL* url = [panel URL];
- NSString* p = [url path];
- std::string outfile([p UTF8String]);
-
- callback(true, outfile, userdata);
- }
- else // cancel
- {
- std::string outfile;
- callback(false, outfile, userdata);
- }
- }];
- }
+ {
+ NSURL* url = [panel URL];
+ NSString* p = [url path];
+ std::string outfile([p UTF8String]);
+
+ callback(true, outfile, userdata);
+ }
+ else // cancel
+ {
+ std::string outfile;
+ callback(false, outfile, userdata);
+ }
+ }];
+ }
}
#endif
diff --git a/indra/newview/llfloateravatarwelcomepack.cpp b/indra/newview/llfloateravatarwelcomepack.cpp
index 82e44d1398..be384bf4d1 100644
--- a/indra/newview/llfloateravatarwelcomepack.cpp
+++ b/indra/newview/llfloateravatarwelcomepack.cpp
@@ -28,8 +28,10 @@
#include "llviewerprecompiledheaders.h"
#include "llfloateravatarwelcomepack.h"
-#include "lluictrlfactory.h"
#include "llmediactrl.h"
+#include "lluictrlfactory.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
LLFloaterAvatarWelcomePack::LLFloaterAvatarWelcomePack(const LLSD& key)
: LLFloater(key)
@@ -52,6 +54,10 @@ bool LLFloaterAvatarWelcomePack::postBuild()
if (mAvatarPicker)
{
mAvatarPicker->clearCache();
+ mAvatarPicker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
+ std::string url = gSavedSettings.getString("AvatarWelcomePack");
+ url = LLWeb::expandURLSubstitutions(url, LLSD());
+ mAvatarPicker->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
}
return true;
diff --git a/indra/newview/llfloaterdestinations.cpp b/indra/newview/llfloaterdestinations.cpp
index fad9693e8f..84fc4afcdd 100644
--- a/indra/newview/llfloaterdestinations.cpp
+++ b/indra/newview/llfloaterdestinations.cpp
@@ -28,7 +28,10 @@
#include "llviewerprecompiledheaders.h"
#include "llfloaterdestinations.h"
+#include "llmediactrl.h"
#include "lluictrlfactory.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
LLFloaterDestinations::LLFloaterDestinations(const LLSD& key)
@@ -43,6 +46,15 @@ LLFloaterDestinations::~LLFloaterDestinations()
bool LLFloaterDestinations::postBuild()
{
enableResizeCtrls(true, true, false);
+ LLMediaCtrl* destinations = getChild<LLMediaCtrl>("destination_guide_contents");
+ destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
+ std::string url = gSavedSettings.getString("DestinationGuideURL");
+ url = LLWeb::expandURLSubstitutions(url, LLSD());
+ destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+
+ // If cookie is there, will set it now. Otherwise will have to wait for login completion
+ // which will also update destinations instance if it already exists.
+ LLViewerMedia::getInstance()->getOpenIDCookie(destinations);
return true;
}
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
index 236aadfbc1..4843a48e66 100644
--- a/indra/newview/llfloaterdisplayname.cpp
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -56,6 +56,7 @@ private:
void onCacheSetName(bool success,
const std::string& reason,
const LLSD& content);
+ bool mIsLockedOut = false;
};
LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
@@ -72,8 +73,8 @@ void LLFloaterDisplayName::onOpen(const LLSD& key)
LLAvatarNameCache::get(gAgent.getID(), &av_name);
F64 now_secs = LLDate::now().secondsSinceEpoch();
-
- if (now_secs < av_name.mNextUpdate)
+ mIsLockedOut = now_secs < av_name.mNextUpdate;
+ if (mIsLockedOut)
{
// ...can't update until some time in the future
F64 next_update_local_secs =
@@ -167,18 +168,19 @@ void LLFloaterDisplayName::onReset()
}
getChild<LLUICtrl>("display_name_editor")->setValue(av_name.getUserName());
- if (getChild<LLUICtrl>("display_name_editor")->getEnabled())
+ if (mIsLockedOut)
{
- // UI is enabled, fill the first field
- getChild<LLUICtrl>("display_name_confirm")->clear();
- getChild<LLUICtrl>("display_name_confirm")->setFocus(true);
+ // UI is disabled.
+ // We should allow resetting even if user already
+ // set a display name, enable save button
+ getChild<LLUICtrl>("display_name_confirm")->setValue(av_name.getUserName());
+ getChild<LLUICtrl>("save_btn")->setEnabled(true);
}
else
{
- // UI is disabled, looks like we should allow resetting
- // even if user already set a display name, enable save button
- getChild<LLUICtrl>("display_name_confirm")->setValue(av_name.getUserName());
- getChild<LLUICtrl>("save_btn")->setEnabled(true);
+ // UI is enabled, focus on the confirm field
+ getChild<LLUICtrl>("display_name_confirm")->clear();
+ getChild<LLUICtrl>("display_name_confirm")->setFocus(true);
}
}
diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp
index af0ef7223d..b7f4df874c 100644
--- a/indra/newview/llfloateremojipicker.cpp
+++ b/indra/newview/llfloateremojipicker.cpp
@@ -377,6 +377,9 @@ void LLFloaterEmojiPicker::initialize()
{
if (!mHint.empty())
{
+ // Hack: Trying to open floater, search for a match,
+ // and hide floater immediately if no match found,
+ // instead of checking prior to opening
hideFloater();
return;
}
@@ -406,6 +409,12 @@ void LLFloaterEmojiPicker::initialize()
return;
}
+ if (!mHint.empty() && getSoundFlags() == LLView::SILENT)
+ {
+ // Sounds were supressed
+ make_ui_sound("UISndWindowOpen");
+ }
+
mGroups->setVisible(true);
mPreview->setIcon(nullptr);
showPreview(true);
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index d28c987414..1825797159 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -134,12 +134,15 @@ void LLFloaterFixedEnvironment::onClose(bool app_quitting)
{
doCloseInventoryFloater(app_quitting);
- LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
- LLEnvironment::instance().setCurrentEnvironmentSelection(LLEnvironment::ENV_LOCAL);
- LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+ if (!app_quitting)
+ {
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().setCurrentEnvironmentSelection(LLEnvironment::ENV_LOCAL);
+ LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
- mSettings.reset();
- syncronizeTabs();
+ mSettings.reset();
+ syncronizeTabs();
+ }
}
void LLFloaterFixedEnvironment::refresh()
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 550c3adc27..c924807273 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -267,6 +267,14 @@ void LLFloaterImagePreview::onBtnOK()
LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
+ if (mRawImagep->getWidth() * mRawImagep->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)
+ {
+ if (gSavedSettings.getBOOL("LosslessJ2CUpload"))
+ {
+ formatted->setReversible(true);
+ }
+ }
+
if (formatted->encode(mRawImagep, 0.0f))
{
LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE);
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 3d88e117ac..143781a225 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1706,6 +1706,11 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
if (session_floater)
{
session_floater->restoreFloater();
+ if (session_floater->isTornOff() && session_floater->isMinimized())
+ {
+ session_floater->setMinimized(false);
+ session_floater->setFocus(true);
+ }
}
}
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 5160ac4d34..48360f30d4 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -618,9 +618,21 @@ void LLFloaterIMSessionTab::deleteAllChildren()
std::string LLFloaterIMSessionTab::appendTime()
{
- std::string timeStr = "[" + LLTrans::getString("TimeHour") + "]:"
- "[" + LLTrans::getString("TimeMin") + "]:"
- "[" + LLTrans::getString("TimeSec") + "]";
+ std::string timeStr;
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ if (use_24h)
+ {
+ timeStr = "[" + LLTrans::getString("TimeHour") + "]:"
+ "[" + LLTrans::getString("TimeMin") + "]:"
+ "[" + LLTrans::getString("TimeSec") + "]";
+ }
+ else
+ {
+ timeStr = "[" + LLTrans::getString("TimeHour12") + "]:"
+ "[" + LLTrans::getString("TimeMin") + "]:"
+ "[" + LLTrans::getString("TimeSec") + "] ["
+ + LLTrans::getString("TimeAMPM") + "]";
+ }
LLSD substitution;
substitution["datetime"] = (S32)time_corrected();
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index 4f993ca0e1..c0fe7ad896 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -220,7 +220,8 @@ void LLFloaterInspect::refresh()
}
time_t timestamp = (time_t) (obj->mCreationDate/1000000);
- std::string timeStr = getString("timeStamp");
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ std::string timeStr = use_24h ? getString("timeStamp") : getString("timeStampAMPM");
LLSD substitution;
substitution["datetime"] = (S32) timestamp;
LLStringUtil::format (timeStr, substitution);
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 52a3e78d04..5c5219bcdd 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -733,7 +733,8 @@ void LLPanelLandGeneral::refresh()
// Display claim date
time_t claim_date = parcel->getClaimDate();
- std::string claim_date_str = getString("time_stamp_template");
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ std::string claim_date_str = use_24h ? getString("time_stamp_template") : getString("time_stamp_template_ampm");
LLSD substitution;
substitution["datetime"] = (S32) claim_date;
LLStringUtil::format (claim_date_str, substitution);
diff --git a/indra/newview/llfloatermarketplace.cpp b/indra/newview/llfloatermarketplace.cpp
index 4abea64302..7316d7617d 100644
--- a/indra/newview/llfloatermarketplace.cpp
+++ b/indra/newview/llfloatermarketplace.cpp
@@ -46,9 +46,16 @@ void LLFloaterMarketplace::onClose(bool app_quitting)
bool LLFloaterMarketplace::postBuild()
{
- LLFloaterWebContent::postBuild();
- mWebBrowser = getChild<LLMediaCtrl>("marketplace_contents");
- mWebBrowser->addObserver(this);
+ if (!LLFloaterWebContent::postBuild())
+ return false;
+
+ mWebBrowser->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
+ std::string url = gSavedSettings.getString("MarketplaceURL");
+ mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+
+ // If cookie is there, will set it now, Otherwise will have to wait for login completion
+ // which will also update marketplace instance if it already exists.
+ LLViewerMedia::getInstance()->getOpenIDCookie(mWebBrowser);
return true;
}
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index f76f39222b..ef29be8200 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1035,8 +1035,13 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data)
gMeshRepo.mDecompThread->submitRequest(request);
}
}
-
- if (stage == "Decompose")
+ if (stage == "Analyze")
+ {
+ sInstance->setStatusMessage(sInstance->getString("decomposing"));
+ sInstance->childSetVisible("Analyze", false);
+ sInstance->childSetVisible("analyze_cancel", true);
+ }
+ else if (stage == "Decompose")
{
sInstance->setStatusMessage(sInstance->getString("decomposing"));
sInstance->childSetVisible("Decompose", false);
@@ -1137,6 +1142,7 @@ void LLFloaterModelPreview::initDecompControls()
childSetCommitCallback("simplify_cancel", onPhysicsStageCancel, NULL);
childSetCommitCallback("decompose_cancel", onPhysicsStageCancel, NULL);
+ childSetCommitCallback("analyze_cancel", onPhysicsStageCancel, NULL);
childSetCommitCallback("physics_lod_combo", onPhysicsUseLOD, NULL);
childSetCommitCallback("physics_browse", onPhysicsBrowse, NULL);
@@ -2018,7 +2024,7 @@ void LLFloaterModelPreview::DecompRequest::completed()
{ //called from the main thread
if (mContinue)
{
- mModel->setConvexHullDecomposition(mHull);
+ mModel->setConvexHullDecomposition(mHull, mHullMesh);
if (sInstance)
{
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index d9753596e6..aa36782942 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -475,6 +475,8 @@ bool LLFloaterPreference::postBuild()
getChild<LLUICtrl>("log_path_string")->setEnabled(false); // make it read-only but selectable
getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
+ mTimeFormatCombobox = getChild<LLComboBox>("time_format_combobox");
+ mTimeFormatCombobox->setCommitCallback(boost::bind(&LLFloaterPreference::onTimeFormatChange, this));
getChild<LLComboBox>("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions"));
getChild<LLComboBox>("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions"));
@@ -772,6 +774,17 @@ void LLFloaterPreference::onOpen(const LLSD& key)
// Load (double-)click to walk/teleport settings.
updateClickActionViews();
+#if LL_LINUX
+ // Lixux doesn't support automatic mode
+ LLComboBox* combo = getChild<LLComboBox>("double_click_action_combo");
+ S32 mode = gSavedSettings.getS32("MouseWarpMode");
+ if (mode == 0)
+ {
+ combo->setValue("1");
+ }
+ combo->setEnabledByValue("0", false);
+#endif
+
// Enabled/disabled popups, might have been changed by user actions
// while preferences floater was closed.
buildPopupLists();
@@ -1103,6 +1116,13 @@ void LLFloaterPreference::onLanguageChange()
}
}
+void LLFloaterPreference::onTimeFormatChange()
+{
+ std::string val = mTimeFormatCombobox->getValue();
+ gSavedSettings.setBOOL("Use24HourClock", val == "1");
+ onLanguageChange();
+}
+
void LLFloaterPreference::onNotificationsChange(const std::string& OptionName)
{
mNotificationOptions[OptionName] = getChild<LLComboBox>(OptionName)->getSelectedItemLabel();
@@ -1318,6 +1338,8 @@ void LLFloaterPreference::refresh()
advanced->refresh();
}
updateClickActionViews();
+
+ mTimeFormatCombobox->selectByValue(gSavedSettings.getBOOL("Use24HourClock") ? "1" : "0");
}
void LLFloaterPreference::onCommitWindowedMode()
@@ -1356,6 +1378,7 @@ void LLFloaterPreference::onChangeQuality(const LLSD& data)
}
mLastQualityLevel = level;
LLFeatureManager::getInstance()->setGraphicsLevel(level, true);
+ gSavedSettings.setU32("DebugQualityPerformance", level);
refreshEnabledGraphics();
refresh();
}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index c93b837e82..8d3f1ed6b0 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -117,6 +117,7 @@ protected:
void onClickClearCache(); // Clear viewer texture cache, file cache on next startup
void onClickBrowserClearCache(); // Clear web history and caches as well as viewer caches above
void onLanguageChange();
+ void onTimeFormatChange();
void onNotificationsChange(const std::string& OptionName);
void onNameTagOpacityChange(const LLSD& newvalue);
@@ -235,6 +236,7 @@ private:
LLButton* mDeleteTranscriptsBtn = nullptr;
LLButton* mEnablePopupBtn = nullptr;
LLButton* mDisablePopupBtn = nullptr;
+ LLComboBox* mTimeFormatCombobox = nullptr;
std::unique_ptr< ll::prefs::SearchData > mSearchData;
bool mSearchDataDirty;
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 2d972ea3f5..7673c2bacd 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -270,10 +270,12 @@ bool LLFloaterRegionInfo::postBuild()
static LLCachedControl<bool> feature_pbr_terrain_transforms_enabled(gSavedSettings, "RenderTerrainPBRTransformsEnabled", false);
if (!feature_pbr_terrain_transforms_enabled() || !feature_pbr_terrain_enabled())
{
+ LL_INFOS("Terrain") << "Building region terrain panel from panel_region_terrain.xml" << LL_ENDL;
panel->buildFromFile("panel_region_terrain.xml");
}
else
{
+ LL_INFOS("Terrain") << "Building region terrain panel from panel_region_terrain_texture_transform.xml" << LL_ENDL;
panel->buildFromFile("panel_region_terrain_texture_transform.xml");
}
mTab->addTabPanel(panel);
@@ -1490,6 +1492,11 @@ bool LLPanelRegionTerrainInfo::validateMaterials()
const LLUUID& material_asset_id = material_ctrl->getImageAssetID();
llassert(material_asset_id.notNull());
if (material_asset_id.isNull()) { return false; }
+ if (material_asset_id == BLANK_MATERIAL_ASSET_ID)
+ {
+ // Default/Blank material is valid by default
+ continue;
+ }
const LLFetchedGLTFMaterial* material = gGLTFMaterialList.getMaterial(material_asset_id);
if (!material->isLoaded())
{
@@ -1999,18 +2006,7 @@ void LLPanelRegionTerrainInfo::initMaterialCtrl(LLTextureCtrl*& ctrl, const std:
ctrl->setCommitCallback(
[this, index](LLUICtrl* ctrl, const LLSD& param)
{
- if (!mMaterialScaleUCtrl[index]
- || !mMaterialScaleVCtrl[index]
- || !mMaterialRotationCtrl[index]
- || !mMaterialOffsetUCtrl[index]
- || !mMaterialOffsetVCtrl[index]) return;
-
- mMaterialScaleUCtrl[index]->setValue(1.f);
- mMaterialScaleVCtrl[index]->setValue(1.f);
- mMaterialRotationCtrl[index]->setValue(0.f);
- mMaterialOffsetUCtrl[index]->setValue(0.f);
- mMaterialOffsetVCtrl[index]->setValue(0.f);
- onChangeAnything();
+ callbackMaterialCommit(index);
});
}
@@ -2098,6 +2094,25 @@ bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, con
return false;
}
+void LLPanelRegionTerrainInfo::callbackMaterialCommit(S32 index)
+{
+ // These can be null if 'transforms' panel was not inited
+ if (mMaterialScaleUCtrl[index]
+ && mMaterialScaleVCtrl[index]
+ && mMaterialRotationCtrl[index]
+ && mMaterialOffsetUCtrl[index]
+ && mMaterialOffsetVCtrl[index])
+ {
+ mMaterialScaleUCtrl[index]->setValue(1.f);
+ mMaterialScaleVCtrl[index]->setValue(1.f);
+ mMaterialRotationCtrl[index]->setValue(0.f);
+ mMaterialOffsetUCtrl[index]->setValue(0.f);
+ mMaterialOffsetVCtrl[index]->setValue(0.f);
+ }
+
+ onChangeAnything();
+}
+
/////////////////////////////////////////////////////////////////////////////
// LLPanelEstateInfo
//
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index a8631c36ca..0036df9c3d 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -272,6 +272,7 @@ public:
static void onClickBakeTerrain(void*);
bool callbackBakeTerrain(const LLSD& notification, const LLSD& response);
bool callbackTextureHeights(const LLSD& notification, const LLSD& response);
+ void callbackMaterialCommit(S32 index);
protected:
bool sendUpdate() override;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 7ee1b88f05..9b7a4e5134 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -161,15 +161,20 @@ void LLFloaterSearch::initiateSearch(const LLSD& tokens)
// Naviation to the calculated URL - we know it's HTML so we can
// tell the media system not to bother with the MIME type check.
- LLMediaCtrl* search_browser = findChild<LLMediaCtrl>("search_contents");
- search_browser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+ mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
}
bool LLFloaterSearch::postBuild()
{
- LLFloaterWebContent::postBuild();
- mWebBrowser = getChild<LLMediaCtrl>("search_contents");
- mWebBrowser->addObserver(this);
+ if (!LLFloaterWebContent::postBuild())
+ return false;
+
+ mWebBrowser->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
+
+ // If cookie is there, will set it now, Otherwise will have to wait for login completion
+ // which will also update search instance if it already exists.
+ LLViewerMedia::getInstance()->getOpenIDCookie(mWebBrowser);
+
getChildView("address")->setEnabled(false);
getChildView("popexternal")->setEnabled(false);
diff --git a/indra/newview/llfloatertoybox.cpp b/indra/newview/llfloatertoybox.cpp
index f6257dbd3d..5e3ec366d5 100644
--- a/indra/newview/llfloatertoybox.cpp
+++ b/indra/newview/llfloatertoybox.cpp
@@ -63,7 +63,7 @@ bool LLFloaterToybox::postBuild()
mToolBar->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
mToolBar->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
- mToolBar->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
+ mToolBar->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4,_5));
mToolBar->setButtonEnterCallback(boost::bind(&LLFloaterToybox::onToolBarButtonEnter,this,_1));
//
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index 7651b2528f..2f1857ec61 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -242,6 +242,16 @@ void LLFloaterURLEntry::getMediaTypeCoro(std::string url, LLHandle<LLFloater> pa
resolvedMimeType = mimeType;
}
}
+ else if (resultHeaders.has(HTTP_IN_HEADER_X_CONTENT_TYPE_OPTIONS))
+ {
+ const std::string& val = resultHeaders[HTTP_IN_HEADER_X_CONTENT_TYPE_OPTIONS];
+ if (val == HTTP_NOSNIFF)
+ {
+ // Doesn't permit 'sniffing' mime type, default to either html or plain
+ // If this doesn't work user will have to choose something manually.
+ resolvedMimeType = HTTP_CONTENT_TEXT_HTML;
+ }
+ }
floaterUrlEntry->headerFetchComplete(status.getType(), resolvedMimeType);
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 8da835ed7d..3e4aadc381 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -359,6 +359,7 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L
{
if (asset_id.isNull() || override_json.empty())
{
+ // If there is no asset, there can't be an override
queueApply(obj, side, asset_id);
}
else
@@ -371,6 +372,7 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L
{
if (asset_id.isNull() || material_override == nullptr)
{
+ // If there is no asset, there can't be an override
queueApply(obj, side, asset_id);
}
else
@@ -470,7 +472,7 @@ void LLGLTFMaterialList::flushUpdatesOnce(std::shared_ptr<CallbackHolder> callba
{
data[i]["gltf_json"] = e.override_data->asJSON();
}
- if (!e.override_json.empty())
+ else if (!e.override_json.empty())
{
data[i]["gltf_json"] = e.override_json;
}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index bc89af2eed..67b62433f8 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -811,6 +811,10 @@ void LLIMModel::LLIMSession::initVoiceChannel(const LLSD& voiceChannelInfo)
{
if (mVoiceChannel)
{
+ if (!voiceChannelInfo.isMap())
+ {
+ LL_WARNS() << "initVoiceChannel called without voiceChannelInfo" << LL_ENDL;
+ }
if (mVoiceChannel->isThisVoiceChannel(voiceChannelInfo))
{
return;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index f508935799..1ec7ec85c9 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4390,6 +4390,32 @@ void LLFolderBridge::pasteLinkFromClipboard()
std::vector<LLUUID> objects;
LLClipboard::instance().pasteFromClipboard(objects);
+ if (objects.size() == 0)
+ {
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+
+ LLUUID& first_id = objects[0];
+ LLInventoryItem* item = model->getItem(first_id);
+ if (item && item->getAssetUUID().isNull())
+ {
+ if (item->getActualType() == LLAssetType::AT_NOTECARD)
+ {
+ // otehrwise AIS will return 'Cannot link to items with a NULL asset_id.'
+ LLNotificationsUtil::add("CantLinkNotecard");
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+ else if (item->getActualType() == LLAssetType::AT_MATERIAL)
+ {
+ LLNotificationsUtil::add("CantLinkMaterial");
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+ }
+
+
LLPointer<LLInventoryCallback> cb = NULL;
LLInventoryPanel* panel = mInventoryPanel.get();
if (panel->getRootFolder()->isSingleFolderMode())
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index a4cb6ea65d..c54af7d9f1 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -2120,6 +2120,30 @@ void LLInventoryGallery::pasteAsLink()
std::vector<LLUUID> objects;
LLClipboard::instance().pasteFromClipboard(objects);
+ if (objects.size() == 0)
+ {
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+
+ LLUUID& first_id = objects[0];
+ LLInventoryItem* item = gInventory.getItem(first_id);
+ if (item && item->getAssetUUID().isNull())
+ {
+ if (item->getActualType() == LLAssetType::AT_NOTECARD)
+ {
+ LLNotificationsUtil::add("CantLinkNotecard");
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+ else if (item->getActualType() == LLAssetType::AT_MATERIAL)
+ {
+ LLNotificationsUtil::add("CantLinkMaterial");
+ LLClipboard::instance().setCutMode(false);
+ return;
+ }
+ }
+
bool paste_into_root = mSelectedItemIDs.empty();
for (LLUUID& dest : mSelectedItemIDs)
{
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp
index b9d4f4471a..6bea648380 100644
--- a/indra/newview/llinventorygallerymenu.cpp
+++ b/indra/newview/llinventorygallerymenu.cpp
@@ -624,20 +624,23 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
bool has_children = false;
bool is_full_perm_item = false;
bool is_copyable = false;
- LLViewerInventoryItem* selected_item = gInventory.getItem(selected_id);
+
+ LLViewerInventoryCategory* selected_category = nullptr;
+ LLViewerInventoryItem* selected_item = nullptr;
if(is_folder)
{
- LLInventoryCategory* category = gInventory.getCategory(selected_id);
- if (category)
+ selected_category = dynamic_cast<LLViewerInventoryCategory*>(obj);
+ if (selected_category)
{
- folder_type = category->getPreferredType();
+ folder_type = selected_category->getPreferredType();
is_system_folder = LLFolderType::lookupIsProtectedType(folder_type);
has_children = (gInventory.categoryHasChildren(selected_id) != LLInventoryModel::CHILDREN_NO);
}
}
else
{
+ selected_item = dynamic_cast<LLViewerInventoryItem*>(obj);
if (selected_item)
{
is_full_perm_item = selected_item->getIsFullPerm();
@@ -756,8 +759,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
{
if (is_agent_inventory && !is_inbox && !is_cof && !is_in_favorites && !is_outfits && !is_in_outfits)
{
- LLViewerInventoryCategory* category = gInventory.getCategory(selected_id);
- if (!category || !LLFriendCardsManager::instance().isCategoryInFriendFolder(category))
+ if (!selected_category || !LLFriendCardsManager::instance().isCategoryInFriendFolder(selected_category))
{
items.push_back(std::string("New Folder"));
}
@@ -785,6 +787,22 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
if (inventory_linking)
{
items.push_back(std::string("Paste As Link"));
+
+ if (selected_item)
+ {
+ if (!LLAssetType::lookupCanLink(selected_item->getActualType()))
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
+ else if (gInventory.isObjectDescendentOf(selected_item->getUUID(), gInventory.getLibraryRootFolderID()))
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
+ }
+ else if (selected_category && LLFolderType::lookupIsProtectedType(selected_category->getPreferredType()))
+ {
+ disabled_items.push_back(std::string("Paste As Link"));
+ }
}
}
if (is_folder && is_agent_inventory)
@@ -1045,9 +1063,8 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
{
if (is_folder)
{
- LLViewerInventoryCategory* cat = gInventory.getCategory(selected_id);
- if (cat
- && !LLFolderType::lookupIsProtectedType(cat->getPreferredType())
+ if (selected_category
+ && !LLFolderType::lookupIsProtectedType(selected_category->getPreferredType())
&& gInventory.isObjectDescendentOf(selected_id, gInventory.getRootFolderID()))
{
can_list = true;
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index cfa37cc3ee..73cc953692 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -40,6 +40,10 @@
#include "llinventorymodel.h"
#include "llviewerinventory.h"
+bool LLInventoryItemsList::sListIdleRegistered = false;
+LLInventoryItemsList::all_list_t LLInventoryItemsList::sAllLists;
+LLInventoryItemsList::all_list_t::iterator LLInventoryItemsList::sAllListIter;
+
LLInventoryItemsList::Params::Params()
{}
@@ -55,13 +59,39 @@ LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p
setNoFilteredItemsMsg(LLTrans::getString("InventoryNoMatchingItems"));
- gIdleCallbacks.addFunction(idle, this);
+ sAllLists.push_back(this);
+ sAllListIter = sAllLists.begin();
+
+ if (!sListIdleRegistered)
+ {
+ sAllListIter = sAllLists.begin();
+ gIdleCallbacks.addFunction(idle, nullptr);
+
+ LLEventPumps::instance().obtain("LLApp").listen(
+ "LLInventoryItemsList",
+ [](const LLSD& stat)
+ {
+ std::string status(stat["status"]);
+ if (status != "running")
+ {
+ // viewer is starting shutdown
+ gIdleCallbacks.deleteFunction(idle, nullptr);
+ }
+ return false;
+ });
+ sListIdleRegistered = true;
+ }
}
// virtual
LLInventoryItemsList::~LLInventoryItemsList()
{
- gIdleCallbacks.deleteFunction(idle, this);
+ auto it = std::find(sAllLists.begin(), sAllLists.end(), this);
+ if (it != sAllLists.end())
+ {
+ sAllLists.erase(it);
+ sAllListIter = sAllLists.begin();
+ }
}
void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array)
@@ -111,25 +141,55 @@ void LLInventoryItemsList::updateSelection()
mSelectTheseIDs.clear();
}
-void LLInventoryItemsList::doIdle()
+bool LLInventoryItemsList::doIdle()
{
- if (mRefreshState == REFRESH_COMPLETE) return;
+ if (mRefreshState == REFRESH_COMPLETE) return true; // done
if (isInVisibleChain() || mForceRefresh || !getFilterSubString().empty())
{
refresh();
mRefreshCompleteSignal(this, LLSD());
+ return false; // keep going
}
+ return true; // done
}
//static
void LLInventoryItemsList::idle(void* user_data)
{
- LLInventoryItemsList* self = static_cast<LLInventoryItemsList*>(user_data);
- if ( self )
- { // Do the real idle
- self->doIdle();
+ if (sAllLists.empty())
+ return;
+
+ LL_PROFILE_ZONE_SCOPED;
+
+ using namespace std::chrono;
+ auto start = steady_clock::now();
+ const milliseconds time_limit = milliseconds(3);
+ const auto end_time = start + time_limit;
+ S32 max_update_count = 50;
+
+ if (sAllListIter == sAllLists.end())
+ {
+ sAllListIter = sAllLists.begin();
+ }
+
+ S32 updated = 0;
+ while (steady_clock::now() < end_time
+ && updated < max_update_count
+ && sAllListIter != sAllLists.end())
+ {
+ LLInventoryItemsList* list = *sAllListIter;
+ // Refresh is split into multiple separate parts,
+ // so keep repeating it while there is time, until done.
+ // Todo: refresh() split is pointless now?
+ // Or still useful for large folders?
+ if (list->doIdle())
+ {
+ // Item is done
+ ++sAllListIter;
+ updated++;
+ }
}
}
@@ -141,6 +201,7 @@ void LLInventoryItemsList::refresh()
{
case REFRESH_ALL:
{
+ LL_PROFILE_ZONE_NAMED("items_refresh_all");
mAddedItems.clear();
mRemovedItems.clear();
computeDifference(getIDs(), mAddedItems, mRemovedItems);
@@ -163,6 +224,7 @@ void LLInventoryItemsList::refresh()
}
case REFRESH_LIST_ERASE:
{
+ LL_PROFILE_ZONE_NAMED("items_refresh_erase");
uuid_vec_t::const_iterator it = mRemovedItems.begin();
for (; mRemovedItems.end() != it; ++it)
{
@@ -175,6 +237,7 @@ void LLInventoryItemsList::refresh()
}
case REFRESH_LIST_APPEND:
{
+ LL_PROFILE_ZONE_NAMED("items_refresh_append");
static const unsigned ADD_LIMIT = 25; // Note: affects perfomance
unsigned int nadded = 0;
@@ -239,6 +302,7 @@ void LLInventoryItemsList::refresh()
}
case REFRESH_LIST_SORT:
{
+ LL_PROFILE_ZONE_NAMED("items_refresh_sort");
// Filter, sort, rearrange and notify parent about shape changes
filterItems(true, true);
@@ -255,7 +319,10 @@ void LLInventoryItemsList::refresh()
break;
}
default:
- break;
+ {
+ mRefreshState = REFRESH_COMPLETE;
+ break;
+ }
}
setForceRefresh(mRefreshState != REFRESH_COMPLETE);
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index 9ebeb5e52b..b20c27eec8 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -59,7 +59,10 @@ public:
* Sets the flag indicating that the list needs to be refreshed even if it is
* not currently visible.
*/
- void setForceRefresh(bool force_refresh) { mForceRefresh = force_refresh; }
+ void setForceRefresh(bool force_refresh)
+ {
+ mForceRefresh = force_refresh;
+ }
/**
* If refreshes when invisible.
@@ -76,7 +79,7 @@ public:
* This is needed for example to filter items of the list hidden by closed
* accordion tab.
*/
- virtual void doIdle(); // Real idle routine
+ bool doIdle(); // Real idle routine
static void idle(void* user_data); // static glue to doIdle()
protected:
@@ -126,6 +129,12 @@ private:
bool mForceRefresh;
commit_signal_t mRefreshCompleteSignal;
+
+ // Update synchronization
+ typedef std::vector<LLInventoryItemsList*> all_list_t;
+ static all_list_t sAllLists;
+ static all_list_t::iterator sAllListIter;
+ static bool sListIdleRegistered;
};
#endif //LL_LLINVENTORYITEMSLIST_H
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index a99c9df0ff..6e56aac270 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -219,7 +219,10 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
LLPointer<LLViewerFetchedTexture> texture = new LLViewerFetchedTexture
("file://"+mFilename, FTT_LOCAL_FILE, mWorldID, LL_LOCAL_USE_MIPMAPS);
- texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image);
+ if (!texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image))
+ {
+ LL_WARNS() << "Failed to create GL texture for local bitmap: " << mFilename << " " << mWorldID << LL_ENDL;
+ }
texture->ref();
gTextureList.addImage(texture, TEX_LIST_STANDARD);
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 999f431bd6..1a07efe25d 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -80,8 +80,8 @@ const static std::string MULTI_LINE_PREFIX(" ");
*
* Note: "You" was used as an avatar names in viewers of previous versions
*/
-const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}:\\d{2}\\]\\s+|\\[\\d{1,2}:\\d{2}\\]\\s+)?(.*)$");
-const static boost::regex TIMESTAMP("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]|\\[\\d{1,2}:\\d{2}\\]).*");
+const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}:\\d{2}\\s[AaPp][Mm]\\]\\s+|\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}:\\d{2}\\]\\s+|\\[\\d{1,2}:\\d{2}:\\d{2}\\s[AaPp][Mm]\\]\\s+|\\[\\d{1,2}:\\d{2}\\]\\s+)?(.*)$");
+const static boost::regex TIMESTAMP("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}(\\s[AaPp][Mm])?\\]|\\[\\d{1,2}:\\d{2}(\\s[AaPp][Mm])?\\]).*");
/**
* Regular expression suitable to match names like
@@ -152,6 +152,10 @@ public:
void checkAndCutOffDate(std::string& time_str)
{
+ if (time_str.size() < 10) // not enough space for a date
+ {
+ return;
+ }
// Cuts off the "%Y/%m/%d" from string for todays timestamps.
// Assume that passed string has at least "%H:%M" time format.
date log_date(not_a_date_time);
@@ -168,20 +172,12 @@ public:
if ( days_alive == zero_days )
{
- // Yep, today's so strip "%Y/%m/%d" info
- ptime stripped_time(not_a_date_time);
-
- mTimeStream.str(LLStringUtil::null);
- mTimeStream << time_str;
- mTimeStream >> stripped_time;
- mTimeStream.clear();
-
- time_str.clear();
-
- mTimeStream.str(LLStringUtil::null);
- mTimeStream << stripped_time;
- mTimeStream >> time_str;
- mTimeStream.clear();
+ size_t pos = time_str.find_first_of(' ');
+ if (pos != std::string::npos)
+ {
+ time_str.erase(0, pos + 1);
+ LLStringUtil::trim(time_str);
+ }
}
LL_DEBUGS("LLChatLogParser")
@@ -310,18 +306,24 @@ std::string LLLogChat::timestamp2LogString(U32 timestamp, bool withdate)
std::string timeStr;
if (withdate)
{
- timeStr = "[" + LLTrans::getString ("TimeYear") + "]/["
- + LLTrans::getString ("TimeMonth") + "]/["
- + LLTrans::getString ("TimeDay") + "] ["
- + LLTrans::getString ("TimeHour") + "]:["
- + LLTrans::getString ("TimeMin") + "]:["
- + LLTrans::getString ("TimeSec") + "]";
+ timeStr = "[" + LLTrans::getString("TimeYear") + "]/["
+ + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "] ";
+ }
+
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ if (use_24h)
+ {
+ timeStr += "[" + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]:["
+ + LLTrans::getString("TimeSec") + "]";
}
else
{
- timeStr = "[" + LLTrans::getString("TimeHour") + "]:["
- + LLTrans::getString ("TimeMin")+"]:["
- + LLTrans::getString ("TimeSec")+"]";
+ timeStr += "[" + LLTrans::getString("TimeHour12") + "]:["
+ + LLTrans::getString("TimeMin") + "]:["
+ + LLTrans::getString("TimeSec") + "] ["
+ + LLTrans::getString("TimeAMPM") + "]";
}
LLSD substitution;
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 4bffe7feac..41cec4f074 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -62,7 +62,7 @@
const S32 LOGIN_MAX_RETRIES = 0; // Viewer should not autmatically retry login
const F32 LOGIN_SRV_TIMEOUT_MIN = 10;
-const F32 LOGIN_SRV_TIMEOUT_MAX = 120;
+const F32 LOGIN_SRV_TIMEOUT_MAX = 180;
const F32 LOGIN_DNS_TIMEOUT_FACTOR = 0.9; // make DNS wait shorter then retry time
class LLLoginInstance::Disposable {
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 8d5f94cdbb..413f02b723 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -256,6 +256,7 @@
// mDecompositionRequests mMutex rw.repo.mMutex, ro.repo.none [5]
// mPhysicsShapeRequests mMutex rw.repo.mMutex, ro.repo.none [5]
// mDecompositionQ mMutex rw.repo.mLoadedMutex, rw.main.mLoadedMutex [5] (was: [0])
+// mPhysicsQ mMutex rw.repo.mLoadedMutex, rw.main.mLoadedMutex [5] (was: [0])
// mHeaderReqQ mMutex ro.repo.none [5], rw.repo.mMutex, rw.any.mMutex
// mLODReqQ mMutex ro.repo.none [5], rw.repo.mMutex, rw.any.mMutex
// mUnavailableQ mMutex rw.repo.none [0], ro.main.none [5], rw.main.mLoadedMutex
@@ -982,6 +983,12 @@ LLMeshRepoThread::~LLMeshRepoThread()
mDecompositionQ.pop_front();
}
+ while (!mPhysicsQ.empty())
+ {
+ delete mPhysicsQ.front();
+ mPhysicsQ.pop_front();
+ }
+
delete mHttpRequest;
mHttpRequest = nullptr;
delete mMutex;
@@ -2565,12 +2572,12 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_
{
LLMutexLock lock(mLoadedMutex);
- mDecompositionQ.push_back(d);
+ mPhysicsQ.push_back(d);
}
return MESH_OK;
}
-LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, const LLMeshUploadThread::lod_sources_map_t& sources_list,
+LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list_t& data, const LLMeshUploadThread::lod_sources_map_t& sources_list,
LLVector3& scale, bool upload_textures,
bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
const std::string & upload_url, LLUUID destination_folder_id, bool do_upload,
@@ -2652,7 +2659,7 @@ void LLMeshUploadThread::DecompRequest::completed()
void LLMeshUploadThread::preStart()
{
//build map of LLModel refs to instances for callbacks
- for (instance_list::iterator iter = mInstanceList.begin(); iter != mInstanceList.end(); ++iter)
+ for (instance_list_t::iterator iter = mInstanceList.begin(); iter != mInstanceList.end(); ++iter)
{
mInstance[iter->mModel].push_back(*iter);
}
@@ -2701,6 +2708,179 @@ LLSD llsd_from_file(std::string filename)
return result;
}
+void LLMeshUploadThread::packModelIntance(
+ LLModel* model,
+ LLMeshUploadThread::instance_list_t& instance_list,
+ std::string& model_name,
+ LLSD& res,
+ S32& mesh_num,
+ S32& texture_num,
+ S32& instance_num,
+ std::unordered_set<LLViewerTexture* >& textures,
+ std::unordered_map<LLViewerTexture*, S32> texture_index,
+ std::unordered_map<LLModel*, S32>& mesh_index,
+ std::vector<std::string>& texture_list_dest,
+ bool include_textures
+ )
+{
+ LLMeshUploadData data;
+ data.mBaseModel = model;
+
+ LLModelInstance& first_instance = *(instance_list.begin());
+ for (S32 i = 0; i < 5; i++)
+ {
+ data.mModel[i] = first_instance.mLOD[i];
+ }
+
+ if (mesh_index.find(data.mBaseModel) == mesh_index.end())
+ {
+ // Have not seen this model before - create a new mesh_list entry for it.
+ if (model_name.empty())
+ {
+ model_name = data.mBaseModel->getName();
+ }
+
+ std::stringstream ostr;
+
+ LLModel::Decomposition& decomp =
+ data.mModel[LLModel::LOD_PHYSICS].notNull() ?
+ data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
+ data.mBaseModel->mPhysics;
+
+ decomp.mBaseHull = mHullMap[data.mBaseModel];
+
+ LLSD mesh_header = LLModel::writeModel(
+ ostr,
+ data.mModel[LLModel::LOD_PHYSICS],
+ data.mModel[LLModel::LOD_HIGH],
+ data.mModel[LLModel::LOD_MEDIUM],
+ data.mModel[LLModel::LOD_LOW],
+ data.mModel[LLModel::LOD_IMPOSTOR],
+ decomp,
+ mUploadSkin,
+ mUploadJoints,
+ mLockScaleIfJointPosition,
+ LLModel::WRITE_BINARY,
+ false,
+ data.mBaseModel->mSubmodelID);
+
+ data.mAssetData = ostr.str();
+ std::string str = ostr.str();
+
+ res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(), str.end());
+ mesh_index[data.mBaseModel] = mesh_num;
+ mesh_num++;
+ }
+
+ // For all instances that use this model
+ for (instance_list_t::iterator instance_iter = instance_list.begin();
+ instance_iter != instance_list.end();
+ ++instance_iter)
+ {
+ LLModelInstance& instance = *instance_iter;
+
+ LLSD instance_entry;
+
+ for (S32 i = 0; i < 5; i++)
+ {
+ data.mModel[i] = instance.mLOD[i];
+ }
+
+ LLVector3 pos, scale;
+ LLQuaternion rot;
+ LLMatrix4 transformation = instance.mTransform;
+ decomposeMeshMatrix(transformation, pos, rot, scale);
+ instance_entry["position"] = ll_sd_from_vector3(pos);
+ instance_entry["rotation"] = ll_sd_from_quaternion(rot);
+ instance_entry["scale"] = ll_sd_from_vector3(scale);
+
+ instance_entry["material"] = LL_MCODE_WOOD;
+ if (model->mSubmodelID)
+ {
+ // Should it really be different?
+ instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_NONE);
+ }
+ else
+ {
+ instance_entry["physics_shape_type"] = data.mModel[LLModel::LOD_PHYSICS].notNull() ? (U8)(LLViewerObject::PHYSICS_SHAPE_PRIM) : (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
+ }
+ instance_entry["mesh"] = mesh_index[data.mBaseModel];
+ instance_entry["mesh_name"] = instance.mLabel;
+
+ instance_entry["face_list"] = LLSD::emptyArray();
+
+ // We want to be able to allow more than 8 materials...
+ //
+ S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), instance.mModel->getNumVolumeFaces());
+
+ for (S32 face_num = 0; face_num < end; face_num++)
+ {
+ // multiple faces can reuse the same material
+ LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
+ LLSD face_entry = LLSD::emptyMap();
+
+ LLViewerFetchedTexture* texture = NULL;
+
+ if (material.mDiffuseMapFilename.size())
+ {
+ texture = FindViewerTexture(material);
+ }
+
+ if ((texture != NULL) &&
+ (textures.find(texture) == textures.end()))
+ {
+ textures.insert(texture);
+ }
+
+ std::stringstream texture_str;
+ if (texture != NULL && include_textures && mUploadTextures)
+ {
+ if (texture->hasSavedRawImage())
+ {
+ LLImageDataLock lock(texture->getSavedRawImage());
+
+ LLPointer<LLImageJ2C> upload_file =
+ LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
+
+ if (!upload_file.isNull() && upload_file->getDataSize() && !upload_file->isBufferInvalid())
+ {
+ texture_str.write((const char*)upload_file->getData(), upload_file->getDataSize());
+ }
+ }
+ }
+
+ if (texture != NULL &&
+ mUploadTextures &&
+ texture_index.find(texture) == texture_index.end())
+ {
+ texture_index[texture] = texture_num;
+ std::string str = texture_str.str();
+ res["texture_list"][texture_num] = LLSD::Binary(str.begin(), str.end());
+ // store indexes for error handling;
+ texture_list_dest.push_back(material.mDiffuseMapFilename);
+ texture_num++;
+ }
+
+ // Subset of TextureEntry fields.
+ if (texture != NULL && mUploadTextures)
+ {
+ face_entry["image"] = texture_index[texture];
+ face_entry["scales"] = 1.0;
+ face_entry["scalet"] = 1.0;
+ face_entry["offsets"] = 0.0;
+ face_entry["offsett"] = 0.0;
+ face_entry["imagerot"] = 0.0;
+ }
+ face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor);
+ face_entry["fullbright"] = material.mFullbright;
+ instance_entry["face_list"][face_num] = face_entry;
+ }
+
+ res["instance_list"][instance_num] = instance_entry;
+ instance_num++;
+ }
+}
+
void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector<std::string>& texture_list_dest, bool include_textures)
{
LLSD result;
@@ -2734,6 +2914,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector<std::string>&
}
S32 mesh_num = 0;
S32 texture_num = 0;
+ S32 instance_num = 0;
std::unordered_set<LLViewerTexture* > textures;
std::unordered_map<LLViewerTexture*,S32> texture_index;
@@ -2741,7 +2922,34 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector<std::string>&
std::unordered_map<LLModel*,S32> mesh_index;
std::string model_name;
- S32 instance_num = 0;
+ // If server gets a m1, m2, m3, m4 list, m1 becomes the root
+ // and the rest go as m4, m3, m2
+ // to counter that mInstance is sorted as m4, m3, m2, m1
+ // and we grab m1 from the end and send it first
+ LLModel* root_model = nullptr;
+ for (instance_map_t::reverse_iterator iter = mInstance.rbegin(); iter != mInstance.rend(); ++iter)
+ {
+ if (iter->first->mSubmodelID)
+ {
+ // Submodel can't be root
+ continue;
+ }
+ root_model = iter->first;
+ packModelIntance(
+ iter->first,
+ iter->second,
+ model_name,
+ res,
+ mesh_num,
+ texture_num,
+ instance_num,
+ textures,
+ texture_index,
+ mesh_index,
+ texture_list_dest,
+ include_textures);
+ break;
+ }
// Handle models, ignore submodels for now.
// Probably should pre-sort by mSubmodelID instead of running twice.
@@ -2749,319 +2957,53 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector<std::string>&
// deterministic order.
for (auto& iter : mInstance)
{
- LLMeshUploadData data;
- data.mBaseModel = iter.first;
-
- if (data.mBaseModel->mSubmodelID)
+ if (iter.first->mSubmodelID)
{
// These are handled below to insure correct parenting order on creation
// due to map walking being based on model address (aka random)
continue;
}
-
- LLModelInstance& first_instance = *(iter.second.begin());
- for (S32 i = 0; i < 5; i++)
- {
- data.mModel[i] = first_instance.mLOD[i];
- }
-
- if (mesh_index.find(data.mBaseModel) == mesh_index.end())
- {
- // Have not seen this model before - create a new mesh_list entry for it.
- if (model_name.empty())
- {
- model_name = data.mBaseModel->getName();
- }
-
- std::stringstream ostr;
-
- LLModel::Decomposition& decomp =
- data.mModel[LLModel::LOD_PHYSICS].notNull() ?
- data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
- data.mBaseModel->mPhysics;
-
- decomp.mBaseHull = mHullMap[data.mBaseModel];
-
- LLSD mesh_header = LLModel::writeModel(
- ostr,
- data.mModel[LLModel::LOD_PHYSICS],
- data.mModel[LLModel::LOD_HIGH],
- data.mModel[LLModel::LOD_MEDIUM],
- data.mModel[LLModel::LOD_LOW],
- data.mModel[LLModel::LOD_IMPOSTOR],
- decomp,
- mUploadSkin,
- mUploadJoints,
- mLockScaleIfJointPosition,
- LLModel::WRITE_BINARY,
- false,
- data.mBaseModel->mSubmodelID);
-
- data.mAssetData = ostr.str();
- std::string str = ostr.str();
-
- res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());
- mesh_index[data.mBaseModel] = mesh_num;
- mesh_num++;
- }
-
- // For all instances that use this model
- for (instance_list::iterator instance_iter = iter.second.begin();
- instance_iter != iter.second.end();
- ++instance_iter)
+ if (root_model == iter.first)
{
-
- LLModelInstance& instance = *instance_iter;
-
- LLSD instance_entry;
-
- for (S32 i = 0; i < 5; i++)
- {
- data.mModel[i] = instance.mLOD[i];
- }
-
- LLVector3 pos, scale;
- LLQuaternion rot;
- LLMatrix4 transformation = instance.mTransform;
- decomposeMeshMatrix(transformation,pos,rot,scale);
- instance_entry["position"] = ll_sd_from_vector3(pos);
- instance_entry["rotation"] = ll_sd_from_quaternion(rot);
- instance_entry["scale"] = ll_sd_from_vector3(scale);
-
- instance_entry["material"] = LL_MCODE_WOOD;
- instance_entry["physics_shape_type"] = data.mModel[LLModel::LOD_PHYSICS].notNull() ? (U8)(LLViewerObject::PHYSICS_SHAPE_PRIM) : (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
- instance_entry["mesh"] = mesh_index[data.mBaseModel];
- instance_entry["mesh_name"] = instance.mLabel;
-
- instance_entry["face_list"] = LLSD::emptyArray();
-
- // We want to be able to allow more than 8 materials...
- //
- S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), instance.mModel->getNumVolumeFaces()) ;
-
- for (S32 face_num = 0; face_num < end; face_num++)
- {
- // multiple faces can reuse the same material
- LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
- LLSD face_entry = LLSD::emptyMap();
-
- LLViewerFetchedTexture *texture = NULL;
-
- if (material.mDiffuseMapFilename.size())
- {
- texture = FindViewerTexture(material);
- }
-
- if ((texture != NULL) &&
- (textures.find(texture) == textures.end()))
- {
- textures.insert(texture);
- }
-
- std::stringstream texture_str;
- if (texture != NULL && include_textures && mUploadTextures)
- {
- if (texture->hasSavedRawImage())
- {
- LLImageDataLock lock(texture->getSavedRawImage());
-
- LLPointer<LLImageJ2C> upload_file =
- LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
-
- if (!upload_file.isNull() && upload_file->getDataSize() && !upload_file->isBufferInvalid())
- {
- texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
- }
- }
- }
-
- if (texture != NULL &&
- mUploadTextures &&
- texture_index.find(texture) == texture_index.end())
- {
- texture_index[texture] = texture_num;
- std::string str = texture_str.str();
- res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
- // store indexes for error handling;
- texture_list_dest.push_back(material.mDiffuseMapFilename);
- texture_num++;
- }
-
- // Subset of TextureEntry fields.
- if (texture != NULL && mUploadTextures)
- {
- face_entry["image"] = texture_index[texture];
- face_entry["scales"] = 1.0;
- face_entry["scalet"] = 1.0;
- face_entry["offsets"] = 0.0;
- face_entry["offsett"] = 0.0;
- face_entry["imagerot"] = 0.0;
- }
- face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor);
- face_entry["fullbright"] = material.mFullbright;
- instance_entry["face_list"][face_num] = face_entry;
- }
-
- res["instance_list"][instance_num] = instance_entry;
- instance_num++;
+ // Reached root, root was already packed and is last non-submodel
+ break;
}
+ packModelIntance(
+ iter.first,
+ iter.second,
+ model_name,
+ res,
+ mesh_num,
+ texture_num,
+ instance_num,
+ textures,
+ texture_index,
+ mesh_index,
+ texture_list_dest,
+ include_textures);
}
// Now handle the submodels.
for (auto& iter : mInstance)
{
- LLMeshUploadData data;
- data.mBaseModel = iter.first;
-
- if (!data.mBaseModel->mSubmodelID)
+ if (!iter.first->mSubmodelID)
{
// These were handled above already...
- //
continue;
}
-
- LLModelInstance& first_instance = *(iter.second.begin());
- for (S32 i = 0; i < 5; i++)
- {
- data.mModel[i] = first_instance.mLOD[i];
- }
-
- if (mesh_index.find(data.mBaseModel) == mesh_index.end())
- {
- // Have not seen this model before - create a new mesh_list entry for it.
- if (model_name.empty())
- {
- model_name = data.mBaseModel->getName();
- }
-
- std::stringstream ostr;
-
- LLModel::Decomposition& decomp =
- data.mModel[LLModel::LOD_PHYSICS].notNull() ?
- data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
- data.mBaseModel->mPhysics;
-
- decomp.mBaseHull = mHullMap[data.mBaseModel];
-
- LLSD mesh_header = LLModel::writeModel(
- ostr,
- data.mModel[LLModel::LOD_PHYSICS],
- data.mModel[LLModel::LOD_HIGH],
- data.mModel[LLModel::LOD_MEDIUM],
- data.mModel[LLModel::LOD_LOW],
- data.mModel[LLModel::LOD_IMPOSTOR],
- decomp,
- mUploadSkin,
- mUploadJoints,
- mLockScaleIfJointPosition,
- LLModel::WRITE_BINARY,
- false,
- data.mBaseModel->mSubmodelID);
-
- data.mAssetData = ostr.str();
- std::string str = ostr.str();
-
- res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());
- mesh_index[data.mBaseModel] = mesh_num;
- mesh_num++;
- }
-
- // For all instances that use this model
- for (instance_list::iterator instance_iter = iter.second.begin();
- instance_iter != iter.second.end();
- ++instance_iter)
- {
-
- LLModelInstance& instance = *instance_iter;
-
- LLSD instance_entry;
-
- for (S32 i = 0; i < 5; i++)
- {
- data.mModel[i] = instance.mLOD[i];
- }
-
- LLVector3 pos, scale;
- LLQuaternion rot;
- LLMatrix4 transformation = instance.mTransform;
- decomposeMeshMatrix(transformation,pos,rot,scale);
- instance_entry["position"] = ll_sd_from_vector3(pos);
- instance_entry["rotation"] = ll_sd_from_quaternion(rot);
- instance_entry["scale"] = ll_sd_from_vector3(scale);
-
- instance_entry["material"] = LL_MCODE_WOOD;
- instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_NONE);
- instance_entry["mesh"] = mesh_index[data.mBaseModel];
-
- instance_entry["face_list"] = LLSD::emptyArray();
-
- // We want to be able to allow more than 8 materials...
- //
- S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ;
-
- for (S32 face_num = 0; face_num < end; face_num++)
- {
- LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]];
- LLSD face_entry = LLSD::emptyMap();
-
- LLViewerFetchedTexture *texture = NULL;
-
- if (material.mDiffuseMapFilename.size())
- {
- texture = FindViewerTexture(material);
- }
-
- if ((texture != NULL) &&
- (textures.find(texture) == textures.end()))
- {
- textures.insert(texture);
- }
-
- std::stringstream texture_str;
- if (texture != NULL && include_textures && mUploadTextures)
- {
- if (texture->hasSavedRawImage())
- {
- LLImageDataLock lock(texture->getSavedRawImage());
-
- LLPointer<LLImageJ2C> upload_file =
- LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage());
-
- if (!upload_file.isNull() && upload_file->getDataSize())
- {
- texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
- }
- }
- }
-
- if (texture != NULL &&
- mUploadTextures &&
- texture_index.find(texture) == texture_index.end())
- {
- texture_index[texture] = texture_num;
- std::string str = texture_str.str();
- res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
- texture_num++;
- }
-
- // Subset of TextureEntry fields.
- if (texture != NULL && mUploadTextures)
- {
- face_entry["image"] = texture_index[texture];
- face_entry["scales"] = 1.0;
- face_entry["scalet"] = 1.0;
- face_entry["offsets"] = 0.0;
- face_entry["offsett"] = 0.0;
- face_entry["imagerot"] = 0.0;
- }
- face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor);
- face_entry["fullbright"] = material.mFullbright;
- instance_entry["face_list"][face_num] = face_entry;
- }
-
- res["instance_list"][instance_num] = instance_entry;
- instance_num++;
- }
+ packModelIntance(
+ iter.first,
+ iter.second,
+ model_name,
+ res,
+ mesh_num,
+ texture_num,
+ instance_num,
+ textures,
+ texture_index,
+ mesh_index,
+ texture_list_dest,
+ include_textures);
}
if (model_name.empty()) model_name = "mesh model";
@@ -3077,7 +3019,7 @@ void LLMeshUploadThread::generateHulls()
{
bool has_valid_requests = false ;
- for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
+ for (instance_map_t::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
{
LLMeshUploadData data;
data.mBaseModel = iter->first;
@@ -3441,13 +3383,14 @@ void LLMeshRepoThread::notifyLoadedMeshes()
}
}
- if (!mSkinInfoQ.empty() || !mSkinUnavailableQ.empty() || ! mDecompositionQ.empty())
+ if (!mSkinInfoQ.empty() || !mSkinUnavailableQ.empty() || !mDecompositionQ.empty() || !mPhysicsQ.empty())
{
if (mLoadedMutex->trylock())
{
std::deque<LLPointer<LLMeshSkinInfo>> skin_info_q;
std::deque<UUIDBasedRequest> skin_info_unavail_q;
std::list<LLModel::Decomposition*> decomp_q;
+ std::list<LLModel::Decomposition*> physics_q;
if (! mSkinInfoQ.empty())
{
@@ -3464,6 +3407,11 @@ void LLMeshRepoThread::notifyLoadedMeshes()
decomp_q.swap(mDecompositionQ);
}
+ if (!mPhysicsQ.empty())
+ {
+ physics_q.swap(mPhysicsQ);
+ }
+
mLoadedMutex->unlock();
// Process the elements free of the lock
@@ -3480,9 +3428,15 @@ void LLMeshRepoThread::notifyLoadedMeshes()
while (! decomp_q.empty())
{
- gMeshRepo.notifyDecompositionReceived(decomp_q.front());
+ gMeshRepo.notifyDecompositionReceived(decomp_q.front(), false);
decomp_q.pop_front();
}
+
+ while (!physics_q.empty())
+ {
+ gMeshRepo.notifyDecompositionReceived(physics_q.front(), true);
+ physics_q.pop_front();
+ }
}
}
@@ -4724,13 +4678,13 @@ void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id)
}
}
-void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decomp)
+void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decomp, bool physics_mesh)
{
- decomposition_map::iterator iter = mDecompositionMap.find(decomp->mMeshID);
+ LLUUID decomp_id = decomp->mMeshID; // Copy to avoid invalidation in below deletion
+ decomposition_map::iterator iter = mDecompositionMap.find(decomp_id);
if (iter == mDecompositionMap.end())
{ //just insert decomp into map
- mDecompositionMap[decomp->mMeshID] = decomp;
- mLoadingDecompositions.erase(decomp->mMeshID);
+ mDecompositionMap[decomp_id] = decomp;
sCacheBytesDecomps += decomp->sizeBytes();
}
else
@@ -4738,10 +4692,17 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
sCacheBytesDecomps -= iter->second->sizeBytes();
iter->second->merge(decomp);
sCacheBytesDecomps += iter->second->sizeBytes();
-
- mLoadingDecompositions.erase(decomp->mMeshID);
delete decomp;
}
+
+ if (physics_mesh)
+ {
+ mLoadingPhysicsShapes.erase(decomp_id);
+ }
+ else
+ {
+ mLoadingDecompositions.erase(decomp_id);
+ }
}
void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume, S32 lod)
@@ -4888,7 +4849,6 @@ void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id)
std::unordered_set<LLUUID>::iterator iter = mLoadingPhysicsShapes.find(mesh_id);
if (iter == mLoadingPhysicsShapes.end())
{ //no request pending for this skin info
- // *FIXME: Nothing ever deletes entries, can't be right
mLoadingPhysicsShapes.insert(mesh_id);
mPendingPhysicsShapeRequests.push(mesh_id);
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index ab17b921d6..01b51e753e 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -521,6 +521,9 @@ public:
// list of completed Decomposition info requests
std::list<LLModel::Decomposition*> mDecompositionQ;
+ // list of completed Physics Mesh info requests
+ std::list<LLModel::Decomposition*> mPhysicsQ;
+
//queue of requested headers
std::queue<HeaderRequest> mHeaderReqQ;
@@ -668,11 +671,11 @@ public:
LLPointer<DecompRequest> mFinalDecomp;
volatile bool mPhysicsComplete;
- typedef std::map<LLPointer<LLModel>, std::vector<LLVector3> > hull_map;
- hull_map mHullMap;
+ typedef std::map<LLPointer<LLModel>, std::vector<LLVector3> > hull_map_t;
+ hull_map_t mHullMap;
- typedef std::vector<LLModelInstance> instance_list;
- instance_list mInstanceList;
+ typedef std::vector<LLModelInstance> instance_list_t;
+ instance_list_t mInstanceList;
// Upload should happen in deterministic order, so sort instances by model name.
struct LLUploadModelInstanceLess
@@ -686,11 +689,11 @@ public:
}
// Note: probably can sort by mBaseModel->mSubmodelID here as well to avoid
// running over the list twice in wholeModelToLLSD.
- return a->mLabel < b->mLabel;
+ return a->mLabel > b->mLabel;
}
};
- typedef std::map<LLPointer<LLModel>, instance_list, LLUploadModelInstanceLess> instance_map;
- instance_map mInstance;
+ typedef std::map<LLPointer<LLModel>, instance_list_t, LLUploadModelInstanceLess> instance_map_t;
+ instance_map_t mInstance;
typedef std::map<std::string, std::string> lod_sources_map_t;
lod_sources_map_t mLodSources;
@@ -709,7 +712,7 @@ public:
std::string mWholeModelUploadURL;
LLUUID mDestinationFolderId;
- LLMeshUploadThread(instance_list& data, const lod_sources_map_t& sources_list,
+ LLMeshUploadThread(instance_list_t& data, const lod_sources_map_t& sources_list,
LLVector3& scale, bool upload_textures,
bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
const std::string & upload_url,
@@ -745,6 +748,22 @@ public:
static LLViewerFetchedTexture* FindViewerTexture(const LLImportMaterial& material);
+protected:
+ void packModelIntance(
+ LLModel* model,
+ LLMeshUploadThread::instance_list_t& instance_list,
+ std::string& model_name,
+ LLSD& res,
+ S32& mesh_num,
+ S32& texture_num,
+ S32& instance_num,
+ std::unordered_set<LLViewerTexture* > &textures,
+ std::unordered_map<LLViewerTexture*, S32> texture_index,
+ std::unordered_map<LLModel*, S32>& mesh_index,
+ std::vector<std::string>& texture_list_dest,
+ bool include_textures
+ );
+
private:
LLHandle<LLWholeModelFeeObserver> mFeeObserverHandle;
LLHandle<LLWholeModelUploadObserver> mUploadObserverHandle;
@@ -855,7 +874,7 @@ public:
void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 request_lod, S32 volume_lod);
void notifySkinInfoReceived(LLMeshSkinInfo* info);
void notifySkinInfoUnavailable(const LLUUID& info);
- void notifyDecompositionReceived(LLModel::Decomposition* info);
+ void notifyDecompositionReceived(LLModel::Decomposition* info, bool physics_mesh);
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
static S32 getActualMeshLOD(LLMeshHeader& header, S32 lod);
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 887d53b918..6a7c25ec0f 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -576,7 +576,7 @@ void LLModelPreview::rebuildUploadData()
for (U32 model_ind = 0; model_ind < mModel[lod].size(); ++model_ind)
{
bool found_model = false;
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
LLModelInstance& instance = *iter;
if (instance.mLOD[lod] == mModel[lod][model_ind])
@@ -2209,7 +2209,7 @@ void LLModelPreview::updateStatusMessages()
total_submeshes[i] = 0;
}
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
LLModelInstance& instance = *iter;
@@ -2626,7 +2626,16 @@ void LLModelPreview::updateStatusMessages()
//enable = enable && !use_hull && fmp->childGetValue("physics_optimize").asBoolean();
//enable/disable "analysis" UI
- LLPanel* panel = fmp->getChild<LLPanel>("physics analysis");
+#if LL_HAVOK
+ LLPanel* panel = fmp->getChild<LLPanel>("physics simplification");
+ panel->setVisible(true);
+
+ panel = fmp->getChild<LLPanel>("physics analysis havok");
+ panel->setVisible(true);
+#else
+ LLPanel* panel = fmp->getChild<LLPanel>("physics analysis vhacd");
+ panel->setVisible(true);
+#endif
LLView* child = panel->getFirstChild();
while (child)
{
@@ -2650,6 +2659,8 @@ void LLModelPreview::updateStatusMessages()
fmp->childSetVisible("simplify_cancel", false);
fmp->childSetVisible("Decompose", true);
fmp->childSetVisible("decompose_cancel", false);
+ fmp->childSetVisible("Analyze", true);
+ fmp->childSetVisible("analyze_cancel", false);
if (phys_hulls > 0)
{
@@ -2659,6 +2670,7 @@ void LLModelPreview::updateStatusMessages()
if (phys_tris || phys_hulls > 0)
{
fmp->childEnable("Decompose");
+ fmp->childEnable("Analyze");
}
}
else
@@ -3530,7 +3542,7 @@ bool LLModelPreview::render()
if (!show_skin_weight)
{
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
LLModelInstance& instance = *iter;
@@ -3620,7 +3632,7 @@ bool LLModelPreview::render()
gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
LLModelInstance& instance = *iter;
@@ -3745,7 +3757,7 @@ bool LLModelPreview::render()
gGL.diffuseColor4f(1.f, 0.f, 0.f, 1.f);
const LLVector4a scale(0.5f);
- for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
{
LLModelInstance& instance = *iter;
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
index 7b3b699b33..92ac2d1faf 100644
--- a/indra/newview/llmodelpreview.h
+++ b/indra/newview/llmodelpreview.h
@@ -319,7 +319,7 @@ protected:
// Amount of triangles in original(base) model
U32 mMaxTriangleLimit;
- LLMeshUploadThread::instance_list mUploadData;
+ LLMeshUploadThread::instance_list_t mUploadData;
std::set<LLViewerFetchedTexture * > mTextureSet;
LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
index 5b8b28ebe6..9a33bcb1b9 100644
--- a/indra/newview/llnotificationlistitem.cpp
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -38,6 +38,7 @@
#include "lluicolortable.h"
#include "message.h"
#include "llnotificationsutil.h"
+#include "llviewercontrol.h"
#include <boost/regex.hpp>
LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p),
@@ -133,10 +134,22 @@ std::string LLNotificationListItem::buildNotificationDate(const LLDate& time_sta
default:
timeStr = "[" + LLTrans::getString("TimeMonth") + "]/["
+LLTrans::getString("TimeDay")+"]/["
- +LLTrans::getString("TimeYear")+"] ["
- +LLTrans::getString("TimeHour")+"]:["
- +LLTrans::getString("TimeMin")+"] ["
- +LLTrans::getString("TimeTimezone")+"]";
+ +LLTrans::getString("TimeYear")+"] [";
+
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ if (use_24h)
+ {
+ timeStr += LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "] ["
+ + LLTrans::getString("TimeTimezone") + "]";
+ }
+ else
+ {
+ timeStr += LLTrans::getString("TimeHour12") + "]:["
+ + LLTrans::getString("TimeMin") + "] ["
+ + LLTrans::getString("TimeAMPM") + "] ["
+ + LLTrans::getString("TimeTimezone") + "]";
+ }
break;
}
LLSD substitution;
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 3adee9fa16..8589afae06 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -818,6 +818,7 @@ void LLOutfitGallery::getCurrentCategories(uuid_vec_t& vcur)
void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
{
+ LL_PROFILE_ZONE_SCOPED;
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
if (!cat) return;
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 4e594af432..58cd9fab83 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -181,6 +181,7 @@ void LLOutfitsList::onOpen(const LLSD& info)
void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
{
+ LL_PROFILE_ZONE_SCOPED;
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
if (!cat) return;
@@ -251,7 +252,9 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
if (AISAPI::isAvailable() && LLInventoryModelBackgroundFetch::instance().folderFetchActive())
{
- // for reliability just fetch it whole, linked items included
+ // For reliability just fetch it whole, linked items included
+ // Todo: list is not warrantied to exist once callback arrives
+ // Fix it!
LLInventoryModelBackgroundFetch::instance().fetchFolderAndLinks(cat_id, [cat_id, list]
{
if (list)
@@ -1059,6 +1062,7 @@ void LLOutfitListBase::onIdle(void* userdata)
void LLOutfitListBase::onIdleRefreshList()
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLAppViewer::instance()->quitRequested())
{
mRefreshListState.CategoryUUID.setNull();
@@ -1072,7 +1076,7 @@ void LLOutfitListBase::onIdleRefreshList()
return;
}
- const F64 MAX_TIME = 0.05f;
+ const F64 MAX_TIME = 0.005f;
F64 curent_time = LLTimer::getTotalSeconds();
const F64 end_time = curent_time + MAX_TIME;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 514d772340..fc5c468297 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -4721,7 +4721,6 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
if (allow)
{
objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false /*managing our own update*/);
- tep->setGLTFRenderMaterial(nullptr);
tep->setGLTFMaterialOverride(nullptr);
if (te_data["te"].has("pbr_override"))
@@ -4737,7 +4736,6 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
else
{
objectp->setRenderMaterialID(te, LLUUID::null, false /*send in bulk later*/ );
- tep->setGLTFRenderMaterial(nullptr);
tep->setGLTFMaterialOverride(nullptr);
// blank out most override data on the server
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 41373cd7f5..7596c0eba8 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -41,6 +41,7 @@
#include "lllandmarkactions.h"
#include "llparcel.h"
#include "llslurl.h"
+#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@@ -326,7 +327,8 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem)
}
else
{
- std::string timeStr = getString("acquired_date");
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ std::string timeStr = use_24h ? getString("acquired_date") : getString("acquired_date_ampm");
LLSD substitution;
substitution["datetime"] = (S32) time_utc;
LLStringUtil::format (timeStr, substitution);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index f90d6d5b3f..a31a54bb67 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -385,10 +385,7 @@ bool LLTaskInvFVBridge::removeItem()
return true;
}
- LLSD payload;
- payload["task_id"] = mPanel->getTaskUUID();
- payload["inventory_ids"].append(mUUID);
- LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
+ LLNotificationsUtil::add("CantModifyContentInNoModTask");
return false;
}
}
@@ -411,13 +408,7 @@ void LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
if (!object->permModify())
{
- LLSD payload;
- payload["task_id"] = mPanel->getTaskUUID();
- for (LLFolderViewModelItem* item : batch)
- {
- payload["inventory_ids"].append(((LLTaskInvFVBridge*)item)->getUUID());
- }
- LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel));
+ LLNotificationsUtil::add("CantModifyContentInNoModTask");
}
else
{
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 578bc5b9a7..24a6875d5a 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -859,7 +859,7 @@ void LLPanelProfileSecondLife::resetData()
resetLoading();
// Set default image and 1:1 dimensions for it
- mSecondLifePic->setValue("Generic_Person_Large");
+ mSecondLifePic->setValue(LLUUID());
LLRect imageRect = mSecondLifePicLayout->getRect();
mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth());
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 902412d359..bfdfa68e01 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -42,6 +42,7 @@
#include "llnotificationsutil.h"
#include "lltextbox.h"
#include "lltoggleablemenu.h"
+#include "llviewercontrol.h"
#include "llviewermenu.h"
#include "lllandmarkactions.h"
#include "llclipboard.h"
@@ -215,8 +216,18 @@ std::string LLTeleportHistoryFlatItem::getTimestamp()
// Only show timestamp for today and yesterday
if(time_diff < seconds_today + seconds_in_day)
{
- timestamp = "[" + LLTrans::getString("TimeHour12")+"]:["
- + LLTrans::getString("TimeMin")+"] ["+ LLTrans::getString("TimeAMPM")+"]";
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ if (use_24h)
+ {
+ timestamp = "[" + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]";
+ }
+ else
+ {
+ timestamp = "[" + LLTrans::getString("TimeHour12") + "]:["
+ + LLTrans::getString("TimeMin") + "] [" + LLTrans::getString("TimeAMPM") + "]";
+ }
+
LLSD substitution;
substitution["datetime"] = (S32) date.secondsSinceEpoch();
LLStringUtil::format(timestamp, substitution);
diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp
index 60877494e7..d8d6bcf5fd 100644
--- a/indra/newview/llpanelvoicedevicesettings.cpp
+++ b/indra/newview/llpanelvoicedevicesettings.cpp
@@ -240,13 +240,38 @@ void LLPanelVoiceDeviceSettings::refresh()
if(mCtrlInputDevices)
{
mCtrlInputDevices->removeall();
- mCtrlInputDevices->add(getLocalizedDeviceName(mInputDevice), mInputDevice, ADD_BOTTOM);
+ auto it = mLocalizedDeviceNames.find(mInputDevice);
+ if (it != mLocalizedDeviceNames.end())
+ {
+ mCtrlInputDevices->add(getLocalizedDeviceName(mInputDevice), mInputDevice, ADD_BOTTOM);
+ }
+ else
+ {
+ // Display name generaly doesn't match value.
+ // Value is an id so it's not nessesary readable,
+ // might not even be valid (disconnected usb).
+ // Until we get the data, don't change the device,
+ // otherwise box might override the control.
+ // But show a readable placeholder.
+ // Combo is disabled so it's safe to show
+ // a placeholder.
+ mCtrlInputDevices->add(getString("device_not_loaded"), mInputDevice, ADD_BOTTOM);
+ }
mCtrlInputDevices->setValue(mInputDevice);
}
if(mCtrlOutputDevices)
{
mCtrlOutputDevices->removeall();
- mCtrlOutputDevices->add(getLocalizedDeviceName(mOutputDevice), mOutputDevice, ADD_BOTTOM);
+ auto it = mLocalizedDeviceNames.find(mOutputDevice);
+ if (it != mLocalizedDeviceNames.end())
+ {
+ mCtrlOutputDevices->add(getLocalizedDeviceName(mOutputDevice), mOutputDevice, ADD_BOTTOM);
+ }
+ else
+ {
+ // Don't change the device, only the label
+ mCtrlOutputDevices->add(getString("device_not_loaded"), mOutputDevice, ADD_BOTTOM);
+ }
mCtrlOutputDevices->setValue(mOutputDevice);
}
}
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 2fbdbeaf59..5916163f60 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -582,7 +582,7 @@ void LLPanelVolume::getState( )
bool enable_material = editable && single_volume && material_same;
LLCachedControl<bool> edit_linked(gSavedSettings, "EditLinkedParts", false);
- if (!enable_material && !edit_linked())
+ if (!enable_material)
{
LLViewerObject* root = selection->getPrimaryObject();
while (root && !root->isAvatar() && root->getParent())
@@ -592,6 +592,10 @@ void LLPanelVolume::getState( )
{
break;
}
+ if (!parent->isSelected())
+ {
+ break;
+ }
root = parent;
}
if (root)
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 22a9dd0027..2fdec14f6d 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -109,25 +109,27 @@ bool LLScriptFloater::toggle(const LLUUID& notification_id)
LLScriptFloater* LLScriptFloater::show(const LLUUID& notification_id)
{
LLScriptFloater* floater = LLFloaterReg::getTypedInstance<LLScriptFloater>("script_floater", notification_id);
- floater->setNotificationId(notification_id);
- floater->createForm(notification_id);
-
- //LLDialog(LLGiveInventory and LLLoadURL) should no longer steal focus (see EXT-5445)
- floater->setAutoFocus(false);
-
- if(LLScriptFloaterManager::OBJ_SCRIPT == LLScriptFloaterManager::getObjectType(notification_id))
+ if (floater)
{
- floater->setSavePosition(true);
- floater->restorePosition();
- }
- else
- {
- floater->dockToChiclet(true);
- }
+ floater->setNotificationId(notification_id);
+ floater->createForm(notification_id);
- //LLDialog(LLGiveInventory and LLLoadURL) should no longer steal focus (see EXT-5445)
- LLFloaterReg::showTypedInstance<LLScriptFloater>("script_floater", notification_id, false);
+ //LLDialog(LLGiveInventory and LLLoadURL) should no longer steal focus (see EXT-5445)
+ floater->setAutoFocus(false);
+ if (LLScriptFloaterManager::OBJ_SCRIPT == LLScriptFloaterManager::getObjectType(notification_id))
+ {
+ floater->setSavePosition(true);
+ floater->restorePosition();
+ }
+ else
+ {
+ floater->dockToChiclet(true);
+ }
+
+ //LLDialog(LLGiveInventory and LLLoadURL) should no longer steal focus (see EXT-5445)
+ LLFloaterReg::showTypedInstance<LLScriptFloater>("script_floater", notification_id, false);
+ }
return floater;
}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 329522f18c..758e91f6c9 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1996,9 +1996,95 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
asset_id = BLANK_MATERIAL_ASSET_ID;
}
}
+
+ // If this face already has the target material ID, do nothing.
+ // This prevents re-sending the same ID on OK, which can cause the server
+ // to drop overrides when queueApply is invoked with the OLD id.
+ if (objectp->getRenderMaterialID(te) == asset_id)
+ {
+ return true;
+ }
+
+ // Preserve existing texture transforms when switching to PBR material
+ LLTextureEntry* tep = objectp->getTE(te);
+ bool should_preserve_transforms = false;
+ LLGLTFMaterial* preserved_override = nullptr;
+
+ if (tep && asset_id.notNull())
+ {
+ // Only preserve transforms from existing GLTF material override
+ // Do not fall back to texture entry transforms when switching between PBR materials
+ LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride();
+ if (existing_override)
+ {
+ // Check if existing override has non-default transforms
+ const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0];
+ const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
+
+ if (existing_transform.mScale != default_transform.mScale ||
+ existing_transform.mOffset != default_transform.mOffset ||
+ existing_transform.mRotation != default_transform.mRotation)
+ {
+ // Preserve non-default transforms from current PBR material
+ preserved_override = new LLGLTFMaterial();
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ preserved_override->mTextureTransform[i].mScale = existing_transform.mScale;
+ preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset;
+ preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation;
+ }
+ should_preserve_transforms = true;
+ }
+ // If existing override has default transforms, don't preserve anything
+ }
+ else
+ {
+ // No existing PBR material override - check texture entry transforms
+ // This handles the case of switching from Blinn-Phong to PBR material
+ F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation;
+ tep->getScale(&existing_scale_s, &existing_scale_t);
+ tep->getOffset(&existing_offset_s, &existing_offset_t);
+ existing_rotation = tep->getRotation();
+
+ const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
+ if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] ||
+ existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] ||
+ existing_rotation != default_transform.mRotation)
+ {
+ // Preserve non-default transforms from texture entry
+ preserved_override = new LLGLTFMaterial();
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ LLVector2 pbr_scale, pbr_offset;
+ F32 pbr_rotation;
+ LLGLTFMaterial::convertTextureTransformToPBR(
+ existing_scale_s, existing_scale_t,
+ existing_offset_s, existing_offset_t,
+ existing_rotation,
+ pbr_scale, pbr_offset, pbr_rotation);
+ preserved_override->mTextureTransform[i].mScale = pbr_scale;
+ preserved_override->mTextureTransform[i].mOffset = pbr_offset;
+ preserved_override->mTextureTransform[i].mRotation = pbr_rotation;
+ }
+ should_preserve_transforms = true;
+ }
+ }
+ }
+
objectp->clearTEWaterExclusion(te);
// Blank out most override data on the object and send to server
- objectp->setRenderMaterialID(te, asset_id);
+ if (should_preserve_transforms && preserved_override)
+ {
+ // Apply material with preserved transforms
+ LLGLTFMaterialList::queueApply(objectp, te, asset_id, preserved_override);
+ // Update local state
+ objectp->setRenderMaterialID(te, asset_id, false, true);
+ tep->setGLTFMaterialOverride(preserved_override);
+ }
+ else
+ {
+ objectp->setRenderMaterialID(te, asset_id);
+ }
return true;
}
@@ -2265,23 +2351,9 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
//blank override out
LLGLTFMaterialList::queueApply(objectp, te, asset_id);
}
- if (old_asset_id != asset_id)
- {
- // Restore overrides and base material
- // Note: might not work reliably if asset is already there, might
- // have a server sided problem where servers applies override
- // first then resets it by adding asset, in which case need
- // to create a server ticket and chain asset then override
- // application.
- LLGLTFMaterialList::queueApply(objectp, te, asset_id, material);
- }
else
{
- // Enqueue override update to server
- // Note: this is suboptimal, better to send asset id as well
- // but there seems to be a server problem with queueApply
- // that ignores override in some cases
- LLGLTFMaterialList::queueModify(objectp, te, material);
+ LLGLTFMaterialList::queueApply(objectp, te, asset_id, material);
}
}
return true;
diff --git a/indra/newview/llsettingspicker.cpp b/indra/newview/llsettingspicker.cpp
index 619882dc5e..5fc39b0dd8 100644
--- a/indra/newview/llsettingspicker.cpp
+++ b/indra/newview/llsettingspicker.cpp
@@ -152,7 +152,11 @@ void LLFloaterSettingsPicker::onClose(bool app_quitting)
owner->setFocus(true);
}
mSettingItemID.setNull();
- mInventoryPanel->getRootFolder()->clearSelection();
+ mInventoryPanel->clearSelection();
+ if (mInventoryPanel->getRootFolder())
+ {
+ mInventoryPanel->getRootFolder()->clearSelection();
+ }
}
void LLFloaterSettingsPicker::setValue(const LLSD& value)
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 3d4b4fb9c1..6d50f216f5 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -487,7 +487,8 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
}
else
{
- std::string timeStr = getString("acquiredDate");
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ std::string timeStr = use_24h ? getString("acquiredDate") : getString("acquiredDateAMPM");
LLSD substitution;
substitution["datetime"] = (S32) time_utc;
LLStringUtil::format (timeStr, substitution);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index eca5ba82ac..c3c7945763 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -446,7 +446,26 @@ bool idle_startup()
system = osString.substr (begIdx, endIdx - begIdx);
system += "Locale";
- LLStringUtil::setLocale (LLTrans::getString(system));
+ std::string locale = LLTrans::getString(system);
+ if (locale != LLStringUtil::getLocale()) // is there a reason to do this on repeat?
+ {
+ LLStringUtil::setLocale(locale);
+
+ // Not all locales have AMPM, test it
+ if (LLStringOps::sAM.empty()) // Might already be overriden from LLAppViewer::init()
+ {
+ LLDate datetime(0.0);
+ std::string val = datetime.toHTTPDateString("%p");
+ if (val.empty())
+ {
+ LL_DEBUGS("InitInfo") << "Current locale \"" << locale << "\" "
+ << "doesn't support AM/PM time format" << LL_ENDL;
+ // fallback to declarations in strings.xml
+ LLStringOps::sAM = LLTrans::getString("dateTimeAM");
+ LLStringOps::sPM = LLTrans::getString("dateTimePM");
+ }
+ }
+ }
//note: Removing this line will cause incorrect button size in the login screen. -- bao.
gTextureList.updateImages(0.01f) ;
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index 1826885069..64359b6cbe 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -28,9 +28,6 @@
#include "llsurface.h"
-#include "llrender.h"
-
-#include "llviewertexturelist.h"
#include "llpatchvertexarray.h"
#include "patch_dct.h"
#include "patch_code.h"
@@ -39,28 +36,25 @@
#include "llregionhandle.h"
#include "llagent.h"
#include "llagentcamera.h"
-#include "llappviewer.h"
#include "llworld.h"
#include "llviewercontrol.h"
#include "llviewertexture.h"
#include "llsurfacepatch.h"
-#include "llvosurfacepatch.h"
#include "llvowater.h"
#include "pipeline.h"
#include "llviewerregion.h"
-#include "llvlcomposition.h"
-#include "noise.h"
-#include "llviewercamera.h"
-#include "llglheaders.h"
#include "lldrawpoolterrain.h"
-#include "lldrawable.h"
#include "llworldmipmap.h"
extern LLPipeline gPipeline;
extern bool gShiftFrame;
-LLColor4U MAX_WATER_COLOR(0, 48, 96, 240);
+namespace
+{
+ static constexpr float MIN_TEXTURE_REQUEST_INTERVAL = 5.0f;
+}
+LLColor4U MAX_WATER_COLOR(0, 48, 96, 240);
S32 LLSurface::sTextureSize = 256;
@@ -74,18 +68,18 @@ LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
mType(type),
mDetailTextureScale(0.f),
mOriginGlobal(0.0, 0.0, 0.0),
- mSTexturep(NULL),
+ mSTexturep(nullptr),
mGridsPerPatchEdge(0),
mMetersPerGrid(1.0f),
mMetersPerEdge(1.0f),
mRegionp(regionp)
{
// Surface data
- mSurfaceZ = NULL;
- mNorm = NULL;
+ mSurfaceZ = nullptr;
+ mNorm = nullptr;
// Patch data
- mPatchList = NULL;
+ mPatchList = nullptr;
// One of each for each camera
mVisiblePatchCount = 0;
@@ -95,14 +89,14 @@ LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
mMinZ = 10000.f;
mMaxZ = -10000.f;
- mWaterObjp = NULL;
+ mWaterObjp = nullptr;
// In here temporarily.
mSurfacePatchUpdateCount = 0;
for (S32 i = 0; i < 8; i++)
{
- mNeighbors[i] = NULL;
+ mNeighbors[i] = nullptr;
}
}
@@ -110,7 +104,7 @@ LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
LLSurface::~LLSurface()
{
delete [] mSurfaceZ;
- mSurfaceZ = NULL;
+ mSurfaceZ = nullptr;
delete [] mNorm;
@@ -129,7 +123,7 @@ LLSurface::~LLSurface()
{
gPipeline.removePool(poolp);
// Don't enable this until we blitz the draw pool for it as well. -- djs
- mSTexturep = NULL;
+ mSTexturep = nullptr;
}
else
{
@@ -144,7 +138,7 @@ void LLSurface::initClasses()
void LLSurface::setRegion(LLViewerRegion *regionp)
{
mRegionp = regionp;
- mWaterObjp = NULL; // depends on regionp, needs recreating
+ mWaterObjp = nullptr; // depends on regionp, needs recreating
}
// Assumes that arguments are powers of 2, and that
@@ -211,16 +205,29 @@ LLViewerTexture* LLSurface::getSTexture()
void LLSurface::createSTexture()
{
- if (!mSTexturep)
+ if (mSTexturep.isNull())
+ {
+ mTimer.setTimerExpirySec(MIN_TEXTURE_REQUEST_INTERVAL);
+ }
+ else if (mSTexturep->hasGLTexture())
{
- U64 handle = mRegionp->getHandle();
+ // Unexpected: createSTexture() called when a valid texture already exists.
+ // This may indicate a logic error in the caller, as textures should not be recreated unnecessarily.
+ LL_WARNS() << "Called LLSurface::createSTexture() while we already have a valid texture!" << LL_ENDL;
+ return;
+ }
+ else if (!mTimer.checkExpirationAndReset(MIN_TEXTURE_REQUEST_INTERVAL))
+ {
+ // We haven't gotten a valid texture yet, but throttle the number of requests to avoid server flooding
+ return;
+ }
- U32 grid_x, grid_y;
+ U64 handle = mRegionp->getHandle();
+ U32 grid_x, grid_y;
- grid_from_region_handle(handle, &grid_x, &grid_y);
+ grid_from_region_handle(handle, &grid_x, &grid_y);
- mSTexturep = LLWorldMipmap::loadObjectsTile(grid_x, grid_y, 1);
- }
+ mSTexturep = LLWorldMipmap::loadObjectsTile(grid_x, grid_y, 1);
}
void LLSurface::initTextures()
@@ -285,7 +292,7 @@ void LLSurface::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegio
S32 i;
for (i = 0; i < 8; i++)
{
- if ( mNeighbors[i] != NULL )
+ if (mNeighbors[i] != nullptr)
{
uniqueRegions.push_back( mNeighbors[i]->getRegion() );
}
@@ -298,7 +305,7 @@ void LLSurface::getNeighboringRegionsStatus( std::vector<S32>& regions )
S32 i;
for (i = 0; i < 8; i++)
{
- if ( mNeighbors[i] != NULL )
+ if (mNeighbors[i] != nullptr)
{
regions.push_back( i );
}
@@ -498,7 +505,7 @@ void LLSurface::disconnectNeighbor(LLSurface *surfacep)
{
if (surfacep == mNeighbors[i])
{
- mNeighbors[i] = NULL;
+ mNeighbors[i] = nullptr;
}
}
@@ -518,7 +525,7 @@ void LLSurface::disconnectAllNeighbors()
if (mNeighbors[i])
{
mNeighbors[i]->disconnectNeighbor(this);
- mNeighbors[i] = NULL;
+ mNeighbors[i] = nullptr;
}
}
}
@@ -910,7 +917,7 @@ LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const
if(0 == mNumberOfPatches)
{
LL_WARNS() << "No patches for current region!" << LL_ENDL;
- return NULL;
+ return nullptr;
}
S32 old_index = index;
index = llclamp(old_index, 0, (mNumberOfPatches - 1));
@@ -996,7 +1003,7 @@ void LLSurface::createPatchData()
}
else
{
- patchp->setNeighborPatch(EAST, NULL);
+ patchp->setNeighborPatch(EAST, nullptr);
}
if (j < mPatchesPerEdge-1)
@@ -1005,7 +1012,7 @@ void LLSurface::createPatchData()
}
else
{
- patchp->setNeighborPatch(NORTH, NULL);
+ patchp->setNeighborPatch(NORTH, nullptr);
}
if (i > 0)
@@ -1014,7 +1021,7 @@ void LLSurface::createPatchData()
}
else
{
- patchp->setNeighborPatch(WEST, NULL);
+ patchp->setNeighborPatch(WEST, nullptr);
}
if (j > 0)
@@ -1023,7 +1030,7 @@ void LLSurface::createPatchData()
}
else
{
- patchp->setNeighborPatch(SOUTH, NULL);
+ patchp->setNeighborPatch(SOUTH, nullptr);
}
if (i < (mPatchesPerEdge-1) && j < (mPatchesPerEdge-1))
@@ -1032,7 +1039,7 @@ void LLSurface::createPatchData()
}
else
{
- patchp->setNeighborPatch(NORTHEAST, NULL);
+ patchp->setNeighborPatch(NORTHEAST, nullptr);
}
if (i > 0 && j < (mPatchesPerEdge-1))
@@ -1041,7 +1048,7 @@ void LLSurface::createPatchData()
}
else
{
- patchp->setNeighborPatch(NORTHWEST, NULL);
+ patchp->setNeighborPatch(NORTHWEST, nullptr);
}
if (i > 0 && j > 0)
@@ -1050,7 +1057,7 @@ void LLSurface::createPatchData()
}
else
{
- patchp->setNeighborPatch(SOUTHWEST, NULL);
+ patchp->setNeighborPatch(SOUTHWEST, nullptr);
}
if (i < (mPatchesPerEdge-1) && j > 0)
@@ -1059,7 +1066,7 @@ void LLSurface::createPatchData()
}
else
{
- patchp->setNeighborPatch(SOUTHEAST, NULL);
+ patchp->setNeighborPatch(SOUTHEAST, nullptr);
}
LLVector3d origin_global;
@@ -1077,7 +1084,7 @@ void LLSurface::destroyPatchData()
// Delete all of the cached patch data for these patches.
delete [] mPatchList;
- mPatchList = NULL;
+ mPatchList = nullptr;
mVisiblePatchCount = 0;
}
@@ -1105,12 +1112,12 @@ LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const
if ((x < 0) || (x >= mPatchesPerEdge))
{
LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL;
- return NULL;
+ return nullptr;
}
if ((y < 0) || (y >= mPatchesPerEdge))
{
LL_ERRS() << "Asking for patch out of bounds" << LL_ENDL;
- return NULL;
+ return nullptr;
}
return mPatchList + x + y*mPatchesPerEdge;
diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h
index fc72ab7db7..a599019ca5 100644
--- a/indra/newview/llsurface.h
+++ b/indra/newview/llsurface.h
@@ -29,14 +29,8 @@
#include "v3math.h"
#include "v3dmath.h"
-#include "v4math.h"
-#include "m3math.h"
-#include "m4math.h"
-#include "llquaternion.h"
-
-#include "v4coloru.h"
-#include "v4color.h"
+#include "lltimer.h"
#include "llvowater.h"
#include "llpatchvertexarray.h"
#include "llviewertexture.h"
@@ -65,7 +59,7 @@ class LLGroupHeader;
class LLSurface
{
public:
- LLSurface(U32 type, LLViewerRegion *regionp = NULL);
+ LLSurface(U32 type, LLViewerRegion *regionp = nullptr);
virtual ~LLSurface();
static void initClasses(); // Do class initialization for LLSurface and its child classes.
@@ -169,14 +163,13 @@ public:
F32 mDetailTextureScale; // Number of times to repeat detail texture across this surface
-protected:
+private:
void createSTexture();
void initTextures();
void createPatchData(); // Allocates memory for patches.
void destroyPatchData(); // Deallocates memory for patches.
-protected:
LLVector3d mOriginGlobal; // In absolute frame
LLSurfacePatch *mPatchList; // Array of all patches
@@ -212,6 +205,7 @@ protected:
private:
LLViewerRegion *mRegionp; // Patch whose coordinate system this surface is using.
static S32 sTextureSize; // Size of the surface texture
+ LLTimer mTimer; // timer to throttle initial requests until the mSTexture is fully fetched
};
extern template bool LLSurface::idleUpdate</*PBR=*/false>(F32 max_update_time);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 5507ef517a..b2f2509e80 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1012,6 +1012,8 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
{
self->setImageID( self->getDefaultImageAssetID() );
self->setTentative(false);
+ // Deselect in case inventory has a selected item with the same id
+ self->mInventoryPanel->getRootFolder()->clearSelection();
}
self->commitIfImmediateSet();
}
@@ -1023,6 +1025,8 @@ void LLFloaterTexturePicker::onBtnBlank(void* userdata)
self->setCanApply(true, true);
self->setImageID( self->getBlankImageAssetID() );
self->setTentative(false);
+ // Deselect in case inventory has a selected item with the same id
+ self->mInventoryPanel->getRootFolder()->clearSelection();
self->commitIfImmediateSet();
}
@@ -1034,6 +1038,8 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata)
self->setCanApply(true, true);
self->setImageID( LLUUID::null );
self->setTentative(false);
+ // Deselect in case inventory has a selected item with null id
+ self->mInventoryPanel->getRootFolder()->clearSelection();
self->commitIfImmediateSet();
}
@@ -1698,10 +1704,16 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mDefaultImageName(p.default_image_name),
mFallbackImage(p.fallback_image)
{
-
- // Default of defaults is white image for diff tex
- //
- setBlankImageAssetID(IMG_WHITE);
+ if (mInventoryPickType == PICK_MATERIAL)
+ {
+ setBlankImageAssetID(BLANK_MATERIAL_ASSET_ID);
+ }
+ else
+ {
+ // Default of defaults is white image for diff tex
+ //
+ setBlankImageAssetID(IMG_WHITE);
+ }
setAllowNoTexture(p.allow_no_texture);
setCanApplyImmediately(p.can_apply_immediately);
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 93b5806acf..f7cb0ee7ed 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -1295,10 +1295,19 @@ bool LLTextureFetchWorker::doWork(S32 param)
else
{
mCanUseCapability = false;
- mRegionRetryAttempt++;
- mRegionRetryTimer.setTimerExpirySec(CAP_MISSING_EXPIRATION_DELAY);
- // ex: waiting for caps
- LL_INFOS_ONCE(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
+ if (gDisconnected)
+ {
+ // We lost connection or are shutting down.
+ mCanUseHTTP = false;
+ return true; // abort
+ }
+ else
+ {
+ // Ex: waiting for caps
+ mRegionRetryAttempt++;
+ mRegionRetryTimer.setTimerExpirySec(CAP_MISSING_EXPIRATION_DELAY);
+ LL_INFOS_ONCE(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
+ }
}
}
else
@@ -1694,10 +1703,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
mHttpReplyOffset = 0;
mLoadedDiscard = mRequestedDiscard;
- if (mLoadedDiscard < 0)
+ if (mLoadedDiscard < 0 || (mLoadedDiscard > MAX_DISCARD_LEVEL && mFormattedImage->getCodec() == IMG_CODEC_J2C))
{
LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
- << ", should be >=0" << LL_ENDL;
+ << ", should be >=0 and <=" << MAX_DISCARD_LEVEL << LL_ENDL;
}
setState(DECODE_IMAGE);
if (mWriteToCacheState != NOT_WRITE)
@@ -1759,14 +1768,27 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS(LOG_TXT) << mID << " DECODE_IMAGE abort: mLoadedDiscard < 0" << LL_ENDL;
return true;
}
+
+ llassert_always(mFormattedImage.notNull());
+ S32 discard = mHaveAllData && mFormattedImage->getCodec() != IMG_CODEC_J2C ? 0 : mLoadedDiscard;
+ if (discard > MAX_DISCARD_LEVEL) // only warn for j2c
+ {
+ // We encode j2c with fixed amount of discard levels,
+ // Trying to decode beyound that will fail.
+ LL_WARNS(LOG_TXT) << "Decode entered with invalid discard. ID = " << mID << LL_ENDL;
+
+ //abort, don't decode
+ setState(DONE);
+ LL_DEBUGS(LOG_TXT) << mID << " DECODE_IMAGE abort: mLoadedDiscard > MAX_DISCARD_LEVEL" << LL_ENDL;
+ return true;
+ }
+
mDecodeTimer.reset();
mRawImage = NULL;
mAuxImage = NULL;
- llassert_always(mFormattedImage.notNull());
// if we have the entire image data (and the image is not J2C), decode the full res image
// DO NOT decode a higher res j2c than was requested. This is a waste of time and memory.
- S32 discard = mHaveAllData && mFormattedImage->getCodec() != IMG_CODEC_J2C ? 0 : mLoadedDiscard;
mDecoded = false;
setState(DECODE_IMAGE_UPDATE);
LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 3c3440d41a..95653dc19b 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -87,10 +87,21 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
std::string timeStr = "[" + LLTrans::getString("TimeWeek") + "], ["
+ LLTrans::getString("TimeMonth") + "]/["
+ LLTrans::getString("TimeDay") + "]/["
- + LLTrans::getString("TimeYear") + "] ["
- + LLTrans::getString("TimeHour") + "]:["
- + LLTrans::getString("TimeMin") + "] ["
- + LLTrans::getString("TimeTimezone") + "]";
+ + LLTrans::getString("TimeYear") + "] [";
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ if (use_24h)
+ {
+ timeStr += LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "] ["
+ + LLTrans::getString("TimeTimezone") + "]";
+ }
+ else
+ {
+ timeStr += LLTrans::getString("TimeHour12") + "]:["
+ + LLTrans::getString("TimeMin") + "] ["
+ + LLTrans::getString("TimeAMPM") + "] ["
+ + LLTrans::getString("TimeTimezone") + "]";
+ }
const LLDate timeStamp = notification->getDate();
LLDate notice_date = timeStamp.notNull() ? timeStamp : payload["received_time"].asDate();
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 0063e0b7fd..c1ec5fa183 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -110,7 +110,7 @@ bool LLToolBarView::postBuild()
{
mToolbars[i]->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
mToolbars[i]->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
- mToolbars[i]->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
+ mToolbars[i]->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4,_5));
mToolbars[i]->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded,_1));
mToolbars[i]->setButtonRemoveCallback(boost::bind(LLToolBarView::onToolBarButtonRemoved,_1));
}
@@ -624,8 +624,14 @@ bool LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
return false;
}
-bool LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar)
+bool LLToolBarView::handleDropTool( void* cargo_data, EDragAndDropType cargo_type, S32 x, S32 y, LLToolBar* toolbar)
{
+ if (cargo_type == DAD_PERSON)
+ {
+ // DAD_PERSON means that cargo_data contains an uuid, not an LLInventoryObject
+ resetDragTool(NULL);
+ return false;
+ }
bool handled = false;
LLInventoryObject* inv_item = static_cast<LLInventoryObject*>(cargo_data);
@@ -647,15 +653,18 @@ bool LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* t
if (old_toolbar_loc != LLToolBarEnums::TOOLBAR_NONE)
{
llassert(gToolBarView->mDragToolbarButton);
- old_toolbar = gToolBarView->mDragToolbarButton->getParentByType<LLToolBar>();
- if (old_toolbar->isReadOnly() && toolbar->isReadOnly())
- {
- // do nothing
- }
- else
+ if (gToolBarView->mDragToolbarButton)
{
- int old_rank = LLToolBar::RANK_NONE;
- gToolBarView->removeCommand(command_id, old_rank);
+ old_toolbar = gToolBarView->mDragToolbarButton->getParentByType<LLToolBar>();
+ if (old_toolbar->isReadOnly() && toolbar->isReadOnly())
+ {
+ // do nothing
+ }
+ else
+ {
+ int old_rank = LLToolBar::RANK_NONE;
+ gToolBarView->removeCommand(command_id, old_rank);
+ }
}
}
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index 7cecd81052..7212f099b7 100644
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -92,7 +92,7 @@ public:
static void startDragTool(S32 x, S32 y, LLToolBarButton* toolbarButton);
static bool handleDragTool(S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type);
- static bool handleDropTool(void* cargo_data, S32 x, S32 y, LLToolBar* toolbar);
+ static bool handleDropTool(void* cargo_data, EDragAndDropType cargo_type, S32 x, S32 y, LLToolBar* toolbar);
static void resetDragTool(LLToolBarButton* toolbarButton);
LLInventoryObject* getDragItem();
LLView* getBottomToolbar() { return mBottomToolbarPanel; }
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index b4a5955be3..f78ff2226c 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -29,6 +29,8 @@
// library headers
#include "llnotificationsutil.h"
+#include <vector>
+#include <tuple>
// project headers
#include "llagent.h"
#include "llagentcamera.h"
@@ -1297,7 +1299,89 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
asset_id = BLANK_MATERIAL_ASSET_ID;
}
- hit_obj->setRenderMaterialID(hit_face, asset_id);
+ // Preserve existing texture transforms when switching to PBR material
+ LLTextureEntry* tep = hit_obj->getTE(hit_face);
+ F32 existing_scale_s = LLGLTFMaterial::TextureTransform().mScale.mV[0];
+ F32 existing_scale_t = LLGLTFMaterial::TextureTransform().mScale.mV[1];
+ F32 existing_offset_s = LLGLTFMaterial::TextureTransform().mOffset.mV[0];
+ F32 existing_offset_t = LLGLTFMaterial::TextureTransform().mOffset.mV[1];
+ F32 existing_rotation = LLGLTFMaterial::TextureTransform().mRotation;
+ bool should_preserve_transforms = false;
+ LLGLTFMaterial* preserved_override = nullptr;
+
+ if (tep && asset_id.notNull())
+ {
+ // Only preserve transforms from existing GLTF material override
+ // Do not fall back to texture entry transforms when switching between PBR materials
+ LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride();
+ if (existing_override)
+ {
+ // Check if existing override has non-default transforms
+ const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0];
+ const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
+
+ if (existing_transform.mScale != default_transform.mScale ||
+ existing_transform.mOffset != default_transform.mOffset ||
+ existing_transform.mRotation != default_transform.mRotation)
+ {
+ // Preserve non-default transforms from current PBR material
+ preserved_override = new LLGLTFMaterial();
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ preserved_override->mTextureTransform[i].mScale = existing_transform.mScale;
+ preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset;
+ preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation;
+ }
+ should_preserve_transforms = true;
+ }
+ // If existing override has default transforms, don't preserve anything
+ }
+ else
+ {
+ // No existing PBR material override - check texture entry transforms
+ // This handles the case of switching from Blinn-Phong to PBR material
+ F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation;
+ tep->getScale(&existing_scale_s, &existing_scale_t);
+ tep->getOffset(&existing_offset_s, &existing_offset_t);
+ existing_rotation = tep->getRotation();
+
+ const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
+ if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] ||
+ existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] ||
+ existing_rotation != default_transform.mRotation)
+ {
+ // Preserve non-default transforms from texture entry
+ preserved_override = new LLGLTFMaterial();
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ LLVector2 pbr_scale, pbr_offset;
+ F32 pbr_rotation;
+ LLGLTFMaterial::convertTextureTransformToPBR(
+ existing_scale_s, existing_scale_t,
+ existing_offset_s, existing_offset_t,
+ existing_rotation,
+ pbr_scale, pbr_offset, pbr_rotation);
+ preserved_override->mTextureTransform[i].mScale = pbr_scale;
+ preserved_override->mTextureTransform[i].mOffset = pbr_offset;
+ preserved_override->mTextureTransform[i].mRotation = pbr_rotation;
+ }
+ should_preserve_transforms = true;
+ }
+ }
+ }
+
+ if (should_preserve_transforms && preserved_override)
+ {
+ // Apply material with preserved transforms
+ LLGLTFMaterialList::queueApply(hit_obj, hit_face, asset_id, preserved_override);
+ // Update local state
+ hit_obj->setRenderMaterialID(hit_face, asset_id, false, true);
+ tep->setGLTFMaterialOverride(preserved_override);
+ }
+ else
+ {
+ hit_obj->setRenderMaterialID(hit_face, asset_id);
+ }
dialog_refresh_all();
@@ -1333,7 +1417,134 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
asset_id = BLANK_MATERIAL_ASSET_ID;
}
- hit_obj->setRenderMaterialIDs(asset_id);
+ // Preserve existing texture transforms when switching to PBR material for all faces
+ std::vector<std::pair<bool, LLGLTFMaterial*>> preserved_transforms(hit_obj->getNumTEs());
+
+ if (asset_id.notNull())
+ {
+ for (S32 te = 0; te < hit_obj->getNumTEs(); ++te)
+ {
+ LLTextureEntry* tep = hit_obj->getTE(te);
+ if (!tep) continue;
+
+ bool should_preserve = false;
+ LLGLTFMaterial* preserved_override = nullptr;
+
+ // Only preserve transforms from existing GLTF material override
+ // Do not fall back to texture entry transforms when switching between PBR materials
+ LLGLTFMaterial* existing_override = tep->getGLTFMaterialOverride();
+ if (existing_override)
+ {
+ // Check if existing override has non-default transforms
+ const LLGLTFMaterial::TextureTransform& existing_transform = existing_override->mTextureTransform[0];
+ const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
+
+ if (existing_transform.mScale != default_transform.mScale ||
+ existing_transform.mOffset != default_transform.mOffset ||
+ existing_transform.mRotation != default_transform.mRotation)
+ {
+ // Preserve non-default transforms from current PBR material
+ preserved_override = new LLGLTFMaterial();
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ preserved_override->mTextureTransform[i].mScale = existing_transform.mScale;
+ preserved_override->mTextureTransform[i].mOffset = existing_transform.mOffset;
+ preserved_override->mTextureTransform[i].mRotation = existing_transform.mRotation;
+ }
+ should_preserve = true;
+ }
+ else
+ {
+ // Existing override has default transforms, fall back to texture entry
+ F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation;
+ tep->getScale(&existing_scale_s, &existing_scale_t);
+ tep->getOffset(&existing_offset_s, &existing_offset_t);
+ existing_rotation = tep->getRotation();
+
+ if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] ||
+ existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] ||
+ existing_rotation != default_transform.mRotation)
+ {
+ // Preserve non-default transforms from texture entry
+ preserved_override = new LLGLTFMaterial();
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ LLVector2 pbr_scale, pbr_offset;
+ F32 pbr_rotation;
+ LLGLTFMaterial::convertTextureTransformToPBR(
+ existing_scale_s, existing_scale_t,
+ existing_offset_s, existing_offset_t,
+ existing_rotation,
+ pbr_scale, pbr_offset, pbr_rotation);
+ preserved_override->mTextureTransform[i].mScale = pbr_scale;
+ preserved_override->mTextureTransform[i].mOffset = pbr_offset;
+ preserved_override->mTextureTransform[i].mRotation = pbr_rotation;
+ }
+ should_preserve = true;
+ }
+ }
+ }
+ else
+ {
+ // No existing PBR material override - check texture entry transforms
+ // This handles the case of switching from Blinn-Phong to PBR material
+ F32 existing_scale_s, existing_scale_t, existing_offset_s, existing_offset_t, existing_rotation;
+ tep->getScale(&existing_scale_s, &existing_scale_t);
+ tep->getOffset(&existing_offset_s, &existing_offset_t);
+ existing_rotation = tep->getRotation();
+
+ const LLGLTFMaterial::TextureTransform& default_transform = LLGLTFMaterial::TextureTransform();
+ if (existing_scale_s != default_transform.mScale.mV[0] || existing_scale_t != default_transform.mScale.mV[1] ||
+ existing_offset_s != default_transform.mOffset.mV[0] || existing_offset_t != default_transform.mOffset.mV[1] ||
+ existing_rotation != default_transform.mRotation)
+ {
+ // Preserve non-default transforms from texture entry
+ preserved_override = new LLGLTFMaterial();
+ for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ LLVector2 pbr_scale, pbr_offset;
+ F32 pbr_rotation;
+ LLGLTFMaterial::convertTextureTransformToPBR(
+ existing_scale_s, existing_scale_t,
+ existing_offset_s, existing_offset_t,
+ existing_rotation,
+ pbr_scale, pbr_offset, pbr_rotation);
+ preserved_override->mTextureTransform[i].mScale = pbr_scale;
+ preserved_override->mTextureTransform[i].mOffset = pbr_offset;
+ preserved_override->mTextureTransform[i].mRotation = pbr_rotation;
+ }
+ should_preserve = true;
+ }
+ }
+
+ preserved_transforms[te] = std::make_pair(should_preserve, preserved_override);
+ }
+ }
+
+ // Apply materials with preserved transforms
+ if (asset_id.notNull())
+ {
+ for (S32 te = 0; te < hit_obj->getNumTEs(); ++te)
+ {
+ LLGLTFMaterial* preserved_override = preserved_transforms[te].second;
+ if (preserved_override)
+ {
+ // Apply material with preserved transforms
+ LLGLTFMaterialList::queueApply(hit_obj, te, asset_id, preserved_override);
+ // Update local state
+ hit_obj->setRenderMaterialID(te, asset_id, false, true);
+ hit_obj->getTE(te)->setGLTFMaterialOverride(preserved_override);
+ }
+ else
+ {
+ hit_obj->setRenderMaterialID(te, asset_id);
+ }
+ }
+ }
+ else
+ {
+ hit_obj->setRenderMaterialIDs(asset_id);
+ }
dialog_refresh_all();
// send the update to the simulator
hit_obj->sendTEUpdate();
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 6a3be8c882..c15fa52aa4 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -68,6 +68,8 @@
#include "llrender.h"
#include "llnavigationbar.h"
#include "llnotificationsutil.h"
+#include "llfloaterpreference.h"
+#include "llfloaterreg.h"
#include "llfloatertools.h"
#include "llpaneloutfitsinventory.h"
#include "llpanellogin.h"
@@ -150,6 +152,21 @@ static bool handleDebugAvatarJointsChanged(const LLSD& newvalue)
return true;
}
+static bool handleDebugQualityPerformanceChanged(const LLSD& newvalue)
+{
+ // control was set directly or after adjusting Preference setting, no need to update
+ if (gSavedSettings.getU32("RenderQualityPerformance") != gSavedSettings.getU32("DebugQualityPerformance"))
+ {
+ LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ gSavedSettings.setU32("RenderQualityPerformance", newvalue.asInteger());
+ instance->onChangeQuality(newvalue);
+ }
+ }
+ return true;
+}
+
static bool handleAvatarHoverOffsetChanged(const LLSD& newvalue)
{
if (isAgentAvatarValid())
@@ -947,6 +964,7 @@ void settings_setup_listeners()
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, "DebugQualityPerformance", handleDebugQualityPerformanceChanged);
setting_setup_signal_listener(gSavedSettings, "TargetFPS", handleTargetFPSChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneFPS", handleAutoTuneFPSChanged);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index f6ad29d085..314e32bffd 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -240,8 +240,11 @@ void display_stats()
if (gRecentFPSTime.getElapsedTimeF32() >= FPS_LOG_FREQUENCY)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS");
+ LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecording();
+ F64 normalized_session_jitter = recording.getLastValue(LLStatViewer::NOTRMALIZED_FRAMETIME_JITTER_SESSION);
+ F64 normalized_period_jitter = recording.getLastValue(LLStatViewer::NORMALIZED_FRAMTIME_JITTER_PERIOD);
F32 fps = gRecentFrameCount / FPS_LOG_FREQUENCY;
- LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL;
+ LL_INFOS() << llformat("FPS: %.02f SESSION JITTER: %.4f PERIOD JITTER: %.4f", fps, normalized_session_jitter, normalized_period_jitter) << LL_ENDL;
gRecentFrameCount = 0;
gRecentFPSTime.reset();
}
@@ -1566,6 +1569,11 @@ void render_ui(F32 zoom_factor, int subfield)
render_disconnected_background();
}
}
+ else
+ {
+ // Make sure particle effects disappear
+ LLHUDObject::renderAllForTimer();
+ }
if (render_ui)
{
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 6155058f14..ec5381ddfc 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -419,7 +419,9 @@ void LLViewerInventoryItem::updateServer(bool is_new) const
<< LL_ENDL;
return;
}
- if(gAgent.getID() != mPermissions.getOwner())
+ LLUUID owner = mPermissions.getOwner();
+ if(gAgent.getID() != owner
+ && owner.notNull()) // incomplete?
{
// *FIX: deal with this better.
LL_WARNS(LOG_INV) << "LLViewerInventoryItem::updateServer() - for unowned item "
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 10a29f3fb2..77ec31fd9d 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -83,6 +83,8 @@ extern bool gCubeSnapshot;
// *TODO: Consider enabling mipmaps (they have been disabled for a long time). Likely has a significant performance impact for tiled/high texture repeat media. Mip generation in a shader may also be an option if necessary.
constexpr bool USE_MIPMAPS = false;
+constexpr S32 MAX_MEDIA_INSTANCES_DEFAULT = 8;
+constexpr S32 MEDIA_INSTANCES_MIN_LIMIT = 6; // 4 'permanent' floaters plus reserve for dynamic ones
void init_threaded_picker_load_dialog(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple)
{
@@ -214,6 +216,7 @@ static bool sViewerMediaMuteListObserverInitialized = false;
LLViewerMedia::LLViewerMedia():
mAnyMediaShowing(false),
mAnyMediaPlaying(false),
+mMaxIntances(MAX_MEDIA_INSTANCES_DEFAULT),
mSpareBrowserMediaSource(NULL)
{
}
@@ -222,6 +225,7 @@ LLViewerMedia::~LLViewerMedia()
{
gIdleCallbacks.deleteFunction(LLViewerMedia::onIdle, NULL);
mTeleportFinishConnection.disconnect();
+ mMaxInstancesConnection.disconnect();
if (mSpareBrowserMediaSource != NULL)
{
delete mSpareBrowserMediaSource;
@@ -235,6 +239,35 @@ void LLViewerMedia::initSingleton()
gIdleCallbacks.addFunction(LLViewerMedia::onIdle, NULL);
mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
setTeleportFinishedCallback(boost::bind(&LLViewerMedia::onTeleportFinished, this));
+
+ LLControlVariable* ctrl = gSavedSettings.getControl("PluginInstancesTotal");
+ if (ctrl)
+ {
+ setMaxInstances(ctrl->getValue().asInteger());
+ mMaxInstancesConnection = ctrl->getSignal()->connect([this](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ setMaxInstances(new_val.asInteger());
+ });
+ }
+ else
+ {
+ setMaxInstances(MAX_MEDIA_INSTANCES_DEFAULT);
+ }
+}
+
+void LLViewerMedia::setMaxInstances(S32 max_instances)
+{
+ const F32Gigabytes MIN_PHYSICAL_MEMORY(8);
+ LLMemory::updateMemoryInfo();
+ F32Gigabytes physical_mem = LLMemory::getMaxMemKB();
+ if (MIN_PHYSICAL_MEMORY > physical_mem)
+ {
+ mMaxIntances = llmax(max_instances - 2, MEDIA_INSTANCES_MIN_LIMIT);
+ }
+ else
+ {
+ mMaxIntances = llmax(max_instances, MEDIA_INSTANCES_MIN_LIMIT);
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -688,7 +721,6 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
static LLCachedControl<bool> inworld_media_enabled(gSavedSettings, "AudioStreamingMedia", true);
static LLCachedControl<bool> inworld_audio_enabled(gSavedSettings, "AudioStreamingMusic", true);
- static LLCachedControl<U32> max_instances(gSavedSettings, "PluginInstancesTotal", 8);
static LLCachedControl<U32> max_normal(gSavedSettings, "PluginInstancesNormal", 2);
static LLCachedControl<U32> max_low(gSavedSettings, "PluginInstancesLow", 4);
static LLCachedControl<F32> max_cpu(gSavedSettings, "PluginInstancesCPULimit", 0.9);
@@ -709,7 +741,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
LLPluginClassMedia::EPriority new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
- if(pimpl->isForcedUnloaded() || (impl_count_total >= (int)max_instances))
+ if(pimpl->isForcedUnloaded() || (impl_count_total >= mMaxIntances))
{
// Never load muted or failed impls.
// Hard limit on the number of instances that will be loaded at one time
@@ -869,7 +901,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
sLowestLoadableImplInterest = 0.0f;
// Only do this calculation if we've hit the impl count limit -- up until that point we always need to load media data.
- if(lowest_interest_loadable && (impl_count_total >= (int)max_instances))
+ if(lowest_interest_loadable && (impl_count_total >= mMaxIntances))
{
// Get the interest value of this impl's object for use by isInterestingEnough
LLVOVolume *object = lowest_interest_loadable->getSomeObject();
@@ -1201,6 +1233,54 @@ LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders()
return headers;
}
+bool LLViewerMedia::getOpenIDCookie(LLMediaCtrl* media_instance) const
+{
+ if (mOpenIDCookie.empty())
+ {
+ return false;
+ }
+
+ std::string authority = mOpenIDURL.mAuthority;
+ std::string::size_type hostStart = authority.find('@');
+ if (hostStart == std::string::npos)
+ {
+ // no username/password
+ hostStart = 0;
+ }
+ else
+ {
+ // Hostname starts after the @.
+ // (If the hostname part is empty, this may put host_start at the end of the string. In that case, it will end up passing through an empty hostname, which is correct.)
+ ++hostStart;
+ }
+ std::string::size_type hostEnd = authority.rfind(':');
+ if ((hostEnd == std::string::npos) || (hostEnd < hostStart))
+ {
+ // no port
+ hostEnd = authority.size();
+ }
+
+ std::string cookie_host = authority.substr(hostStart, hostEnd - hostStart);
+ std::string cookie_name = "";
+ std::string cookie_value = "";
+ std::string cookie_path = "";
+ bool httponly = true;
+ bool secure = true;
+ if (!parseRawCookie(mOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure))
+ {
+ return false;
+ }
+ std::string cefUrl(std::string(mOpenIDURL.mURI) + "://" + std::string(mOpenIDURL.mAuthority));
+ if (media_instance && media_instance->getMediaPlugin())
+ {
+ media_instance->getMediaPlugin()->setCookie(cefUrl, cookie_name, cookie_value, cookie_host,
+ cookie_path, httponly, secure);
+
+ media_instance->getMediaPlugin()->storeOpenIDCookie(cefUrl, cookie_name, cookie_value,
+ cookie_host, cookie_path, httponly, secure);
+ }
+ return true;
+}
/////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMedia::setOpenIDCookie(const std::string& url)
@@ -1267,7 +1347,7 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
bool secure = true;
LLViewerMedia* inst = getInstance();
- if (inst->parseRawCookie(inst->mOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure))
+ if (parseRawCookie(inst->mOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure))
{
// MAINT-5711 - inexplicably, the CEF setCookie function will no longer set the cookie if the
// url and domain are not the same. This used to be my.sl.com and id.sl.com respectively and worked.
@@ -1284,20 +1364,24 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
std::string browser_name;
};
struct MediaCookieInstance media_cookie_instances[] = {
- {"search", "search_contents" },
- {"marketplace", "marketplace_contents" },
+ {"search", "webbrowser" },
+ {"marketplace", "webbrowser" },
{"destinations", "destination_guide_contents" },
};
for (MediaCookieInstance mci : media_cookie_instances)
{
- LLMediaCtrl* media_instance = LLFloaterReg::getInstance(mci.floater_name)->getChild<LLMediaCtrl>(mci.browser_name);
- if (media_instance && media_instance->getMediaPlugin())
+ LLFloater *floaterp = LLFloaterReg::findInstance(mci.floater_name);
+ if (floaterp)
{
- media_instance->getMediaPlugin()->setCookie(cefUrl, cookie_name, cookie_value, cookie_host,
- cookie_path, httponly, secure);
+ LLMediaCtrl* media_instance = floaterp->getChild<LLMediaCtrl>(mci.browser_name);
+ if (media_instance && media_instance->getMediaPlugin())
+ {
+ media_instance->getMediaPlugin()->setCookie(cefUrl, cookie_name, cookie_value, cookie_host,
+ cookie_path, httponly, secure);
- media_instance->getMediaPlugin()->storeOpenIDCookie(cefUrl, cookie_name, cookie_value,
- cookie_host, cookie_path, httponly, secure);
+ media_instance->getMediaPlugin()->storeOpenIDCookie(cefUrl, cookie_name, cookie_value,
+ cookie_host, cookie_path, httponly, secure);
+ }
}
}
}
@@ -3018,7 +3102,10 @@ void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* da
// -Cosmic,2023-04-04
// Allocate GL texture based on LLImageRaw but do NOT copy to GL
LLGLuint tex_name = 0;
- media_tex->createGLTexture(0, raw, 0, true, LLGLTexture::OTHER, true, &tex_name);
+ if (!media_tex->createGLTexture(0, raw, 0, true, LLGLTexture::OTHER, true, &tex_name))
+ {
+ LL_WARNS("Media") << "Failed to create media texture" << LL_ENDL;
+ }
// copy just the subimage covered by the image raw to GL
media_tex->setSubImage(data, data_width, data_height, x_pos, y_pos, width, height, tex_name);
@@ -3087,7 +3174,10 @@ LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage()
mMediaSource->getTextureFormatSwapBytes());
int discard_level = 0;
- media_tex->createGLTexture(discard_level, raw);
+ if (!media_tex->createGLTexture(discard_level, raw))
+ {
+ LL_WARNS("Media") << "Failed to create media texture" << LL_ENDL;
+ }
// MEDIAOPT: set this dynamically on play/stop
// FIXME
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index c17cf59815..1fc5bbc9e0 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -69,6 +69,7 @@ private:
};
class LLViewerMediaImpl;
+class LLMediaCtrl;
class LLViewerMedia: public LLSingleton<LLViewerMedia>
{
@@ -162,22 +163,26 @@ public:
LLSD getHeaders();
LLCore::HttpHeaders::ptr_t getHttpHeaders();
+ bool getOpenIDCookie(LLMediaCtrl* media_instance) const;
private:
void onAuthSubmit(const LLSD& notification, const LLSD& response);
- bool parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path, bool& httponly, bool& secure);
+ static bool parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path, bool& httponly, bool& secure);
void setOpenIDCookie(const std::string& url);
void onTeleportFinished();
static void openIDSetupCoro(std::string openidUrl, std::string openidToken);
static void getOpenIDCookieCoro(std::string url);
+ void setMaxInstances(S32 max_instances);
bool mAnyMediaShowing;
bool mAnyMediaPlaying;
+ S32 mMaxIntances = 8;
LLURL mOpenIDURL;
std::string mOpenIDCookie;
LLPluginClassMedia* mSpareBrowserMediaSource;
boost::signals2::connection mTeleportFinishConnection;
+ boost::signals2::connection mMaxInstancesConnection;
};
// Implementation functions not exported into header file
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 452a2cec50..374a2ae075 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6531,7 +6531,7 @@ bool handle_zoom_to_object(const LLUUID& object_id)
LLViewerObject* object = gObjectList.findObject(object_id);
- if (object)
+ if (object && object->isReachable())
{
gAgentCamera.setFocusOnAvatar(false, ANIMATE);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index cd6cf869ae..c54feba06b 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3159,7 +3159,10 @@ void process_crossed_region(LLMessageSystem* msg, void**)
return;
}
LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL;
- gAgentAvatarp->resetRegionCrossingTimer();
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->resetRegionCrossingTimer();
+ }
U32 sim_ip;
msg->getIPAddrFast(_PREHASH_RegionData, _PREHASH_SimIP, sim_ip);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b0401b1425..c13e541da0 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5091,11 +5091,10 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
if (base_material && override_material)
{
tep->setGLTFMaterialOverride(new LLGLTFMaterial(*override_material));
-
- LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
- *render_material = *base_material;
- render_material->applyOverride(*override_material);
- tep->setGLTFRenderMaterial(render_material);
+ }
+ if (base_material)
+ {
+ initRenderMaterial(i);
}
}
}
@@ -5271,6 +5270,9 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)
});
}
getTE(te)->setGLTFMaterial(mat);
+ initRenderMaterial(te);
+ mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial();
+ llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(getTE(te)->getGLTFRenderMaterial()) != nullptr);
}
else if (mat_id.isNull() && mat != nullptr)
{
@@ -5660,6 +5662,42 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
return retval;
}
+// Set render material if there are overrides or if the base material is has a
+// baked texture. Otherwise, set it to null.
+// If you are setting the material override and not sending an update message,
+// you should probably call this function.
+S32 LLViewerObject::initRenderMaterial(U8 te)
+{
+ LL_PROFILE_ZONE_SCOPED;
+
+ LLTextureEntry* tep = getTE(te);
+ if (!tep) { return 0; }
+ const LLFetchedGLTFMaterial* base_material = static_cast<LLFetchedGLTFMaterial*>(tep->getGLTFMaterial());
+ llassert(base_material);
+ if (!base_material) { return 0; }
+ const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
+ LLFetchedGLTFMaterial* render_material = nullptr;
+ bool need_render_material = override_material;
+ if (!need_render_material)
+ {
+ for (const LLUUID& texture_id : base_material->mTextureId)
+ {
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(texture_id))
+ {
+ need_render_material = true;
+ break;
+ }
+ }
+ }
+ if (need_render_material)
+ {
+ render_material = new LLFetchedGLTFMaterial(*base_material);
+ if (override_material) { render_material->applyOverride(*override_material); }
+ render_material->clearFetchedTextures();
+ }
+ return tep->setGLTFRenderMaterial(render_material);
+}
+
S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat)
{
LL_PROFILE_ZONE_SCOPED;
@@ -5693,22 +5731,13 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
if (retval)
{
+ retval = initRenderMaterial(te) | retval;
if (override_mat)
{
- LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
- render_mat->applyOverride(*override_mat);
- tep->setGLTFRenderMaterial(render_mat);
- retval = TEM_CHANGE_TEXTURE;
-
for (LLGLTFMaterial::local_tex_map_t::value_type &val : override_mat->mTrackingIdToLocalTexture)
{
LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat);
}
-
- }
- else if (tep->setGLTFRenderMaterial(nullptr))
- {
- retval = TEM_CHANGE_TEXTURE;
}
}
@@ -7578,25 +7607,15 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
// the overrides have not changed due to being only texture
// transforms. Re-apply the overrides to the render material here,
// if present.
- const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
- if (override_material)
+ // Also, sometimes, the material has baked textures, which requires
+ // a copy unique to this object.
+ // Currently, we do not deduplicate render materials.
+ new_material->onMaterialComplete([obj_id = getID(), te]()
{
- new_material->onMaterialComplete([obj_id = getID(), te]()
- {
- LLViewerObject* obj = gObjectList.findObject(obj_id);
- if (!obj) { return; }
- LLTextureEntry* tep = obj->getTE(te);
- if (!tep) { return; }
- const LLGLTFMaterial* new_material = tep->getGLTFMaterial();
- if (!new_material) { return; }
- const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
- if (!override_material) { return; }
- LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
- *render_material = *new_material;
- render_material->applyOverride(*override_material);
- tep->setGLTFRenderMaterial(render_material);
- });
- }
+ LLViewerObject* obj = gObjectList.findObject(obj_id);
+ if (!obj) { return; }
+ obj->initRenderMaterial(te);
+ });
}
}
@@ -7718,6 +7737,51 @@ void LLViewerObject::clearTEWaterExclusion(const U8 te)
}
}
+bool LLViewerObject::isReachable()
+{
+ LLViewerRegion* agent_region = gAgent.getRegion();
+ LLViewerRegion* object_region = getRegion();
+
+ if (!agent_region || !object_region)
+ {
+ return false;
+ }
+ if (agent_region == object_region)
+ {
+ return true;
+ }
+
+ std::unordered_set<LLViewerRegion*> visited;
+ std::queue<LLViewerRegion*> pending;
+ visited.insert(agent_region);
+ pending.push(agent_region);
+
+ while (!pending.empty())
+ {
+ LLViewerRegion* current = pending.front();
+ pending.pop();
+
+ std::vector<LLViewerRegion*> neighbors;
+ current->getNeighboringRegions(neighbors);
+
+ for (LLViewerRegion* neighbor : neighbors)
+ {
+ if (!neighbor) continue;
+
+ if (neighbor == object_region)
+ {
+ return true;
+ }
+ // region's neighbors were not checked
+ if (visited.insert(neighbor).second)
+ {
+ pending.push(neighbor);
+ }
+ }
+ }
+ return false;
+}
+
class ObjectPhysicsProperties : public LLHTTPNode
{
public:
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 972f8cf846..6e26da74e7 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -249,6 +249,9 @@ public:
// Accessor functions
LLViewerRegion* getRegion() const { return mRegionp; }
+ // Check if object is reachable from agent region by traversing loaded neighboring regions
+ bool isReachable();
+
bool isSelected() const { return mUserSelected; }
// Check whole linkset
bool isAnySelected() const;
@@ -389,6 +392,7 @@ public:
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
+ S32 initRenderMaterial(const U8 te);
virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat);
// Used by Materials update functions to properly kick off rebuilds
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index c15fd86f71..0a6197a67a 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1070,7 +1070,7 @@ void LLViewerObjectList::fetchObjectCostsCoro(std::string url)
if (diff.empty())
{
- LL_INFOS() << "No outstanding object IDs to request. Pending count: " << mPendingObjectCost.size() << LL_ENDL;
+ LL_DEBUGS() << "No outstanding object IDs to request. Pending count: " << mPendingObjectCost.size() << LL_ENDL;
return;
}
@@ -1205,7 +1205,7 @@ void LLViewerObjectList::fetchPhisicsFlagsCoro(std::string url)
if (idList.size() < 1)
{
- LL_INFOS() << "No outstanding object physics flags to request." << LL_ENDL;
+ LL_DEBUGS() << "No outstanding object physics flags to request." << LL_ENDL;
return;
}
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 011269d7ee..1ac8b2f66b 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -229,6 +229,9 @@ extern LLTrace::EventStatHandle<F64Seconds > AVATAR_EDIT_TIME,
extern LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE;
+extern LLTrace::SampleStatHandle<F64> NOTRMALIZED_FRAMETIME_JITTER_SESSION;
+extern LLTrace::SampleStatHandle<F64> NORMALIZED_FRAMTIME_JITTER_PERIOD;
+
}
class LLViewerStats : public LLSingleton<LLViewerStats>
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e40f109e55..c7513ded62 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -406,7 +406,10 @@ void LLViewerTextureManager::init()
}
}
}
- imagep->createGLTexture(0, image_raw);
+ if (!imagep->createGLTexture(0, image_raw))
+ {
+ LL_WARNS() << "Failed to create default texture " << IMG_DEFAULT << LL_ENDL;
+ }
image_raw = NULL;
#else
LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, true, LLGLTexture::BOOST_UI);
@@ -2153,7 +2156,7 @@ bool LLViewerFetchedTexture::updateFetch()
}
const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
- if (override_tex_discard_level != 0)
+ if (override_tex_discard_level != 0 && override_tex_discard_level <= MAX_DISCARD_LEVEL)
{
desired_discard = override_tex_discard_level;
}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 9942ea3de8..ef24bcf598 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1466,18 +1466,43 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window)
LLToolTipMgr::instance().blockToolTips();
}
-bool LLViewerWindow::handleCloseRequest(LLWindow *window)
+bool LLViewerWindow::handleCloseRequest(LLWindow *window, bool from_user)
{
if (!LLApp::isExiting() && !LLApp::isStopped())
{
- // User has indicated they want to close, but we may need to ask
- // about modified documents.
- LLAppViewer::instance()->userQuit();
- // Don't quit immediately
+ if (from_user)
+ {
+ // User has indicated they want to close, but we may need to ask
+ // about modified documents.
+ LLAppViewer::instance()->userQuit();
+ // Don't quit immediately
+ }
+ else
+ {
+ // OS is asking us to quit, assume we have time and start cleanup
+ LLAppViewer::instance()->requestQuit();
+ }
}
return false;
}
+bool LLViewerWindow::handleSessionExit(LLWindow* window)
+{
+ if (!LLApp::isExiting() && !LLApp::isStopped())
+ {
+ // Viewer received WM_ENDSESSION and app will be killed soon if it doesn't respond
+ LLAppViewer* app = LLAppViewer::instance();
+ app->sendSimpleLogoutRequest();
+ app->earlyExitNoNotify();
+
+ // Not viewer's fault, remove marker files so
+ // that statistics won't consider this to be a crash
+ app->removeMarkerFiles();
+ return false;
+ }
+ return true;
+}
+
void LLViewerWindow::handleQuit(LLWindow *window)
{
if (gNonInteractive)
@@ -1897,7 +1922,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
p.ignore_pixel_depth,
0,
max_core_count,
- max_gl_version); //don't use window level anti-aliasing
+ max_gl_version); //don't use window level anti-aliasing, windows only
if (NULL == mWindow)
{
@@ -2299,36 +2324,23 @@ void LLViewerWindow::initWorldUI()
gToolBarView->setVisible(true);
}
- if (!gNonInteractive)
+ // Don't preload cef instances on low end hardware
+ const F32Gigabytes MIN_PHYSICAL_MEMORY(8);
+ F32Gigabytes physical_mem = LLMemory::getMaxMemKB();
+ if (physical_mem <= 0)
{
- LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
- if (destinations)
- {
- destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
- std::string url = gSavedSettings.getString("DestinationGuideURL");
- url = LLWeb::expandURLSubstitutions(url, LLSD());
- destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
- }
- LLMediaCtrl* avatar_welcome_pack = LLFloaterReg::getInstance("avatar_welcome_pack")->findChild<LLMediaCtrl>("avatar_picker_contents");
- if (avatar_welcome_pack)
- {
- avatar_welcome_pack->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
- std::string url = gSavedSettings.getString("AvatarWelcomePack");
- url = LLWeb::expandURLSubstitutions(url, LLSD());
- avatar_welcome_pack->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
- }
- LLMediaCtrl* search = LLFloaterReg::getInstance("search")->findChild<LLMediaCtrl>("search_contents");
- if (search)
- {
- search->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
- }
- LLMediaCtrl* marketplace = LLFloaterReg::getInstance("marketplace")->getChild<LLMediaCtrl>("marketplace_contents");
- if (marketplace)
- {
- marketplace->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
- std::string url = gSavedSettings.getString("MarketplaceURL");
- marketplace->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
- }
+ LLMemory::updateMemoryInfo();
+ physical_mem = LLMemory::getMaxMemKB();
+ }
+
+ if (!gNonInteractive && physical_mem > MIN_PHYSICAL_MEMORY)
+ {
+ LL_INFOS() << "Preloading cef instances" << LL_ENDL;
+
+ LLFloaterReg::getInstance("destinations");
+ LLFloaterReg::getInstance("avatar_welcome_pack");
+ LLFloaterReg::getInstance("search");
+ LLFloaterReg::getInstance("marketplace");
}
}
@@ -3317,7 +3329,31 @@ void LLViewerWindow::clearPopups()
void LLViewerWindow::moveCursorToCenter()
{
- if (! gSavedSettings.getBOOL("DisableMouseWarp"))
+ bool mouse_warp = false;
+ LLCachedControl<S32> mouse_warp_mode(gSavedSettings, "MouseWarpMode", 1);
+
+ switch (mouse_warp_mode())
+ {
+ case 0:
+ // For Windows:
+ // Mouse usually uses 'delta' position since it isn't aware of own location, keep it centered.
+ // Touch screen reports absolute or virtual absolute position and warping a physical
+ // touch is pointless, so don't move it.
+ //
+ // MacOS
+ // If 'decoupled', CGAssociateMouseAndMouseCursorPosition can make mouse stay in
+ // one place and not move, do not move it (needs testing).
+ mouse_warp = mWindow->isWrapMouse();
+ break;
+ case 1:
+ mouse_warp = true;
+ break;
+ default:
+ mouse_warp = false;
+ break;
+ }
+
+ if (mouse_warp)
{
S32 x = getWorldViewWidthScaled() / 2;
S32 y = getWorldViewHeightScaled() / 2;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index d55c2d3817..61aa84394c 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -197,7 +197,8 @@ public:
/*virtual*/ bool handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended
/*virtual*/ bool handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ bool handleCloseRequest(LLWindow *window);
+ /*virtual*/ bool handleCloseRequest(LLWindow *window, bool from_user);
+ /*virtual*/ bool handleSessionExit(LLWindow* window);
/*virtual*/ void handleQuit(LLWindow *window);
/*virtual*/ bool handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ bool handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 52a6afc2d0..5d456b1a19 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -498,7 +498,7 @@ void LLVOCacheEntry::updateDebugSettings()
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");
+ static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction", .75f);
const F32 min_radius_plus_one = sNearRadius + 1.f;
const F32 max_radius = rear_max_radius_frac * draw_radius;
const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance]
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 14f0b52174..40de236c90 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1023,7 +1023,6 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
std::string old_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SLVoice.old");
if (gDirUtilp->fileExists(new_log))
{
- LLFile::remove(old_log, ENOENT);
LLFile::rename(new_log, old_log);
}
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index e1667c505e..447f1b652a 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -296,10 +296,10 @@ void LLWebRTCVoiceClient::terminate()
LL_INFOS("Voice") << "Terminating WebRTC" << LL_ENDL;
mVoiceEnabled = false;
+ sShuttingDown = true; // so that coroutines won't post more work.
llwebrtc::terminate();
- mWebRTCDeviceInterface = nullptr;
- sShuttingDown = true;
+ mWebRTCDeviceInterface = nullptr;
}
//---------------------------------------------------
@@ -396,7 +396,7 @@ void LLWebRTCVoiceClient::updateSettings()
config.mNoiseSuppressionLevel = noiseSuppressionLevel;
audioConfigChanged = true;
}
- if (audioConfigChanged)
+ if (audioConfigChanged && mWebRTCDeviceInterface)
{
mWebRTCDeviceInterface->setAudioConfig(config);
}
@@ -797,7 +797,10 @@ void LLWebRTCVoiceClient::tuningStart()
{
if (!mIsInTuningMode)
{
- mWebRTCDeviceInterface->setTuningMode(true);
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setTuningMode(true);
+ }
mIsInTuningMode = true;
}
}
@@ -806,7 +809,10 @@ void LLWebRTCVoiceClient::tuningStop()
{
if (mIsInTuningMode)
{
- mWebRTCDeviceInterface->setTuningMode(false);
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->setTuningMode(false);
+ }
mIsInTuningMode = false;
}
}
@@ -839,6 +845,10 @@ void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume)
float LLWebRTCVoiceClient::tuningGetEnergy(void)
{
+ if (!mWebRTCDeviceInterface)
+ {
+ return 0.f;
+ }
float rms = mWebRTCDeviceInterface->getTuningAudioLevel();
return TUNING_LEVEL_START_POINT - TUNING_LEVEL_SCALE * rms;
}
@@ -866,7 +876,10 @@ void LLWebRTCVoiceClient::refreshDeviceLists(bool clearCurrentList)
clearCaptureDevices();
clearRenderDevices();
}
- mWebRTCDeviceInterface->refreshDevices();
+ if (mWebRTCDeviceInterface)
+ {
+ mWebRTCDeviceInterface->refreshDevices();
+ }
}
@@ -1174,7 +1187,7 @@ void LLWebRTCVoiceClient::sendPositionUpdate(bool force)
void LLWebRTCVoiceClient::updateOwnVolume()
{
F32 audio_level = 0.0f;
- if (!mMuteMic)
+ if (!mMuteMic && mWebRTCDeviceInterface)
{
float rms = mWebRTCDeviceInterface->getPeerConnectionAudioLevel();
audio_level = LEVEL_START_POINT - LEVEL_SCALE * rms;
@@ -2674,6 +2687,11 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio
void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
+ if (LLWebRTCVoiceClient::isShuttingDown())
+ {
+ mOutstandingRequests--;
+ return;
+ }
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
@@ -3281,6 +3299,12 @@ void LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
+ if (LLWebRTCVoiceClient::isShuttingDown())
+ {
+ mOutstandingRequests--;
+ return;
+ }
+
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
LL_DEBUGS("Voice") << "Requesting voice connection." << LL_ENDL;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index acdb1a3edb..4f828cc0ff 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -5025,7 +5025,7 @@ void LLRiggedVolume::update(
else
{
face_begin = face_index;
- face_end = face_begin + 1;
+ face_end = llmin(face_begin + 1, volume->getNumVolumeFaces());
}
for (S32 i = face_begin; i < face_end; ++i)
{
@@ -6764,7 +6764,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
&& te->getShiny()
&& can_be_shiny)
{ //shiny
- if (tex->getPrimaryFormat() == GL_ALPHA)
+ if (tex && tex->getPrimaryFormat() == GL_ALPHA)
{ //invisiprim+shiny
if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh())
{
@@ -6804,7 +6804,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
else
{ //not alpha and not shiny
- if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
+ if (!is_alpha && tex && tex->getPrimaryFormat() == GL_ALPHA)
{ //invisiprim
if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh())
{
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 7962c28e6d..153bee3aef 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -32,6 +32,7 @@
#include "message.h"
#include "lltracker.h"
#include "lluistring.h"
+#include "llviewercontrol.h"
#include "llviewertexturelist.h"
#include "lltrans.h"
#include "llgltexture.h"
@@ -492,9 +493,20 @@ bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID&
case MAP_ITEM_MATURE_EVENT:
case MAP_ITEM_ADULT_EVENT:
{
- std::string timeStr = "["+ LLTrans::getString ("TimeHour")+"]:["
- +LLTrans::getString ("TimeMin")+"] ["
- +LLTrans::getString ("TimeAMPM")+"]";
+ std::string timeStr;
+
+ static bool use_24h = gSavedSettings.getBOOL("Use24HourClock");
+ if (use_24h)
+ {
+ timeStr = "[" + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]";
+ }
+ else
+ {
+ timeStr = "[" + LLTrans::getString("TimeHour12") + "]:["
+ + LLTrans::getString("TimeMin") + "] ["
+ + LLTrans::getString("TimeAMPM") + "]";
+ }
LLSD substitution;
substitution["datetime"] = (S32) extra;
LLStringUtil::format (timeStr, substitution);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index dde8b8ed2a..1415e40ed8 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4509,7 +4509,7 @@ void LLPipeline::renderPhysicsDisplay()
gGL.flush();
gDebugProgram.bind();
- LLGLEnable(GL_POLYGON_OFFSET_LINE);
+ LLGLEnable polygon_offset_line(GL_POLYGON_OFFSET_LINE);
glPolygonOffset(3.f, 3.f);
//glLineWidth(3.f);
LLGLEnable blend(GL_BLEND);
@@ -11997,21 +11997,24 @@ public:
}
};
-
+// Called from LLViewHighlightTransparent when "Highlight Transparent" is toggled
void LLPipeline::rebuildDrawInfo()
{
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ const U32 types_to_traverse[] =
{
- LLViewerRegion* region = *iter;
-
- LLOctreeDirty dirty;
-
- LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME);
- dirty.traverse(part->mOctree);
+ LLViewerRegion::PARTITION_VOLUME,
+ LLViewerRegion::PARTITION_BRIDGE,
+ LLViewerRegion::PARTITION_AVATAR
+ };
- part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
- dirty.traverse(part->mOctree);
+ LLOctreeDirty dirty;
+ for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList())
+ {
+ for (U32 type : types_to_traverse)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(type);
+ dirty.traverse(part->mOctree);
+ }
}
}
diff --git a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
index d52845160b..e5ad86b315 100644
--- a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
@@ -15,6 +15,9 @@
<panel.string name="acquiredDate">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
</panel.string>
+ <panel.string name="acquiredDateAMPM">
+ [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour12,datetime,local]:[min,datetime,local]:[second,datetime,local] [ampm,datetime,local] [year,datetime,local]
+ </panel.string>
<panel.string name="origin_inventory">
(Beholdning)
</panel.string>
diff --git a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
index 168bb14248..3570ccacd2 100644
--- a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
@@ -21,6 +21,9 @@
<panel.string name="acquiredDate">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
</panel.string>
+ <panel.string name="acquiredDateAMPM">
+ [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour12,datetime,local]:[min,datetime,local]:[second,datetime,local] [ampm,datetime,local] [year,datetime,local]
+ </panel.string>
<panel.string name="origin_inventory">
(Inventar)
</panel.string>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 7284e4e6a8..a17eb22d89 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -5074,10 +5074,10 @@ Bitte ÃŒberprÃŒfen Sie http://status.secondlifegrid.net, um herauszufinden, ob e
[MDAY]
</string>
<string name="dateTimeAM">
- Uhr
+ AM
</string>
<string name="dateTimePM">
- Uhr
+ PM
</string>
<string name="LocalEstimateUSD">
[AMOUNT] US$
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 044e61ccbe..ae78e968ad 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -236,6 +236,8 @@ sse2neon Copyright (c) 2015-2024 SSE2NEON Contributors.
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+V-HACD Copyright (c) 2011, Khaled Mamou (kmamou at gmail dot com)
+
xxHash Copyright (C) 2012-2020 Yann Collet.
zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
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 508aba6ae1..c5b42b6dae 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -125,6 +125,9 @@
name="no_selection_text">
No parcel selected.
</panel.string>
+ <panel.string name="time_stamp_template_ampm">
+ [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour12,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [ampm,datetime,slt] [year,datetime,slt]
+ </panel.string>
<panel.string name="time_stamp_template">
[wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
</panel.string>
diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml
index 9403d58441..a083683c23 100644
--- a/indra/newview/skins/default/xui/en/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/en/floater_inspect.xml
@@ -12,6 +12,10 @@
title="INSPECT OBJECTS"
width="400">
<floater.string
+ name="timeStampAMPM">
+ [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour12,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [ampm,datetime,slt] [year,datetime,slt]
+ </floater.string>
+ <floater.string
name="timeStamp">
[wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
</floater.string>
diff --git a/indra/newview/skins/default/xui/en/floater_marketplace.xml b/indra/newview/skins/default/xui/en/floater_marketplace.xml
index 99fb3a1ad8..40bf674d2d 100644
--- a/indra/newview/skins/default/xui/en/floater_marketplace.xml
+++ b/indra/newview/skins/default/xui/en/floater_marketplace.xml
@@ -169,7 +169,7 @@
follows="all"
layout="topleft"
left="0"
- name="marketplace_contents"
+ name="webbrowser"
top="0"/>
</layout_panel>
<layout_panel name="status_bar"
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 f11d687840..39e9de0980 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -40,7 +40,7 @@
<string name="simplifying">Simplifying...</string>
<string name="tbd">TBD</string>
<string name="ModelTextureScaling">One or more textures in this model were scaled to be within the allowed limits.</string>
-
+
<!-- Warnings and info from model loader-->
<string name="TooManyJoint">Skinning disabled due to too many joints: [JOINTS], maximum: [MAX]</string>
<string name="UnrecognizedJoint">Rigged to unrecognized joint name [NAME]</string>
@@ -807,7 +807,7 @@
help_topic="upload_model_physics"
label="Physics"
name="physics_panel">
-
+
<!-- ==== STEP 1: Level of Detail ==== -->
<view_border
bevel_style="none"
@@ -873,7 +873,7 @@
<!-- <check_box name="physics_optimize" follows="left|top" width="130" left="10" top_pad="5" height="20" label="Optimize"/>
<check_box name="physics_use_hull" follows="left|top" width="130" left_pad="5" height="20" label="Use Convex Hull"/> -->
</panel>
-
+
<!-- ==== STEP 2: Analyze ==== -->
<view_border
bevel_style="none"
@@ -890,9 +890,9 @@
height="65"
follows="top|left"
left="18"
- name="physics analysis"
+ name="physics analysis havok"
top_pad="10"
- visible="true"
+ visible="false"
width="589">
<text
follows="left|top"
@@ -980,7 +980,131 @@
visible="false"
width="90"/>
</panel>
-
+ <panel
+ bg_alpha_color="0 0 0 0"
+ bg_opaque_color="0 0 0 0.3"
+ height="65"
+ follows="top|left"
+ left="18"
+ name="physics analysis vhacd"
+ top_delta="0"
+ visible="false"
+ width="589">
+ <text
+ follows="left|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="method_label"
+ text_color="White"
+ top_pad="0">
+ Step 2: Convert to hulls (optional)
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ name="analysis_method_label"
+ top_pad="10"
+ width="100">
+ Fill Mode:
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ name="quality_label"
+ layout="topleft"
+ left_pad="5"
+ width="85">
+ Resolution:
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ name="quality_label"
+ layout="topleft"
+ left_pad="25"
+ width="95">
+ Hulls per Mesh:
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ name="smooth_method_label"
+ layout="topleft"
+ left_pad="5"
+ width="95">
+ Vertices per hull:
+ </text>
+ <text
+ follows="top|left"
+ height="15"
+ name="tolerance_label"
+ layout="topleft"
+ left_pad="5"
+ width="100">
+ Error tolerance:
+ </text>
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ left="0"
+ name="Fill Mode"
+ top_pad="0"
+ height="20"
+ width="100"/>
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ left_pad="5"
+ name="Voxel Resolution"
+ height="20"
+ width="100"/>
+ <spinner
+ follows="top|left"
+ name="Num Hulls"
+ height="20"
+ left_pad="10"
+ width="60"
+ decimal_digits="0"
+ allow_digits_only="true"/>
+ <spinner
+ follows="top|left"
+ name="Num Vertices"
+ height="20"
+ left_pad="40"
+ width="60"
+ decimal_digits="0"
+ allow_digits_only="true"/>
+ <spinner
+ follows="top|left"
+ name="Error Tolerance"
+ height="20"
+ left_pad="40"
+ width="60"
+ decimal_digits="4"
+ allow_digits_only="true"/>
+ <button
+ bottom="1"
+ follows="top|right"
+ height="20"
+ label="Analyze"
+ layout="bottomleft"
+ name="Analyze"
+ right="-1"
+ width="90"/>
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left_delta="0"
+ name="analyze_cancel"
+ visible="false"
+ width="90"/>
+ </panel>
+
<!-- ==== STEP 3: Simplify ==== -->
<view_border
bevel_style="none"
@@ -999,7 +1123,8 @@
left="18"
name="physics simplification"
top_pad="10"
- width="589">
+ width="589"
+ visible="false">
<text
text_color="White"
follows="left|top"
@@ -1088,7 +1213,7 @@
name="simplify_cancel"
width="90"/>
</panel>
-
+
<!-- ==== Results ==== -->
<view_border
bevel_style="none"
@@ -1186,7 +1311,7 @@
name="modifiers_panel"
help_topic="upload_model_modifiers">
<view_border
- bevel_style="none"
+ bevel_style="none"
follows="top|left"
height="306"
layout="topleft"
@@ -1593,7 +1718,7 @@ Model:
[MODEL]
</text>
</panel>
- <!--
+ <!--
Streaming breakdown numbers are available but not fully understood
uncommenting the following sections will display the numbers for debugging purposes
<text
@@ -1695,7 +1820,7 @@ Analysed:
width="462"
visible="true">
You don't have rights to upload mesh models. [[VURL] Find out how] to get certified.
- </text>
+ </text>
<text
text_color="Yellow"
layout="topleft"
@@ -1706,7 +1831,7 @@ Analysed:
</text>
</panel>
</panel>
-
+
<text
follows="left|top"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index 43c4aa1b9d..8891ebcd87 100644
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
@@ -170,7 +170,7 @@
layout="topleft"
left="0"
trusted_content="true"
- name="search_contents"
+ name="webbrowser"
top="0"/>
</layout_panel>
<layout_panel name="status_bar"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index be40ca2f1f..5b9144e535 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1670,7 +1670,7 @@ The new skin will appear after you restart [APP_NAME].
icon="alertmodal.tga"
name="ChangeLanguage"
type="alertmodal">
-Changing language will take effect after you restart [APP_NAME].
+Changing language or time format will take effect after you restart [APP_NAME].
</notification>
<notification
@@ -2244,7 +2244,7 @@ Couldn&apos;t open uploaded sound file for reading:
Model upload is not yet available on Apple Silicon, but will be supported in an upcoming release.
Workaround: Right-click the Second Life app in Finder, select
-"Get Info", then check "Open using Rosetta"
+&apos;Get Info&apos;, then check &apos;Open using Rosetta&apos;
<tag>fail</tag>
</notification>
@@ -6595,6 +6595,22 @@ Do you want to replace it with the selected object?
</notification>
<notification
+ icon="alertmodal.tga"
+ name="CantLinkNotecard"
+ type="alertmodal">
+ You must save the notecard before creating a link to it.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantLinkMaterial"
+ type="alertmodal">
+ You must save the material before creating a link to it.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
icon="alert.tga"
label="Do Not Disturb Mode Warning"
name="DoNotDisturbModePay"
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index 02e135a2c7..868d54401e 100644
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel
- height="750"
+ height="770"
label="Members &amp; Roles"
layout="topleft"
left="0"
@@ -18,9 +18,9 @@
<panel.string
name="help_text" />
<tab_container
- border="false"
+ border="false"
follows="left|top|right"
- height="552"
+ height="770"
halign="center"
layout="topleft"
left="0"
@@ -29,16 +29,10 @@
tab_position="top"
tab_height="22"
tab_min_width="90"
- top="0"
- width="304">
+ top="0">
<panel
border="false"
- follows="all"
- height="303"
label="MEMBERS"
- layout="topleft"
- left="0"
- right="-1"
help_topic="roles_members_tab"
name="members_sub_tab"
tool_tip="Members"
@@ -65,16 +59,16 @@ clicking on their names.
name="power_partial_icon" translate="false">
Checkbox_Off
</panel.string>
- <filter_editor
- layout="topleft"
- top="5"
- left="5"
- right="-5"
- height="22"
- search_button_visible="false"
- follows="left|top|right"
- label="Filter Members"
- name="filter_input" />
+ <filter_editor
+ layout="topleft"
+ top="5"
+ left="5"
+ right="-5"
+ height="22"
+ search_button_visible="false"
+ follows="left|top|right"
+ label="Filter Members"
+ name="filter_input" />
<name_list
column_padding="2"
draw_heading="true"
@@ -90,11 +84,11 @@ clicking on their names.
<name_list.columns
label="Member"
name="name"
- relative_width="0.44" />
+ relative_width="0.44" />
<name_list.columns
label="Donation"
name="donated"
- relative_width="0.2" />
+ relative_width="0.2" />
<name_list.columns
label="Status"
name="online"
@@ -118,25 +112,21 @@ clicking on their names.
left_pad="10"
name="member_eject"
width="100" />
- <button
- height="23"
- label="Ban Member(s)"
- follows="top|left"
- left_pad="10"
- name="member_ban"
- width="100" />
+ <button
+ height="23"
+ label="Ban Member(s)"
+ follows="top|left"
+ left_pad="10"
+ name="member_ban"
+ width="100" />
</panel>
<panel
border="false"
- height="303"
label="ROLES"
- layout="topleft"
- left="0"
- right="-1"
help_topic="roles_roles_tab"
name="roles_sub_tab"
class="panel_group_roles_subtab">
- <!-- <button
+ <!--<button
enabled="false"
height="20"
label="Show All"
@@ -145,411 +135,393 @@ clicking on their names.
right="-5"
name="show_all_button"
width="100" />-->
- <panel.string
- name="help_text">
- Roles have a title and an allowed list of Abilities
- that Members can perform. Members can belong to
- one or more Roles. A group can have up to 10 Roles,
- including the Everyone and Owner Roles.
- </panel.string>
- <panel.string
- name="cant_delete_role">
- The &apos;Everyone&apos; and &apos;Owners&apos; Roles are special and can't be deleted.
- </panel.string>
- <panel.string
- name="power_folder_icon" translate="false">
- Inv_FolderClosed
- </panel.string>
- <panel.string
- name="power_all_have_icon" translate="false">
- Checkbox_On
- </panel.string>
- <panel.string
- name="power_partial_icon" translate="false">
- Checkbox_Off
- </panel.string>
- <filter_editor
- layout="topleft"
- top="5"
- left="5"
- right="-5"
- height="22"
- search_button_visible="false"
- follows="left|top|right"
- label="Filter Roles"
- name="filter_input" />
- <scroll_list
- column_padding="0"
- draw_heading="true"
- draw_stripes="false"
- heading_height="23"
- height="132"
- layout="topleft"
- search_column="1"
- left="0"
- follows="left|top|right"
- right="-1"
- name="role_list"
- top_pad="2"
- width="310">
- <scroll_list.columns
- label="Role"
- name="name"
- relative_width="0.45" />
- <scroll_list.columns
- label="Title"
- name="title"
- relative_width="0.45" />
- <scroll_list.columns
- label="#"
- name="members"
- relative_width="0.15" />
- </scroll_list>
- <button
- follows="top|left"
- height="23"
- label="New Role"
- layout="topleft"
- left="0"
- name="role_create"
- width="100" />
- <button
- follows="top|left"
- height="23"
- label="Copy Role"
- layout="topleft"
- left_pad="10"
- name="role_copy"
- width="100" />
- <button
- height="23"
- follows="top|left"
- label="Delete Role"
- layout="topleft"
- left_pad="10"
- name="role_delete"
- width="100" />
- </panel>
+ <panel.string
+ name="help_text">
+ Roles have a title and an allowed list of Abilities
+that Members can perform. Members can belong to
+one or more Roles. A group can have up to 10 Roles,
+including the Everyone and Owner Roles.
+ </panel.string>
+ <panel.string
+ name="cant_delete_role">
+ The &apos;Everyone&apos; and &apos;Owners&apos; Roles are special and can't be deleted.
+ </panel.string>
+ <panel.string
+ name="power_folder_icon" translate="false">
+ Inv_FolderClosed
+ </panel.string>
+ <panel.string
+ name="power_all_have_icon" translate="false">
+ Checkbox_On
+ </panel.string>
+ <panel.string
+ name="power_partial_icon" translate="false">
+ Checkbox_Off
+ </panel.string>
+ <filter_editor
+ layout="topleft"
+ top="5"
+ left="5"
+ right="-5"
+ height="22"
+ search_button_visible="false"
+ follows="left|top|right"
+ label="Filter Roles"
+ name="filter_input" />
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ draw_stripes="false"
+ heading_height="23"
+ height="138"
+ layout="topleft"
+ search_column="1"
+ left="0"
+ follows="left|top|right"
+ right="-1"
+ name="role_list"
+ top_pad="2">
+ <scroll_list.columns
+ label="Role"
+ name="name"
+ relative_width="0.45" />
+ <scroll_list.columns
+ label="Title"
+ name="title"
+ relative_width="0.45" />
+ <scroll_list.columns
+ label="#"
+ name="members"
+ relative_width="0.15" />
+ </scroll_list>
+ <button
+ follows="top|left"
+ height="23"
+ label="New Role"
+ layout="topleft"
+ left="0"
+ name="role_create"
+ width="100" />
+ <button
+ follows="top|left"
+ height="23"
+ label="Copy Role"
+ layout="topleft"
+ left_pad="10"
+ name="role_copy"
+ width="100" />
+ <button
+ height="23"
+ follows="top|left"
+ label="Delete Role"
+ layout="topleft"
+ left_pad="10"
+ name="role_delete"
+ width="100" />
+ </panel>
+ <panel
+ border="false"
+ label="ABILITIES"
+ help_topic="roles_actions_tab"
+ name="actions_sub_tab"
+ class="panel_group_actions_subtab"
+ tool_tip="You can view an Ability&apos;s Description and which Roles and Members can execute the Ability.">
+ <panel.string
+ name="help_text">
+ Abilities allow Members in Roles to do specific
+things in this group. There&apos;s a broad variety of Abilities.
+ </panel.string>
+ <panel.string
+ name="power_folder_icon" translate="false">
+ Inv_FolderClosed
+ </panel.string>
+ <panel.string
+ name="power_all_have_icon" translate="false">
+ Checkbox_On
+ </panel.string>
+ <panel.string
+ name="power_partial_icon" translate="false">
+ Checkbox_Off
+ </panel.string>
+ <filter_editor
+ layout="topleft"
+ top="5"
+ left="5"
+ right="-5"
+ height="22"
+ search_button_visible="false"
+ follows="left|top|right"
+ label="Filter Abilities"
+ name="filter_input" />
+ <scroll_list
+ column_padding="0"
+ draw_stripes="true"
+ height="200"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ right="-1"
+ name="action_list"
+ search_column="2"
+ tool_tip="Select an Ability to view more details"
+ top_pad="5">
+ <scroll_list.columns
+ label=""
+ name="icon"
+ width="2" />
+ <scroll_list.columns
+ label=""
+ name="checkbox"
+ width="20" />
+ <scroll_list.columns
+ label=""
+ name="action" />
+ </scroll_list>
+ </panel>
+ <panel
+ border="false"
+ label="BANNED RESIDENTS"
+ help_topic="roles_banlist_tab"
+ name="banlist_sub_tab"
+ class="panel_group_banlist_subtab"
+ tool_tip="View the banned residents from this group.">
+ <panel.string
+ name="help_text">
+ Any resident on the ban list will be unable to join the group.
+ </panel.string>
+ <panel.string
+ name="ban_count_template">
+ Ban count: [COUNT]/[LIMIT]
+ </panel.string>
+ <name_list
+ column_padding="0"
+ draw_heading="true"
+ height="714"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ right="-1"
+ multi_select="true"
+ name="ban_list"
+ short_names="false"
+ top_pad="5">
+ <name_list.columns
+ label="Resident"
+ name="name"
+ font.name="SANSSERIF_SMALL"
+ font.style="NORMAL"
+ relative_width="0.7" />
+ <name_list.columns
+ label="Date Banned"
+ name="ban_date"
+ relative_width="0.3" />
+ </name_list>
+ <button
+ follows="top|left"
+ height="23"
+ label="Ban Resident(s)"
+ layout="topleft"
+ left="3"
+ name="ban_create"
+ tool_tip="Ban residents from your group"
+ width="120" />
+ <button
+ follows="top|left"
+ height="23"
+ label="Remove Ban(s)"
+ layout="topleft"
+ left_pad="5"
+ name="ban_delete"
+ tool_tip="Unban selected residents from your group"
+ width="120" />
+ <button
+ follows="top|left"
+ height="23"
+ width="23"
+ image_overlay="Refresh_Off"
+ layout="topleft"
+ left_pad="5"
+ name="ban_refresh"
+ tool_tip="Refresh the ban list" />
+ <text
+ type="string"
+ height="18"
+ left_pad="5"
+ follows="top|left"
+ layout="topleft"
+ name="ban_count"
+ width="100">
+ </text>
+ </panel>
+ </tab_container>
<panel
- border="false"
- height="303"
- label="ABILITIES"
+ height="350"
+ background_visible="false"
+ bg_alpha_color="FloaterUnfocusBorderColor"
layout="topleft"
+ follows="top|left|right"
left="0"
right="-1"
- help_topic="roles_actions_tab"
- name="actions_sub_tab"
- class="panel_group_actions_subtab"
- tool_tip="You can view an Ability&apos;s Description and which Roles and Members can execute the Ability."
- width="310">
- <panel.string
- name="help_text">
- Abilities allow Members in Roles to do specific
- things in this group. There&apos;s a broad variety of Abilities.
- </panel.string>
- <panel.string
- name="power_folder_icon" translate="false">
- Inv_FolderClosed
- </panel.string>
- <panel.string
- name="power_all_have_icon" translate="false">
- Checkbox_On
- </panel.string>
- <panel.string
- name="power_partial_icon" translate="false">
- Checkbox_Off
- </panel.string>
- <filter_editor
- layout="topleft"
- top="5"
- left="5"
- right="-5"
- height="22"
- search_button_visible="false"
- follows="left|top|right"
- label="Filter Abilities"
- name="filter_input" />
- <scroll_list
- column_padding="0"
- draw_stripes="true"
- height="200"
- follows="left|top|right"
- layout="topleft"
- left="0"
- right="-1"
- name="action_list"
- search_column="2"
- tool_tip="Select an Ability to view more details"
- top_pad="5"
- width="300">
- <scroll_list.columns
- label=""
- name="icon"
- width="2" />
- <scroll_list.columns
- label=""
- name="checkbox"
- width="20" />
- <scroll_list.columns
- label=""
- name="action" />
- </scroll_list>
+ mouse_opaque="false"
+ name="members_footer"
+ top="325"
+ visible="false">
+ <text
+ type="string"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="5"
+ top="8"
+ text_color="EmphasisColor"
+ name="static"
+ width="300">
+ Assigned Roles
+ </text>
+ <scroll_list
+ draw_stripes="true"
+ follows="left|top|right"
+ height="150"
+ layout="topleft"
+ left="0"
+ right="-1"
+ name="member_assigned_roles"
+ top_pad="0">
+ <scroll_list.columns
+ label=""
+ name="checkbox"
+ width="20" />
+ <scroll_list.columns
+ label=""
+ name="role"
+ width="270" />
+ </scroll_list>
+ <text
+ type="string"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="5"
+ top_pad="5"
+ text_color="EmphasisColor"
+ name="static2"
+ width="285">
+ Allowed Abilities
+ </text>
+ <scroll_list
+ draw_stripes="true"
+ follows="left|top|right"
+ height="150"
+ layout="topleft"
+ left="0"
+ right="-1"
+ name="member_allowed_actions"
+ search_column="2"
+ tool_tip="For details of each allowed ability see the abilities tab"
+ top_pad="0">
+ <scroll_list.columns
+ label=""
+ name="icon"
+ width="2" />
+ <scroll_list.columns
+ label=""
+ name="checkbox"
+ width="20" />
+ <scroll_list.columns
+ label=""
+ name="action"
+ width="270" />
+ </scroll_list>
</panel>
<panel
- border="false"
- height="303"
- label="BANNED RESIDENTS"
+ height="90"
+ background_visible="false"
+ bg_alpha_color="FloaterUnfocusBorderColor"
layout="topleft"
+ follows="top|left|right"
left="0"
right="-1"
- help_topic="roles_banlist_tab"
- name="banlist_sub_tab"
- class="panel_group_banlist_subtab"
- tool_tip="View the banned residents from this group."
- width="310">
- <panel.string
- name="help_text">
- Any resident on the ban list will be unable to join the group.
- </panel.string>
- <panel.string
- name="ban_count_template">
- Ban count: [COUNT]/[LIMIT]
- </panel.string>
- <name_list
- column_padding="0"
- draw_heading="true"
- height="400"
- follows="left|top|right"
- layout="topleft"
- left="0"
- right="-1"
- multi_select="true"
- name="ban_list"
- short_names="false"
- top_pad="5">
- <name_list.columns
- label="Resident"
- name="name"
- font.name="SANSSERIF_SMALL"
- font.style="NORMAL"
- relative_width="0.7" />
- <name_list.columns
- label="Date Banned"
- name="ban_date"
- relative_width="0.3" />
- </name_list>
- <button
- follows="top|left"
- height="23"
- label="Ban Resident(s)"
- layout="topleft"
- left="3"
- name="ban_create"
- tool_tip="Ban residents from your group"
- width="120" />
- <button
- follows="top|left"
- height="23"
- label="Remove Ban(s)"
- layout="topleft"
- left_pad="5"
- name="ban_delete"
- tool_tip="Unban selected residents from your group"
- width="120" />
- <button
- follows="top|left"
- height="23"
- width="23"
- image_overlay="Refresh_Off"
- layout="topleft"
- left_pad="5"
- name="ban_refresh"
- tool_tip="Refresh the ban list"
- />
- <text
- type="string"
- height="18"
- left_pad="5"
- follows="top|left"
- layout="topleft"
- name="ban_count"
- width="100">
- </text>
+ mouse_opaque="false"
+ name="members_header"
+ top_pad="3"
+ visible="false">
+ <text_editor
+ bg_readonly_color="Transparent"
+ text_readonly_color="EmphasisColor"
+ font="SansSerifSmall"
+ type="string"
+ enabled="false"
+ halign="left"
+ layout="topleft"
+ top_pad="0"
+ follows="left|top|right"
+ left="0"
+ right="-1"
+ height="90"
+ max_length="512"
+ name="member_action_description"
+ word_wrap="true">
+ This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
+ </text_editor>
</panel>
- </tab_container>
- <panel
- height="350"
- background_visible="false"
- bg_alpha_color="FloaterUnfocusBorderColor"
- layout="topleft"
- follows="top|left|right"
- left="0"
- right="-1"
- width="313"
- mouse_opaque="false"
- name="members_footer"
- top="325"
- visible="false">
- <text
- type="string"
- height="16"
- layout="topleft"
- follows="left|top"
- left="5"
- top="8"
- text_color="EmphasisColor"
- name="static"
- width="300">
- Assigned Roles
- </text>
- <scroll_list
- draw_stripes="true"
- follows="left|top|right"
- height="150"
+ <panel
+ height="460"
+ background_visible="false"
+ bg_alpha_color="FloaterUnfocusBorderColor"
layout="topleft"
+ follows="top|left|right"
left="0"
right="-1"
- name="member_assigned_roles"
- top_pad="0">
- <scroll_list.columns
- label=""
- name="checkbox"
- width="20" />
- <scroll_list.columns
- label=""
- name="role"
- width="270" />
- </scroll_list>
- <text
- type="string"
- height="16"
- layout="topleft"
- follows="left|top"
- left="5"
- top_pad="5"
- text_color="EmphasisColor"
- name="static2"
- width="285">
- Allowed Abilities
- </text>
- <scroll_list
- draw_stripes="true"
+ mouse_opaque="false"
+ name="roles_footer"
+ top_delta="0"
+ top="215"
+ visible="false">
+ <text
+ type="string"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="5"
+ top="5"
+ name="static"
+ width="300">
+ Role Name
+ </text>
+ <line_editor
+ type="string"
+ height="20"
+ layout="topleft"
+ left="0"
follows="left|top|right"
- height="150"
- layout="topleft"
- left="0"
- right="-1"
- name="member_allowed_actions"
- search_column="2"
- tool_tip="For details of each allowed ability see the abilities tab"
- top_pad="0">
- <scroll_list.columns
- label=""
- name="icon"
- width="2" />
- <scroll_list.columns
- label=""
- name="checkbox"
- width="20" />
- <scroll_list.columns
- label=""
- name="action"
- width="270" />
- </scroll_list>
- </panel>
- <panel
- height="90"
- background_visible="false"
- bg_alpha_color="FloaterUnfocusBorderColor"
- layout="topleft"
- follows="top|left|right"
- left="0"
- right="-1"
- width="313"
- mouse_opaque="false"
- name="members_header"
- top_pad="3"
- visible="false">
- <text_editor
- bg_readonly_color="Transparent"
- text_readonly_color="EmphasisColor"
- font="SansSerifSmall"
- type="string"
- enabled="false"
- halign="left"
- layout="topleft"
- top_pad="0"
- follows="left|top|right"
- left="0"
- right="-1"
- height="90"
- max_length="512"
- name="member_action_description"
- word_wrap="true">
- This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
- </text_editor>
- </panel>
- <panel
- height="460"
- background_visible="false"
- bg_alpha_color="FloaterUnfocusBorderColor"
- layout="topleft"
- follows="top|left|right"
- left="0"
- right="-1"
- width="313"
- mouse_opaque="false"
- name="roles_footer"
- top_delta="0"
- top="209"
- visible="false">
- <text
- type="string"
- height="16"
- layout="topleft"
- follows="left|top"
- left="5"
- top="5"
- name="static"
- width="300">
- Role Name
- </text>
- <line_editor
- type="string"
- height="20"
- layout="topleft"
- left="0"
- follows="left|top|right"
- right="-1"
- max_length_bytes="20"
- name="role_name"
- top_pad="0"
- width="300">
- </line_editor>
- <text
- type="string"
- height="16"
- layout="topleft"
- follows="left|top"
- left="5"
- name="static3"
- top_pad="5"
- width="300">
- Role Title
- </text>
- <line_editor
- type="string"
- height="20"
- layout="topleft"
- left="0"
- follows="left|top|right"
- right="-1"
- max_length_bytes="20"
- name="role_title"
- top_pad="0"
- width="300">
- </line_editor>
- <text
+ right="-1"
+ max_length_bytes="20"
+ name="role_name"
+ top_pad="0">
+ </line_editor>
+ <text
+ type="string"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="5"
+ name="static3"
+ top_pad="5"
+ width="300">
+ Role Title
+ </text>
+ <line_editor
+ type="string"
+ height="20"
+ layout="topleft"
+ left="0"
+ follows="left|top|right"
+ right="-1"
+ max_length_bytes="20"
+ name="role_title"
+ top_pad="0">
+ </line_editor>
+ <text
type="string"
height="16"
layout="topleft"
@@ -558,192 +530,185 @@ clicking on their names.
name="static2"
top_pad="5"
width="200">
- Description
- </text>
- <text_editor
- type="string"
- layout="topleft"
- left="0"
- follows="left|top|right"
- right="-1"
- max_length="295"
- height="35"
- name="role_description"
- top_pad="0"
- width="300"
- word_wrap="true">
- </text_editor>
- <text
- type="string"
- height="16"
- layout="topleft"
- follows="left|top"
- left="5"
- text_color="EmphasisColor"
- name="static4"
- top_pad="5"
- width="300">
- Assigned Members
- </text>
- <name_list
- draw_stripes="true"
- height="128"
- layout="topleft"
- left="0"
- follows="left|top|right"
- right="-1"
- name="role_assigned_members"
- top_pad="0"
- width="300" />
- <check_box
- height="15"
- label="Reveal members"
- left="5"
- layout="topleft"
- name="role_visible_in_list"
- tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."
- top_pad="4"
- width="300" />
- <text
- type="string"
- height="16"
- layout="topleft"
- follows="left|top"
- left="5"
- text_color="EmphasisColor"
- name="static5"
- top_pad="2"
- width="300">
- Allowed Abilities
- </text>
- <scroll_list
- draw_stripes="true"
- height="140"
- layout="topleft"
- left="0"
- follows="left|top|right"
- right="-1"
- name="role_allowed_actions"
- search_column="2"
- tool_tip="For details of each allowed ability see the abilities tab"
- top_pad="0"
- width="300">
- <scroll_list.columns
- label=""
- name="icon"
- width="2" />
- <scroll_list.columns
- label=""
- name="checkbox"
- width="20" />
- <scroll_list.columns
- label=""
- name="action" />
- </scroll_list>
- </panel>
- <panel
- height="90"
- background_visible="false"
- bg_alpha_color="FloaterUnfocusBorderColor"
- layout="topleft"
- follows="top|left|right"
- left="0"
- right="-1"
- width="313"
- mouse_opaque="false"
- name="roles_header"
- top_pad="3"
- visible="false">
- <text_editor
- bg_readonly_color="Transparent"
- text_readonly_color="EmphasisColor"
- font="SansSerifSmall"
- type="string"
- enabled="false"
- halign="left"
- layout="topleft"
- top_pad="0"
- follows="left|top|right"
- left="0"
- right="-1"
+ Description
+ </text>
+ <text_editor
+ type="string"
+ layout="topleft"
+ left="0"
+ follows="left|top|right"
+ right="-1"
+ max_length="295"
+ height="35"
+ name="role_description"
+ top_pad="0"
+ word_wrap="true">
+ </text_editor>
+ <text
+ type="string"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="5"
+ text_color="EmphasisColor"
+ name="static4"
+ top_pad="5"
+ width="300">
+ Assigned Members
+ </text>
+ <name_list
+ draw_stripes="true"
+ height="128"
+ layout="topleft"
+ left="0"
+ follows="left|top|right"
+ right="-1"
+ name="role_assigned_members"
+ top_pad="0" />
+ <check_box
+ height="15"
+ label="Reveal members"
+ left="5"
+ layout="topleft"
+ name="role_visible_in_list"
+ tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."
+ top_pad="4"
+ width="300" />
+ <text
+ type="string"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="5"
+ text_color="EmphasisColor"
+ name="static5"
+ top_pad="2"
+ width="300">
+ Allowed Abilities
+ </text>
+ <scroll_list
+ draw_stripes="true"
+ height="140"
+ layout="topleft"
+ left="0"
+ follows="left|top|right"
+ right="-1"
+ name="role_allowed_actions"
+ search_column="2"
+ tool_tip="For details of each allowed ability see the abilities tab"
+ top_pad="0">
+ <scroll_list.columns
+ label=""
+ name="icon"
+ width="2" />
+ <scroll_list.columns
+ label=""
+ name="checkbox"
+ width="20" />
+ <scroll_list.columns
+ label=""
+ name="action" />
+ </scroll_list>
+ </panel>
+ <panel
height="90"
- max_length="512"
- name="role_action_description"
- word_wrap="true">
- This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
- </text_editor>
- </panel>
- <panel
- height="424"
- background_visible="false"
- bg_alpha_color="FloaterUnfocusBorderColor"
- layout="topleft"
- follows="top|left|right"
- left="0"
- right="-1"
- width="313"
- mouse_opaque="false"
- name="actions_footer"
- top_delta="0"
- top="255"
- visible="false">
- <text_editor
- bg_readonly_color="Transparent"
- text_readonly_color="EmphasisColor"
- font="SansSerifSmall"
- type="string"
- enabled="false"
- halign="left"
+ background_visible="false"
+ bg_alpha_color="FloaterUnfocusBorderColor"
layout="topleft"
- follows="left|top|right"
+ follows="top|left|right"
left="0"
right="-1"
- height="90"
- max_length="512"
- name="action_description"
- top="0"
- word_wrap="true">
- This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
- </text_editor>
- <text
- type="string"
- height="16"
- layout="topleft"
- follows="left|top"
- left="5"
- name="static2"
- top_pad="1"
- width="300">
- Roles with this ability
- </text>
- <scroll_list
- height="172"
- layout="topleft"
- follows="left|top|right"
- left="5"
- right="-1"
- name="action_roles"
- top_pad="0"
- width="300" />
- <text
- type="string"
- height="16"
- layout="topleft"
- follows="left|top"
- left="5"
- name="static3"
- top_pad="5"
- width="300">
- Members with this ability
- </text>
- <name_list
- height="122"
- follows="left|top|right"
+ mouse_opaque="false"
+ name="roles_header"
+ top_pad="3"
+ visible="false">
+ <text_editor
+ bg_readonly_color="Transparent"
+ text_readonly_color="EmphasisColor"
+ font="SansSerifSmall"
+ type="string"
+ enabled="false"
+ halign="left"
+ layout="topleft"
+ top_pad="0"
+ follows="left|top|right"
+ left="0"
+ right="-1"
+ height="90"
+ max_length="512"
+ name="role_action_description"
+ word_wrap="true">
+ This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
+ </text_editor>
+ </panel>
+ <panel
+ height="513"
+ background_visible="false"
+ bg_alpha_color="FloaterUnfocusBorderColor"
layout="topleft"
- left="5"
+ follows="top|left|right"
+ left="0"
right="-1"
- name="action_members"
- top_pad="0"
- width="300" />
- </panel>
+ mouse_opaque="false"
+ name="actions_footer"
+ top_delta="0"
+ top="255"
+ visible="false">
+ <text_editor
+ bg_readonly_color="Transparent"
+ text_readonly_color="EmphasisColor"
+ font="SansSerifSmall"
+ type="string"
+ enabled="false"
+ halign="left"
+ layout="topleft"
+ follows="left|top|right"
+ left="0"
+ right="-1"
+ height="90"
+ max_length="512"
+ name="action_description"
+ top="0"
+ word_wrap="true">
+ This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
+ </text_editor>
+ <text
+ type="string"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="5"
+ name="static2"
+ top_pad="1"
+ width="300">
+ Roles with this ability
+ </text>
+ <scroll_list
+ height="216"
+ layout="topleft"
+ follows="left|top|right"
+ left="5"
+ right="-1"
+ name="action_roles"
+ top_pad="0" />
+ <text
+ type="string"
+ height="16"
+ layout="topleft"
+ follows="left|top"
+ left="5"
+ name="static3"
+ top_pad="5"
+ width="300">
+ Members with this ability
+ </text>
+ <name_list
+ height="167"
+ follows="left|top|right"
+ layout="topleft"
+ left="5"
+ right="-1"
+ name="action_members"
+ top_pad="0" />
+ </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index e25145dd2a..9cb64e7a13 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -40,6 +40,10 @@
Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner.
</string>
<string
+ name="acquired_date_ampm">
+ [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour12,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [ampm,datetime,slt] [year,datetime,slt]
+ </string>
+ <string
name="acquired_date">
[wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
</string>
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index 9aa0907a38..66cd1cacf1 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -89,6 +89,10 @@
Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner.
</string>
<string
+ name="acquired_date_ampm">
+ [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour12,datetime,local]:[min,datetime,local]:[second,datetime,local] [ampm,datetime,local] [year,datetime,local]
+ </string>
+ <string
name="acquired_date">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
</string>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 101c506309..ddddb4855f 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -91,6 +91,37 @@
name="Traditional Chinese"
value="zh" />
</combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left="255"
+ name="time_format_textbox"
+ top="10"
+ width="200">
+ Time Format:
+ </text>
+ <combo_box
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left="255"
+ max_chars="135"
+ name="time_format_combobox"
+ width="70">
+ <combo_box.item
+ enabled="true"
+ label="1:00 AM"
+ name="12H"
+ value="0" />
+ <combo_box.item
+ enabled="true"
+ label="13:00"
+ name="24H"
+ value="1" />
+ </combo_box>
<text
font="SansSerifSmall"
type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
index 395efe3169..eee55bd7bc 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
@@ -202,9 +202,43 @@
height="10"
layout="topleft"
left="86"
- name="single_click_action_lbl"
+ name="mouse_warp_lbl"
width="150"
top_pad="20">
+ Mouse Warp:
+ </text>
+ <combo_box
+ control_name="MouseWarpMode"
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ top_delta="-6"
+ name="mouse_warp_combo"
+ tool_tip="Controls warping of the mouse to the center of the screen during alt-zoom and mouse look."
+ width="200">
+ <combo_box.item
+ label="Automatic"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="On"
+ name="1"
+ value="1"/>
+ <combo_box.item
+ label="Off"
+ name="2"
+ value="2"/>
+ </combo_box>
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="86"
+ name="single_click_action_lbl"
+ width="150"
+ top_pad="12">
Single click on land:
</text>
<combo_box
@@ -266,7 +300,7 @@
layout="topleft"
left="83"
name="sound_on_collisions"
- top_pad="10"
+ top_pad="0"
width="200" />
<check_box
control_name="DoubleClickZoomIn"
@@ -275,7 +309,7 @@
layout="topleft"
left="83"
name="double_click_zoom_in"
- top_pad="10"
+ top_pad="0"
width="200" />
<button
height="23"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
index 6554dd0952..831b631505 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
@@ -22,7 +22,6 @@
<profile_image
name="real_world_pic"
image_name="Generic_Person_Large"
- show_loading="false"
follows="top|left"
layout="topleft"
top="10"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
index e361a0f28c..4d4c7f2252 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
@@ -74,7 +74,6 @@ Account: [ACCTTYPE]
<profile_image
name="2nd_life_pic"
image_name="Generic_Person_Large"
- show_loading="false"
layout="topleft"
follows="all"
interactable="true"
@@ -191,7 +190,7 @@ Account: [ACCTTYPE]
visible="false">
<icon
name="badge_icon"
- image_name="Beta_Tester"
+ image_name="Profile_Badge_Beta"
layout="topleft"
follows="left|top"
top="10"
diff --git a/indra/newview/skins/default/xui/en/panel_sound_devices.xml b/indra/newview/skins/default/xui/en/panel_sound_devices.xml
index 7598f7d7e5..b858d0ed02 100644
--- a/indra/newview/skins/default/xui/en/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/en/panel_sound_devices.xml
@@ -20,6 +20,10 @@
name="name_default_system_device">
Default System Device
</string>
+ <string
+ name="device_not_loaded">
+ Device not loaded
+ </string>
<icon
follows="left|top"
height="18"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index 1cb3eca2eb..40a88d4121 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -32,6 +32,10 @@
Owner can:
</panel.string>
<panel.string
+ name="acquiredDateAMPM">
+ [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour12,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [ampm,datetime,slt] [year,datetime,slt]
+ </panel.string>
+ <panel.string
name="acquiredDate">
[wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt]
</panel.string>
diff --git a/indra/newview/skins/default/xui/ja/control_table_contents_columns_basic.xml b/indra/newview/skins/default/xui/ja/control_table_contents_columns_basic.xml
index 83f204648d..db833e2c8e 100644
--- a/indra/newview/skins/default/xui/ja/control_table_contents_columns_basic.xml
+++ b/indra/newview/skins/default/xui/ja/control_table_contents_columns_basic.xml
@@ -2,6 +2,6 @@
<contents>
<columns label="アクション" name="lst_action"/>
<columns label="優先コントロヌル" name="lst_ctrl1"/>
- <columns label="代わり" name="lst_ctrl2"/>
- <columns label="代わり" name="lst_ctrl3"/>
+ <columns label="代替1" name="lst_ctrl2"/>
+ <columns label="代替2" name="lst_ctrl3"/>
</contents>
diff --git a/indra/newview/skins/default/xui/ja/floater_360capture.xml b/indra/newview/skins/default/xui/ja/floater_360capture.xml
index d0a6eef0e0..4199327e88 100644
--- a/indra/newview/skins/default/xui/ja/floater_360capture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_360capture.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="360capture" title="床ショット">
+<floater name="360capture" title="360床スナップショット">
<panel name="ui_panel_left">
<text name="quality_level_label">
品質
@@ -11,7 +11,7 @@
<radio_item label="最高品䜍" name="maximum_quality" value="2048" tool_tip="最高品質"/>
</radio_group>
<check_box label="アバタヌをすべお隠す" name="360_hide_avatar"/>
- <button label="床画像を䜜成" name="capture_button"/>
+ <button label="360床画像を䜜成" name="capture_button"/>
<button label="名前を぀けお保存 " name="save_local_button"/>
</panel>
<panel name="ui_panel_right">
diff --git a/indra/newview/skins/default/xui/ja/floater_about_land.xml b/indra/newview/skins/default/xui/ja/floater_about_land.xml
index 7da5f41f90..ed057704fe 100644
--- a/indra/newview/skins/default/xui/ja/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about_land.xml
@@ -45,7 +45,7 @@
[AREA]㎡
</panel.string>
<panel.string name="auction_id_text">
- オヌクション[ID]
+ オヌクションID[ID]
</panel.string>
<panel.string name="need_tier_to_modify">
この土地を修正倉曎するには、賌入を承認する必芁がありたす。
@@ -72,7 +72,7 @@
区画が遞択されおいたせん。
</panel.string>
<panel.string name="time_stamp_template">
- [year,datetime,local]幎[mth,datetime,local]月[day,datetime,local]日[wkday,datetime,local] [hour,datetime,local][min,datetime,local][second,datetime,local]
+ [year,datetime,local]幎[mth,datetime,local]月[day,datetime,local]日[wkday,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local]
</panel.string>
<text name="Name:">
名前
@@ -85,7 +85,7 @@
皮類
</text>
<text name="LandTypeText">
- メむンランド入怍地
+ メむンランド / ホヌムステッド
</text>
<text name="ContentRating">
区分
@@ -136,7 +136,7 @@
4048m²
</text>
<text name="Traffic:">
- トラフィック
+ 亀通量
</text>
<text name="DwellText">
読み蟌んでいたす 
@@ -178,7 +178,7 @@
この䞍動産には玄欟がありたせん。
</text_editor>
<text name="covenant_timestamp_text">
- 最埌曎新1969幎12月31日氎曜日 160000
+ 最埌曎新1969幎12月31日氎曜日 16:00:00
</text>
<text font="SansSerifLarge" name="region_section_lbl">
地域
@@ -190,7 +190,7 @@
皮類
</text>
<text name="region_landtype_text">
- メむンランド入怍地
+ メむンランド / ホヌムステッド
</text>
<text name="region_maturity_lbl">
区分
@@ -270,7 +270,7 @@
[COUNT]個
</text>
<text name="Autoreturn">
- 他者のオブゞェクトの自動返华分単䜍、で自動返华なし
+ 他者のオブゞェクトの自動返华分単䜍、0で自動返华なし
</text>
<line_editor name="clean other time"/>
<text name="Object Owners:">
@@ -291,7 +291,7 @@
この区画を怜玢結果に衚瀺する
</panel.string>
<panel.string name="search_disabled_small_tooltip">
- 区画面積が㎡未満のため、このオプションは無効です。
+ 区画面積が128㎡未満のため、このオプションは無効です。
倧きな区画のみ怜玢に衚瀺させるこずが可胜です。
</panel.string>
<panel.string name="search_disabled_permissions_tooltip">
@@ -385,7 +385,7 @@
<text name="with media:">
皮類
</text>
- <combo_box name="media type" tool_tip="動画や、Webペヌゞ、その他のメディアのを指定したす。"/>
+ <combo_box name="media type" tool_tip="動画や、Webペヌゞ、その他のメディアのURLを指定したす。"/>
<text name="at URL:">
ホヌムペヌゞ
</text>
@@ -402,11 +402,11 @@
このテクスチャを䜿甚するオブゞェクトの「再生」をクリックするず、動画やWebペヌゞを衚瀺したす。テクスチャを倉曎するにはサムネむルを遞択しおください。
</text>
<check_box label="スケヌルを自動蚭定" name="media_auto_scale" tool_tip="このオプションをチェックするず、この区画のコンテンツのスケヌルが自動的に蚭定されたす。動䜜速床ず画質が少し䜎䞋するこずがありたすが、他のテクスチャのスケヌリングや敎列が必芁になるこずはありたせん。"/>
- <text name="media_size" tool_tip="レンダリングするWebメディアのサむズです。デフォルトののたたにしたす。">
+ <text name="media_size" tool_tip="レンダリングするWebメディアのサむズです。デフォルトの0のたたにしたす。">
サむズ
</text>
- <spinner name="media_size_width" tool_tip="レンダリングするWebメディアのサむズです。デフォルトののたたにしたす。"/>
- <spinner name="media_size_height" tool_tip="レンダリングするWebメディアのサむズです。デフォルトののたたにしたす。"/>
+ <spinner name="media_size_width" tool_tip="レンダリングするWebメディアのサむズです。デフォルトの0のたたにしたす。"/>
+ <spinner name="media_size_height" tool_tip="レンダリングするWebメディアのサむズです。デフォルトの0のたたにしたす。"/>
<text name="pixels">
ピクセル
</text>
@@ -417,7 +417,7 @@
</panel>
<panel label="サりンド" name="land_audio_panel">
<text name="MusicURL:">
- 音楜
+ 音楜URL
</text>
<text name="Sound:">
サりンド
@@ -443,7 +443,7 @@
぀以䞊のオプションが、䞍動産レベルで蚭定されおいたす。
</panel.string>
<check_box label="誰でも蚪問可このオプションをオフにするず立入犁止ラむンが䜜成されたす" name="public_access"/>
- <check_box label="歳以䞊である必芁がありたす。[ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="この区画にアクセスするには、歳以䞊でなければなりたせん。詳现に぀きたしおは、[SUPPORT_SITE]をご芧になっおください。"/>
+ <check_box label="18歳以䞊である必芁がありたす。[ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="この区画にアクセスするには、18歳以䞊でなければなりたせん。詳现に぀きたしおは、[SUPPORT_SITE]をご芧になっおください。"/>
<check_box label="支払情報が登録されおいる必芁がありたす。[ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="アカりントに支払情報が登録されおいない堎合、この区画にアクセスするこずはできたせん。詳现に぀きたしおは、[SUPPORT_SITE]をご芧になっおください。"/>
<check_box label="制玄なしにグルヌプ[GROUP]を蚱可する。" name="GroupCheck" tool_tip="「䞀般」タブで、グルヌプを遞択しおください。"/>
<check_box label="入堎蚱可を販売" name="PassCheck" tool_tip="この区画ぞの䞀時的なアクセスを蚱可したす。"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_add_payment_method.xml b/indra/newview/skins/default/xui/ja/floater_add_payment_method.xml
index fb2cd37cc3..b420bf7d20 100644
--- a/indra/newview/skins/default/xui/ja/floater_add_payment_method.xml
+++ b/indra/newview/skins/default/xui/ja/floater_add_payment_method.xml
@@ -5,7 +5,7 @@
</floater.string>
<panel label="wrapper_panel" name="wrapper_panel">
<text name="title_txt">
- 支払い方法を登録しおリンデンドルを賌入し、Second Lifeをもっず楜しみたしょう。
+ 支払い方法を远加しおリンデンドルを賌入し、Second Lifeをもっず楜しみたしょう。
</text>
<button label="始めたしょう" name="continue_btn"/>
<button label="たた埌で"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml b/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml
index 5de3486ea1..a4909c18fd 100644
--- a/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml
@@ -6,13 +6,13 @@
<scroll_container name="profile_scroll">
<panel name="scroll_content_panel">
<text name="label">
- ベヌクド
+ ベむク枈み
テクスチャ
</text>
<text name="composite_label">
合成テクスチャ
</text>
- <button label="をコン゜ヌルにダンプ" label_selected="ダンプ" name="Dump"/>
+ <button label="IDをコン゜ヌルにダンプ" label_selected="ダンプ" name="Dump"/>
<panel name="scroll_content_panel2">
<texture_picker label="髪" name="hair-baked"/>
<texture_picker label="髪" name="hair_grain"/>
@@ -53,12 +53,12 @@
<texture_picker label="巊腕のタトゥ" name="leftarm_tattoo"/>
<texture_picker label="å·Šè¶³" name="leftleg-baked"/>
<texture_picker label="巊足のタトゥ" name="leftleg_tattoo"/>
- <texture_picker label="予備" name="aux1-baked"/>
- <texture_picker label="予備タトゥ" name="aux1_tattoo"/>
- <texture_picker label="予備" name="aux2-baked"/>
- <texture_picker label="予備タトゥ" name="aux2_tattoo"/>
- <texture_picker label="予備" name="aux3-baked"/>
- <texture_picker label="予備タトゥ" name="aux3_tattoo"/>
+ <texture_picker label="予備1" name="aux1-baked"/>
+ <texture_picker label="予備1タトゥ" name="aux1_tattoo"/>
+ <texture_picker label="予備2" name="aux2-baked"/>
+ <texture_picker label="予備2タトゥ" name="aux2_tattoo"/>
+ <texture_picker label="予備3" name="aux3-baked"/>
+ <texture_picker label="予備3タトゥ" name="aux3_tattoo"/>
</panel>
</panel>
</scroll_container>
diff --git a/indra/newview/skins/default/xui/ja/floater_bumps.xml b/indra/newview/skins/default/xui/ja/floater_bumps.xml
index 8cd9c0cff9..c48296fa8f 100644
--- a/indra/newview/skins/default/xui/ja/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/ja/floater_bumps.xml
@@ -4,21 +4,21 @@
怜出なし
</floater.string>
<floater.string name="bump">
- [TIME] [NAME]があなたに衝突したした。
+ [TIME] [NAME]があなたに衝突したした。
</floater.string>
<floater.string name="llpushobject">
- [TIME] [NAME]がスクリプトであなたを抌したした。
+ [TIME] [NAME]がスクリプトであなたを抌したした。
</floater.string>
<floater.string name="selected_object_collide">
- [TIME] [NAME]が、オブゞェクトであなたを叩きたした。
+ [TIME] [NAME]が、オブゞェクトであなたを叩きたした。
</floater.string>
<floater.string name="scripted_object_collide">
- [TIME] [NAME]が、スクリプトのオブゞェクトであなたを叩きたした。
+ [TIME] [NAME]が、スクリプトのオブゞェクトであなたを叩きたした。
</floater.string>
<floater.string name="physical_object_collide">
- [TIME] [NAME]が、物理オブゞェクトであなたを叩きたした。
+ [TIME] [NAME]が、物理オブゞェクトであなたを叩きたした。
</floater.string>
<floater.string name="timeStr">
- [[hour,datetime,slt][min,datetime,slt][second,datetime,slt]]
+ [[hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt]]
</floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml
index f75564cd4c..a72836bbbc 100644
--- a/indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml
+++ b/indra/newview/skins/default/xui/ja/floater_edit_ext_day_cycle.xml
@@ -13,7 +13,7 @@
自分で䜜成したデむサむクルを線集するには、垌望の蚭定に調節しお、「保存」をクリックしたす。
</string>
<string name="time_label">
- [HH][MM]
+ [HH]:[MM]
</string>
<string name="sky_track_label">
空[ALT]
@@ -42,9 +42,9 @@
<layout_stack name="content_stack">
<layout_panel name="timeline_track_selection">
<panel name="timeline_layers">
- <button label="空" name="sky4_track"/>
- <button label="空" name="sky3_track"/>
- <button label="空" name="sky2_track"/>
+ <button label="空4" name="sky4_track"/>
+ <button label="空3" name="sky3_track"/>
+ <button label="空2" name="sky2_track"/>
<button label="地面" name="sky1_track"/>
<button label="氎面" name="water_track"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_god_tools.xml b/indra/newview/skins/default/xui/ja/floater_god_tools.xml
index 3c96e2e340..d82be80c95 100644
--- a/indra/newview/skins/default/xui/ja/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/ja/floater_god_tools.xml
@@ -20,17 +20,17 @@
<button label="地圢を元に戻す" label_selected="地圢を元に戻す" name="Revert Terrain" tool_tip="珟圚の地圢をデフォルトに眮換したす。"/>
<button label="地圢を亀換" label_selected="地圢を亀換" name="Swap Terrain" tool_tip="珟圚の地圢をデフォルトず入れ替えたす。"/>
<text name="estate id">
- 䞍動産
+ 䞍動産ID
</text>
<text name="parent id">
- 芪
+ 芪ID
</text>
<line_editor name="parentestate" tool_tip="これは、このリヌゞョン地域の芪䞍動産です。"/>
<text name="Grid Pos: ">
グリッド䜍眮
</text>
- <line_editor name="gridposx" tool_tip="これは、このリヌゞョン地域のグリッド座暙です。"/>
- <line_editor name="gridposy" tool_tip="これは、このリヌゞョン地域のグリッド座暙です。"/>
+ <line_editor name="gridposx" tool_tip="これは、このリヌゞョン地域のグリッドX座暙です。"/>
+ <line_editor name="gridposy" tool_tip="これは、このリヌゞョン地域のグリッドY座暙です。"/>
<text name="Redirect to Grid: ">
グリッドにリダむレクト
</text>
@@ -85,7 +85,7 @@
<combo_box.item label="コラむダヌステップ" name="item1"/>
<combo_box.item label="スクリプト回数、オプション・パタヌン" name="item2"/>
<combo_box.item label="オブゞェクトパタヌン" name="item3"/>
- <combo_box.item label="rez アセット" name="item4"/>
+ <combo_box.item label="rez アセットID" name="item4"/>
</combo_box>
<text name="Parameter:">
パラメヌタヌ
diff --git a/indra/newview/skins/default/xui/ja/floater_incoming_call.xml b/indra/newview/skins/default/xui/ja/floater_incoming_call.xml
index 319db34879..5b09d2da53 100644
--- a/indra/newview/skins/default/xui/ja/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/ja/floater_incoming_call.xml
@@ -4,7 +4,7 @@
5
</floater.string>
<floater.string name="localchat">
- 近隣のボむスチャット
+ 近くのボむスチャット
</floater.string>
<floater.string name="anonymous">
匿名ナヌザヌ
diff --git a/indra/newview/skins/default/xui/ja/floater_inspect.xml b/indra/newview/skins/default/xui/ja/floater_inspect.xml
index fca7b2eab8..0a859f9142 100644
--- a/indra/newview/skins/default/xui/ja/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/ja/floater_inspect.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="inspect" title="オブゞェクトの調査">
<floater.string name="timeStamp">
- [year,datetime,slt]幎[mth,datetime,slt]月[day,datetime,slt]日[wkday,datetime,slt] [hour,datetime,slt][min,datetime,slt][second,datetime,slt]
+ [year,datetime,slt]幎[mth,datetime,slt]月[day,datetime,slt]日[wkday,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt]
</floater.string>
<scroll_list name="object_list" tool_tip="このリストからオブゞェクトを遞択しお、むンワヌルドでハむラむトしたす。">
<scroll_list.columns label="オブゞェクト名" name="object_name"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_joystick.xml b/indra/newview/skins/default/xui/ja/floater_joystick.xml
index 559ecee5a8..0d3f0992a2 100644
--- a/indra/newview/skins/default/xui/ja/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/ja/floater_joystick.xml
@@ -6,9 +6,9 @@
<text name="joystick_lbl">
ゞョむスティック
</text>
- <spinner label="軞マッピング" name="JoystickAxis1"/>
- <spinner label="軞マッピング" name="JoystickAxis2"/>
- <spinner label="軞マッピング" name="JoystickAxis0"/>
+ <spinner label="X軞マッピング" name="JoystickAxis1"/>
+ <spinner label="Y軞マッピング" name="JoystickAxis2"/>
+ <spinner label="Z軞マッピング" name="JoystickAxis0"/>
<spinner label="ピッチ・マッピング" name="JoystickAxis4"/>
<spinner label="ペヌ・マッピング" name="JoystickAxis5"/>
<spinner label="ロヌル・マッピング" name="JoystickAxis3"/>
@@ -23,19 +23,19 @@
<check_box label="造る" name="JoystickBuildEnabled"/>
<check_box label="フラむ・カメラ" name="JoystickFlycamEnabled"/>
<text name="XScale">
- スケヌル
+ Xスケヌル
</text>
<spinner name="AvatarAxisScale1"/>
<spinner name="BuildAxisScale1"/>
<spinner name="FlycamAxisScale1"/>
<text name="YScale">
- スケヌル
+ Yスケヌル
</text>
<spinner name="AvatarAxisScale2"/>
<spinner name="BuildAxisScale2"/>
<spinner name="FlycamAxisScale2"/>
<text name="ZScale">
- スケヌル
+ Zスケヌル
</text>
<spinner name="AvatarAxisScale0"/>
<spinner name="BuildAxisScale0"/>
@@ -58,19 +58,19 @@
<spinner name="BuildAxisScale3"/>
<spinner name="FlycamAxisScale3"/>
<text name="XDeadZone">
- デッド・ゟヌン
+ Xデッド・ゟヌン
</text>
<spinner name="AvatarAxisDeadZone1"/>
<spinner name="BuildAxisDeadZone1"/>
<spinner name="FlycamAxisDeadZone1"/>
<text name="YDeadZone">
- デッド・ゟヌン
+ Yデッド・ゟヌン
</text>
<spinner name="AvatarAxisDeadZone2"/>
<spinner name="BuildAxisDeadZone2"/>
<spinner name="FlycamAxisDeadZone2"/>
<text name="ZDeadZone">
- デッド・ゟヌン
+ Zデッド・ゟヌン
</text>
<spinner name="AvatarAxisDeadZone0"/>
<spinner name="BuildAxisDeadZone0"/>
@@ -110,12 +110,12 @@
<button label="" label_selected="" name="ok_btn"/>
<button label="キャンセル" label_selected="キャンセル" name="cancel_btn"/>
<stat_view label="ゞョむスティック・モニタヌ" name="axis_view">
- <stat_bar label="軞" name="axis0"/>
- <stat_bar label="軞" name="axis1"/>
- <stat_bar label="軞" name="axis2"/>
- <stat_bar label="軞" name="axis3"/>
- <stat_bar label="軞" name="axis4"/>
- <stat_bar label="軞" name="axis5"/>
+ <stat_bar label="軞0" name="axis0"/>
+ <stat_bar label="軞1" name="axis1"/>
+ <stat_bar label="軞2" name="axis2"/>
+ <stat_bar label="軞3" name="axis3"/>
+ <stat_bar label="軞4" name="axis4"/>
+ <stat_bar label="軞5" name="axis5"/>
</stat_view>
<string name="NoDevice">
デバむスは怜出されたせんでした。
diff --git a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml b/indra/newview/skins/default/xui/ja/floater_lagmeter.xml
index e7830bbd25..67b4e29e45 100644
--- a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/ja/floater_lagmeter.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_lagmeter" title="ラグメヌタヌ">
<floater.string name="max_title_msg">
- 遅延蚈枬噚
+ ラグメヌタヌ
</floater.string>
<floater.string name="max_width_px">
360
diff --git a/indra/newview/skins/default/xui/ja/floater_land_holdings.xml b/indra/newview/skins/default/xui/ja/floater_land_holdings.xml
index 31009cb2e0..cd32fac8ac 100644
--- a/indra/newview/skins/default/xui/ja/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_land_holdings.xml
@@ -17,13 +17,13 @@
<column label="面積" name="area"/>
</scroll_list>
<text name="allowed_label">
- 珟圚の支払いプランで利甚可胜な入怍地
+ 珟圚の支払いプランで所有可胜な土地:
</text>
<text name="allowed_text">
[AREA]㎡
</text>
<text name="current_label">
- 珟圚の保有地
+ 珟圚所有しおいる土地:
</text>
<text name="current_text">
[AREA]㎡
diff --git a/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml b/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml
index 4bb370f6ea..f362bff2bd 100644
--- a/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="script ed float" title="レファレンス">
+<floater name="script ed float" title="LSLレファレンス">
<check_box label="カヌ゜ルを远う" name="lock_check"/>
<combo_box label="ロック" name="history_combo"/>
<button label="戻る" name="back_btn"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_model_preview.xml b/indra/newview/skins/default/xui/ja/floater_model_preview.xml
index 69629f357f..123421a97d 100644
--- a/indra/newview/skins/default/xui/ja/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_model_preview.xml
@@ -233,7 +233,7 @@
</panel>
<panel label="アップロヌドのオプション" name="modifiers_panel">
<text name="scale_label">
- スケヌル増枛なし
+ スケヌル1増枛なし
</text>
<spinner name="import_scale" value="1.0"/>
<text name="dimensions_label">
@@ -250,7 +250,7 @@
<check_box label="ゞョむント䜍眮を含む" name="upload_joints"/>
<check_box label="ゞョむント䜍眮が定矩されおいる堎合、スケヌルをロック" name="lock_scale_if_joint_position"/>
<text name="pelvis_offset_label">
- オフセットアバタヌを䞊䞋調敎
+ Zオフセットアバタヌを䞊䞋調敎
</text>
<spinner name="pelvis_offset" value="0.0"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_outgoing_call.xml b/indra/newview/skins/default/xui/ja/floater_outgoing_call.xml
index d74b714b1a..35f4cd3ca3 100644
--- a/indra/newview/skins/default/xui/ja/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/ja/floater_outgoing_call.xml
@@ -4,7 +4,7 @@
5
</floater.string>
<floater.string name="localchat">
- 近隣のボむスチャット
+ 近くのボむスチャット
</floater.string>
<floater.string name="anonymous">
匿名ナヌザヌ
diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml
index 00742aef23..092b564455 100644
--- a/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml
+++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml
@@ -32,7 +32,7 @@
<scroll_list.columns label="名前" name="name"/>
<scroll_list.columns label="説明" name="description"/>
<scroll_list.columns label="所有者" name="owner"/>
- <scroll_list.columns label="" name="cpu_time"/>
+ <scroll_list.columns label="CPU" name="cpu_time"/>
<scroll_list.columns label="高床" name="altitude"/>
</scroll_list>
<text name="messaging_status">
diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml
index 218fade27b..72d9f4b44a 100644
--- a/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml
+++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml
@@ -89,17 +89,17 @@
</text>
<combo_box name="show_heatmap_mode">
<combo_box.item label="衚瀺しない" name="show_heatmap_mode_none"/>
- <combo_box.item label="キャラクタヌタむプ" name="show_heatmap_mode_a"/>
- <combo_box.item label="キャラクタヌタむプ" name="show_heatmap_mode_b"/>
- <combo_box.item label="キャラクタヌタむプ" name="show_heatmap_mode_c"/>
- <combo_box.item label="キャラクタヌタむプ" name="show_heatmap_mode_d"/>
+ <combo_box.item label="キャラクタヌタむプA" name="show_heatmap_mode_a"/>
+ <combo_box.item label="キャラクタヌタむプB" name="show_heatmap_mode_b"/>
+ <combo_box.item label="キャラクタヌタむプC" name="show_heatmap_mode_c"/>
+ <combo_box.item label="キャラクタヌタむプD" name="show_heatmap_mode_d"/>
</combo_box>
<check_box label="歩行可胜" name="show_walkables"/>
<check_box label="玠材ボリュヌム" name="show_material_volumes"/>
<check_box label="静的障害物" name="show_static_obstacles"/>
<check_box label="陀倖ボリュヌム" name="show_exclusion_volumes"/>
<check_box label="氎䞊飛行機" name="show_water_plane"/>
- <check_box label="線衚瀺" name="show_xray"/>
+ <check_box label="X線衚瀺" name="show_xray"/>
</panel>
<panel label="パスをテスト" name="test_panel">
<text name="ctrl_click_label">
@@ -113,17 +113,17 @@
</text>
<slider name="character_width" value="1"/>
<text name="character_width_unit_label">
- 
+ m
</text>
<text name="character_type_label">
キャラクタヌタむプ
</text>
<combo_box name="path_character_type">
<combo_box.item label="なし" name="path_character_type_none"/>
- <combo_box.item label="" name="path_character_type_a"/>
- <combo_box.item label="" name="path_character_type_b"/>
- <combo_box.item label="" name="path_character_type_c"/>
- <combo_box.item label="" name="path_character_type_d"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
</combo_box>
<button label="経路をクリア" name="clear_path"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml
index 0189cbd47b..0bf9b6a308 100644
--- a/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml
+++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml
@@ -119,10 +119,10 @@
<scroll_list.columns label="ランドむンパクト" name="land_impact"/>
<scroll_list.columns label="距離" name="dist_from_you"/>
<scroll_list.columns label="経路探玢で䜿甚" name="linkset_use"/>
- <scroll_list.columns label="" name="a_percent"/>
- <scroll_list.columns label="" name="b_percent"/>
- <scroll_list.columns label="" name="c_percent"/>
- <scroll_list.columns label="" name="d_percent"/>
+ <scroll_list.columns label="A %" name="a_percent"/>
+ <scroll_list.columns label="B %" name="b_percent"/>
+ <scroll_list.columns label="C %" name="c_percent"/>
+ <scroll_list.columns label="D %" name="d_percent"/>
</scroll_list>
<text name="messaging_status">
リンクセット
@@ -150,21 +150,21 @@
歩行可胜性
</text>
<text name="edit_a_label">
- 
+ A
</text>
- <line_editor name="edit_a_value" tool_tip="タむプのキャラクタヌの歩行可胜性。キャラクタヌタむプの䟋はヒュヌマノむドです。"/>
+ <line_editor name="edit_a_value" tool_tip="タむプAのキャラクタヌの歩行可胜性。キャラクタヌタむプの䟋はヒュヌマノむドです。"/>
<text name="edit_b_label">
- 
+ B
</text>
- <line_editor name="edit_b_value" tool_tip="タむプのキャラクタヌの歩行可胜性。キャラクタヌタむプの䟋はクリヌチャヌです。"/>
+ <line_editor name="edit_b_value" tool_tip="タむプBのキャラクタヌの歩行可胜性。キャラクタヌタむプの䟋はクリヌチャヌです。"/>
<text name="edit_c_label">
- 
+ C
</text>
- <line_editor name="edit_c_value" tool_tip="タむプのキャラクタヌの歩行可胜性。キャラクタヌタむプの䟋はメカニカルです。"/>
+ <line_editor name="edit_c_value" tool_tip="タむプCのキャラクタヌの歩行可胜性。キャラクタヌタむプの䟋はメカニカルです。"/>
<text name="edit_d_label">
- 
+ D
</text>
- <line_editor name="edit_d_value" tool_tip="タむプのキャラクタヌの歩行可胜性。キャラクタヌタむプの䟋はその他です。"/>
+ <line_editor name="edit_d_value" tool_tip="タむプDのキャラクタヌの歩行可胜性。キャラクタヌタむプの䟋はその他です。"/>
<button label="倉曎を適甚" name="apply_edit_values"/>
<text name="suggested_use_a_label">
ヒュヌマノむド
diff --git a/indra/newview/skins/default/xui/ja/floater_performance.xml b/indra/newview/skins/default/xui/ja/floater_performance.xml
index e2efc152a4..ecb00dd58c 100644
--- a/indra/newview/skins/default/xui/ja/floater_performance.xml
+++ b/indra/newview/skins/default/xui/ja/floater_performance.xml
@@ -39,7 +39,7 @@
</panel>
<panel name="nearby_subpanel">
<text name="avatars_nearby_lbl">
- 近隣のアバタヌ
+ 近くのアバタヌ
</text>
<text name="avatars_nearby_desc">
近くにいるアバタヌのうち、どのタむプのアバタヌを完党に衚瀺するかを管理したす。
@@ -51,16 +51,16 @@
アバタヌの耇雑床
</text>
<text name="complexity_info">
- が出ない堎合は、アバタヌの耇雑床を枛らしおください。
+ FPSが出ない堎合は、アバタヌの耇雑床を枛らしおください。
</text>
<icon name="icon_arrow4"/>
</panel>
<panel name="huds_subpanel">
<text name="huds_lbl">
- アクティブな
+ アクティブなHUD
</text>
<text name="huds_desc">
- 䜿甚しおいないを倖すず、速床が向䞊する可胜性がありたす。
+ 䜿甚しおいないHUDを倖すず、速床が向䞊する可胜性がありたす。
</text>
<icon name="icon_arrow4"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_preferences.xml b/indra/newview/skins/default/xui/ja/floater_preferences.xml
index c26bad3176..f75026c6a6 100644
--- a/indra/newview/skins/default/xui/ja/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preferences.xml
@@ -15,7 +15,7 @@
<panel label="色" name="colors"/>
<panel label="プラむバシヌ" name="im"/>
<panel label="セットアップ" name="input"/>
- <panel label="拡匵" name="advanced1"/>
+ <panel label="アドバンス" name="advanced1"/>
<panel label="アップロヌド" name="uploads"/>
<panel label="操䜜" name="controls"/>
</tab_container>
diff --git a/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml
index 66a416f416..9a2ed64291 100644
--- a/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preferences_graphics_advanced.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="prefs_graphics_advanced" title="拡匵グラフィック蚭定">
+<floater name="prefs_graphics_advanced" title="グラフィック詳现蚭定">
<text name="GeneralText">
党般
</text>
<slider label="描画距離" name="DrawDistance"/>
<text name="DrawDistanceMeterText2">
- 
+ m
</text>
<slider label="最倧パヌティクル数" name="MaxParticleCount"/>
<slider label="ポストプロセス品質" name="RenderPostProcess"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_preferences_view_advanced.xml b/indra/newview/skins/default/xui/ja/floater_preferences_view_advanced.xml
index 5efbbf7e17..5f686e41e4 100644
--- a/indra/newview/skins/default/xui/ja/floater_preferences_view_advanced.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preferences_view_advanced.xml
@@ -4,14 +4,14 @@
カメラのオフセット
</text>
<spinner name="camera_x"/>
- <spinner label="" name="camera_y"/>
- <spinner label="" name="camera_z"/>
+ <spinner label="Y" name="camera_y"/>
+ <spinner label="Z" name="camera_z"/>
<text name="focus_offset_lbl">
焊点のオフセット
</text>
<spinner name="focus_x"/>
- <spinner label="" name="focus_y"/>
- <spinner label="" name="focus_z"/>
+ <spinner label="Y" name="focus_y"/>
+ <spinner label="Z" name="focus_z"/>
<text name="offset_scale_lbl">
カメラのオフセット倍率
</text>
diff --git a/indra/newview/skins/default/xui/ja/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/ja/floater_scene_load_stats.xml
index 43d5223ecc..b43d54001c 100644
--- a/indra/newview/skins/default/xui/ja/floater_scene_load_stats.xml
+++ b/indra/newview/skins/default/xui/ja/floater_scene_load_stats.xml
@@ -4,7 +4,7 @@
<container_view name="statistics_view">
<stat_view name="basic" label="基本">
<stat_bar label="フレヌムごずのピクセル差" name="frame difference" unit_label=""/>
- <stat_bar label="デヌタの受信量" name="bandwidth" unit_label="kbps"/>
+ <stat_bar label="UDPデヌタの受信量" name="bandwidth" unit_label="kbps"/>
<stat_bar label="パケットロス" name="packet_loss" unit_label=""/>
</stat_view>
<stat_view name="advanced" label="拡匵">
@@ -57,15 +57,15 @@
<stat_bar name="simsimphysicsshapeupdatemsec" label=" 物理圢状曎新" unit_label="㎳"/>
<stat_bar name="simsimphysicsothermsec" label=" 他の物理䜜甚" unit_label="㎳"/>
<stat_bar name="simsleepmsec" label=" スリヌプ時間" unit_label="㎳"/>
- <stat_bar name="simpumpiomsec" label=" ポンプ" unit_label="㎳"/>
+ <stat_bar name="simpumpiomsec" label=" ポンプIO" unit_label="㎳"/>
</stat_view>
</stat_view>
</stat_view>
<stat_view name="frame_stats" label="フレヌムの内蚳">
<stat_bar name="scenery_frame_pct" label="景色" unit_label=""/>
<stat_bar name="avatar_frame_pct" label="アバタヌ" unit_label=""/>
- <stat_bar name="ui_frame_pct" label="" unit_label=""/>
- <stat_bar name="huds_frame_pct" label="" unit_label=""/>
+ <stat_bar name="ui_frame_pct" label="UI" unit_label=""/>
+ <stat_bar name="huds_frame_pct" label="HUD" unit_label=""/>
<stat_bar name="swap_frame_pct" label="スワップ" unit_label=""/>
<stat_bar name="idle_frame_pct" label="タスク" unit_label=""/>
</stat_view>
diff --git a/indra/newview/skins/default/xui/ja/floater_settings_debug.xml b/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
index f304ab9769..ef1947dbce 100644
--- a/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
@@ -16,10 +16,10 @@
</radio_group>
<line_editor name="val_text"/>
<color_swatch label="色" name="val_color_swatch"/>
- <spinner label="" name="val_spinner_1"/>
- <spinner label="" name="val_spinner_2"/>
- <spinner label="" name="val_spinner_3"/>
- <spinner label="" name="val_spinner_4"/>
+ <spinner label="x" name="val_spinner_1"/>
+ <spinner label="x" name="val_spinner_2"/>
+ <spinner label="x" name="val_spinner_3"/>
+ <spinner label="x" name="val_spinner_4"/>
<button label="デフォルトにリセット" name="default_btn"/>
<check_box label="倉曎された蚭定のみ衚瀺" name="hide_default"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
index 8035e8a13f..be9c52fb12 100644
--- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
@@ -49,7 +49,7 @@
<combo_box.item label="色深床" name="Depth" value="depth"/>
</combo_box>
<check_box label="むンタヌフェヌス" name="ui_check"/>
- <check_box label="" name="hud_check"/>
+ <check_box label="HUD" name="hud_check"/>
<check_box label="フレヌムをフリヌズ党画面" name="freeze_frame_check"/>
<check_box label="自動リフレッシュ" name="auto_snapshot_check"/>
<text name="filter_list_label">
@@ -93,6 +93,6 @@
[SIZE]㎅
</text>
<text name="360_label">
- 床ショットを撮圱
+ 360床スナップショットを撮圱
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_stats.xml b/indra/newview/skins/default/xui/ja/floater_stats.xml
index 0c28b47351..41a482a4b9 100644
--- a/indra/newview/skins/default/xui/ja/floater_stats.xml
+++ b/indra/newview/skins/default/xui/ja/floater_stats.xml
@@ -3,15 +3,15 @@
<scroll_container name="statistics_scroll">
<container_view name="statistics_view">
<stat_view label="基本" name="basic">
- <stat_bar label="" name="fps" unit_label="秒"/>
+ <stat_bar label="FPS" name="fps" unit_label="秒"/>
<stat_bar name="frame_mean" label="フレヌム平均" unit_label="㎳"/>
<stat_bar name="frame_median" label="フレヌム䞭倮倀" unit_label="㎳"/>
<stat_bar name="framet_jitter" label="ゞッタ"/>
- <stat_bar label="受信したデヌタ" name="bandwidth"/>
+ <stat_bar label="受信したUDPデヌタ" name="bandwidth"/>
<stat_bar label="パケットロス" name="packet_loss"/>
<stat_bar label="シムのPing" name="ping"/>
</stat_view>
- <stat_view label="拡匵" name="advanced">
+ <stat_view label="詳现" name="advanced">
<stat_view label="描画" name="render">
<stat_bar label="フレヌムあたりのKTris" name="ktrisframe" unit_label="ktrisフレヌム"/>
<stat_bar label="秒あたりのKTris" name="ktrissec"/>
@@ -27,15 +27,15 @@
<stat_bar label="キャッシュヒット率" name="texture_cache_hits"/>
<stat_bar label="キャッシュ読み取り遅延" name="texture_cache_read_latency"/>
<stat_bar label="カりント" name="numimagesstat"/>
- <stat_bar label="カりント" name="numrawimagesstat"/>
- <stat_bar label="メモリ" name="gltexmemstat"/>
+ <stat_bar label="Rawカりント" name="numrawimagesstat"/>
+ <stat_bar label="GLメモリ" name="gltexmemstat"/>
<stat_bar label="フォヌマット枈メモリ" name="formattedmemstat"/>
- <stat_bar label="メモリ" name="rawmemstat"/>
+ <stat_bar label="Rawメモリ" name="rawmemstat"/>
<stat_bar label="統合メモリ" name="glboundmemstat"/>
</stat_view>
<stat_view label="メモリ䜿甚量" name="memory">
- <stat_bar label="トレヌス" name="LLTrace"/>
- <stat_bar label="" name="LLView"/>
+ <stat_bar label="LLトレヌス" name="LLTrace"/>
+ <stat_bar label="UI" name="LLView"/>
<stat_bar label="フォント" name="LLFontFreetype"/>
<stat_bar label="むンベントリ" name="LLInventoryObject"/>
<stat_bar label="ビュヌアオブゞェクト" name="LLViewerObject"/>
@@ -47,7 +47,7 @@
<stat_bar label="描画情報" name="LLDrawInfo"/>
<stat_bar label="テクスチャデヌタ" name="LLTexture"/>
<stat_bar label="画像デヌタ" name="LLImage"/>
- <stat_bar label="画像デヌタ" name="LLImageGL"/>
+ <stat_bar label="GL画像デヌタ" name="LLImageGL"/>
<stat_bar label="頂点バッファ" name="LLVertexBuffer"/>
</stat_view>
<stat_view label="ネットワヌク" name="network">
@@ -63,11 +63,11 @@
</stat_view>
<stat_view label="シミュレヌタヌ" name="sim">
<stat_bar label="遅延時間" name="simtimedilation"/>
- <stat_bar label="シムの" name="simfps"/>
- <stat_bar label="物理䜜甚の" name="simphysicsfps"/>
+ <stat_bar label="シムのFPS" name="simfps"/>
+ <stat_bar label="物理䜜甚のFPS" name="simphysicsfps"/>
<stat_view label="物理䜜甚の詳现" name="physicsdetail">
<stat_bar label="ピン留めオブゞェクト" name="physicspinnedtasks"/>
- <stat_bar label="䜎オブゞェクト" name="physicslodtasks"/>
+ <stat_bar label="䜎LODオブゞェクト" name="physicslodtasks"/>
<stat_bar label="メモリ配分" name="physicsmemoryallocated"/>
</stat_view>
<stat_bar label="゚ヌゞェントの曎新秒" name="simagentups"/>
@@ -79,7 +79,7 @@
<stat_bar label="スクリプト実行" name="simpctscriptsrun"/>
<stat_bar label="スクリプトむベント" name="simscripteps" unit_label="eps"/>
<stat_view label="経路探玢" name="simpathfinding">
- <stat_bar label="ステップ時間" name="simsimaistepmsec"/>
+ <stat_bar label="AIステップ時間" name="simsimaistepmsec"/>
<stat_bar label="スキップされたシル゚ットステップ" name="simsimskippedsilhouettesteps" unit_label="秒"/>
<stat_bar label="曎新されたキャラクタヌ" name="simsimpctsteppedcharacters" unit_label=""/>
</stat_view>
diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml
index fb95a71ce0..f14d8f7241 100644
--- a/indra/newview/skins/default/xui/ja/floater_tools.xml
+++ b/indra/newview/skins/default/xui/ja/floater_tools.xml
@@ -40,7 +40,7 @@
土地をクリックし、ドラッグしお遞択
</floater.string>
<floater.string name="status_selectcount">
- 遞択されおいるオブゞェクトは[OBJ_COUNT]個、土地の負荷は[LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳现]
+ 遞択されおいるオブゞェクトは[OBJ_COUNT]個、土地の負荷は[LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳现]
</floater.string>
<floater.string name="status_remaining_capacity">
残りの蚱容数[LAND_CAPACITY]
@@ -123,7 +123,7 @@
䜕も遞択されおいたせん。
</text>
<text name="remaining_capacity">
- [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights 詳现]
+ [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights 詳现]
</text>
<tab_container name="Object Info Tabs">
<panel label="䞀般" name="General">
@@ -232,22 +232,22 @@
<check_box label="コピヌ" name="checkbox next owner can copy" tool_tip="譲枡先の所有者は、このオブゞェクトを無制限にコピヌできたす。コピヌには制䜜者の情報が含たれ、コピヌ元のアむテムず違っお蚱可などに関し制玄がありたす。"/>
<check_box label="再販・譲枡" name="checkbox next owner can transfer" tool_tip="譲枡先の所有者は、このオブゞェクトを他人に譲枡したり再販するこずができたす。"/>
<text name="B:">
- 
+ B
</text>
<text name="O:">
- 
+ O
</text>
<text name="G:">
- 
+ G
</text>
<text name="E:">
- 
+ E
</text>
<text name="N:">
- 
+ N
</text>
<text name="F:">
- 
+ F
</text>
</panel>
<panel name="pathfinding_attrs_panel">
@@ -264,21 +264,21 @@
<text name="label position">
䜍眮メヌトル
</text>
- <spinner label="" name="Pos X"/>
- <spinner label="" name="Pos Y"/>
- <spinner label="" name="Pos Z"/>
+ <spinner label="X" name="Pos X"/>
+ <spinner label="Y" name="Pos Y"/>
+ <spinner label="Z" name="Pos Z"/>
<text name="label size">
サむズメヌトル
</text>
- <spinner label="" name="Scale X"/>
- <spinner label="" name="Scale Y"/>
- <spinner label="" name="Scale Z"/>
+ <spinner label="X" name="Scale X"/>
+ <spinner label="Y" name="Scale Y"/>
+ <spinner label="Z" name="Scale Z"/>
<text name="label rotation">
回転床
</text>
- <spinner label="" name="Rot X"/>
- <spinner label="" name="Rot Y"/>
- <spinner label="" name="Rot Z"/>
+ <spinner label="X" name="Rot X"/>
+ <spinner label="Y" name="Rot Y"/>
+ <spinner label="Z" name="Rot Z"/>
<combo_box name="comboBaseType">
<combo_box.item label="ボックス" name="Box"/>
<combo_box.item label="シリンダヌ" name="Cylinder"/>
@@ -320,13 +320,13 @@
<text name="scale_hole">
穎寞法
</text>
- <spinner label="" name="Taper Scale X"/>
- <spinner label="" name="Taper Scale Y"/>
+ <spinner label="X" name="Taper Scale X"/>
+ <spinner label="Y" name="Taper Scale Y"/>
<text name="text topshear">
䞊郚局
</text>
- <spinner label="" name="Shear X"/>
- <spinner label="" name="Shear Y"/>
+ <spinner label="X" name="Shear X"/>
+ <spinner label="Y" name="Shear Y"/>
<text name="advanced_cut">
プロフィヌルカット始点ず終点
</text>
@@ -341,8 +341,8 @@
<text name="text taper2">
テヌパヌ
</text>
- <spinner label="" name="Taper X"/>
- <spinner label="" name="Taper Y"/>
+ <spinner label="X" name="Taper X"/>
+ <spinner label="Y" name="Taper Y"/>
<text name="text radius delta">
半埄
</text>
@@ -350,7 +350,7 @@
回転䜓
</text>
<texture_picker label="スカルプトテクスチャ" name="sculpt texture control" tool_tip="クリックしお画像を遞択しおください。"/>
- <check_box label="ミラヌ" name="sculpt mirror control" tool_tip="スカルプトプリムを軞䞊で反転させたす"/>
+ <check_box label="ミラヌ" name="sculpt mirror control" tool_tip="スカルプトプリムをX軞䞊で反転させたす"/>
<check_box label="裏返し" name="sculpt invert control" tool_tip="スカルプトプリムを反転させお裏返したす"/>
<text name="label sculpt type">
瞫い目のタむプ
@@ -379,20 +379,20 @@
オブゞェクトの特城を線集
</text>
<check_box label="アニメヌションメッシュ" name="Animated Mesh Checkbox Ctrl" tool_tip="リグ入りメッシュオブゞェクトを、それぞれアニメヌションさせるこずができるようになりたす。"/>
- <check_box label="フレキシブルパス" name="Flexible1D Checkbox Ctrl" tool_tip="軞を䞭心に、オブゞェクトの屈曲を有効にしたす。クラむアント偎のみ"/>
+ <check_box label="フレキシブルパス" name="Flexible1D Checkbox Ctrl" tool_tip="Z軞を䞭心に、オブゞェクトの屈曲を有効にしたす。クラむアント偎のみ"/>
<spinner label="柔軟性" name="FlexNumSections"/>
<spinner label="重力" name="FlexGravity"/>
<spinner label="ドラッグ" name="FlexFriction"/>
<spinner label="颚" name="FlexWind"/>
<spinner label="緊匵" name="FlexTension"/>
- <spinner label="軞方向の力" name="FlexForceX"/>
- <spinner label="軞方向の力" name="FlexForceY"/>
- <spinner label="軞方向の力" name="FlexForceZ"/>
+ <spinner label="X軞方向の力" name="FlexForceX"/>
+ <spinner label="Y軞方向の力" name="FlexForceY"/>
+ <spinner label="Z軞方向の力" name="FlexForceZ"/>
<check_box label="発光" name="Light Checkbox Ctrl" tool_tip="オブゞェクトが発光したす"/>
<color_swatch label="" name="colorswatch" tool_tip="クリックしおカラヌピッカヌを開きたす"/>
<texture_picker label="" name="light texture control" tool_tip="クリックで投圱画を遞択したす遅延レンダリング有効時のみ"/>
<spinner label="茝床" name="Light Intensity"/>
- <spinner label="" name="Light FOV"/>
+ <spinner label="FOV" name="Light FOV"/>
<spinner label="半埄" name="Light Radius"/>
<spinner label="焊点" name="Light Focus"/>
<spinner label="匱たる" name="Light Falloff"/>
@@ -412,7 +412,7 @@
</combo_box>
<spinner label="重力" name="Physics Gravity"/>
<spinner label="摩擊" name="Physics Friction"/>
- <spinner label="密床㎏/㎥" name="Physics Density"/>
+ <spinner label="密床100㎏/㎥" name="Physics Density"/>
<spinner label="埩元" name="Physics Restitution"/>
</panel>
<panel label="材質" name="Texture"/>
@@ -426,13 +426,13 @@
区画情報
</text>
<text name="label_area_price">
- 䟡栌[AREA]㎡ L$ [PRICE]
+ 䟡栌[AREA]㎡ L$ [PRICE]
</text>
<text name="label_area">
面積[AREA]㎡
</text>
<button label="土地情報" label_selected="土地情報" name="button about land"/>
- <check_box label="所有者を衚瀺" name="checkbox show owners" tool_tip="所有者の皮類別に区画を色づけたす緑色あなたの土地 氎色あなたのグルヌプ所有地 赀色他人が所有する土地 黄色 = 売り出し䞭 玫色オヌクション 灰色公共領域"/>
+ <check_box label="所有者を衚瀺" name="checkbox show owners" tool_tip="所有者の皮類別に区画を色づけたす&#10;&#10;緑色あなたの土地 &#10;氎色あなたのグルヌプ所有地 &#10;赀色他人が所有する土地 &#10;黄色 = 売り出し䞭 &#10;玫色オヌクション &#10;灰色公共領域"/>
<text name="label_parcel_modify">
区画の線集
</text>
diff --git a/indra/newview/skins/default/xui/ja/floater_top_objects.xml b/indra/newview/skins/default/xui/ja/floater_top_objects.xml
index 86ab64cb3e..69d527a087 100644
--- a/indra/newview/skins/default/xui/ja/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/ja/floater_top_objects.xml
@@ -22,7 +22,7 @@
䜕も芋぀かりたせんでした。
</floater.string>
<floater.string name="URLs">
- 
+ URL
</floater.string>
<floater.string name="memory">
メモリ㎅
@@ -41,7 +41,7 @@
<scroll_list.columns label="メモリ㎅" name="memory"/>
</scroll_list>
<text name="id_text">
- 物䜓
+ 物䜓ID:
</text>
<button label="暙識を衚瀺" name="show_beacon_btn"/>
<text name="obj_name_text">
diff --git a/indra/newview/skins/default/xui/ja/floater_translation_settings.xml b/indra/newview/skins/default/xui/ja/floater_translation_settings.xml
index 8bbcbcdfed..dbe5c3007a 100644
--- a/indra/newview/skins/default/xui/ja/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_translation_settings.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_translation_settings" title="チャットの翻蚳蚭定">
<string name="azure_api_key_not_verified">
- Azureサヌビス識別子の認蚌ができたせんでした。ステヌタス[STATUS] 蚭定をお確かめの䞊、もう䞀床やり盎しおください。
+ Azureサヌビス識別子の認蚌ができたせんでした。ステヌタス[STATUS] 蚭定をお確かめの䞊、もう䞀床やり盎しおください。
</string>
<string name="google_api_key_not_verified">
- Google APIキヌの認蚌ができたせんでした。ステヌタス[STATUS] 蚭定をお確かめの䞊、もう䞀床やり盎しおください。
+ Google APIキヌの認蚌ができたせんでした。ステヌタス[STATUS] 蚭定をお確かめの䞊、もう䞀床やり盎しおください。
</string>
<string name="deepl_api_key_not_verified">
- DeepL Authキヌの認蚌ができたせんでした。ステヌタス[STATUS] 蚭定をお確かめの䞊、もう䞀床やり盎しおください。
+ DeepL Authキヌの認蚌ができたせんでした。ステヌタス[STATUS] 蚭定をお確かめの䞊、もう䞀床やり盎しおください。
</string>
<string name="azure_api_key_verified">
Azureサヌビス識別子が認蚌されたした。
diff --git a/indra/newview/skins/default/xui/ja/floater_ui_preview.xml b/indra/newview/skins/default/xui/ja/floater_ui_preview.xml
index b907b4e8d7..c3d70e7055 100644
--- a/indra/newview/skins/default/xui/ja/floater_ui_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_ui_preview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="gui_preview_tool" title="プレビュヌツヌル">
+<floater name="gui_preview_tool" title="XUIプレビュヌツヌル">
<string name="ExternalEditorNotSet">
環境倉数LL_XUI_EDITORたたはExternalEditor蚭定を蚭定するか、[EDITOR PATH]フィヌルドにそのパスを指定しお、゚ディタヌを遞択したす。
</string>
@@ -10,11 +10,11 @@
<combo_box name="language_select_combo">
<combo_box.item label="ja" name="item1" value="ja"/>
</combo_box>
- <button label="衚瀺" label_selected="衚瀺" name="display_floater" tool_tip="遞択したファむルで定矩されたフロヌタを衚瀺したす。"/>
+ <button label="衚瀺" label_selected="衚瀺" name="display_floater" tool_tip="遞択したXMLファむルで定矩されたXUIフロヌタを衚瀺したす。"/>
<button label="非衚瀺" label_selected="非衚瀺" name="close_displayed_floater" tool_tip="珟圚衚瀺されおいるフロヌタヌが存圚する堎合は、それを閉じたす。"/>
- <button label="線集 " label_selected="線集 " name="edit_floater" tool_tip="遞択したファむルによっお定矩されたフロヌタヌを線集したす。倖郚゚ディタヌを開きたすロヌカラむズされたバヌゞョンが存圚しない堎合は、enバヌゞョンを開きたす。"/>
- <button label="保存" label_selected="保存" name="save_floater" tool_tip="遞択したファむルで定矩されたフロヌタを保存したす。"/>
- <button label="党お保存" label_selected="党お保存" name="save_all_floaters" tool_tip="遞択した蚀語で定矩されたすべおのフロヌタを保存したす。"/>
+ <button label="線集 " label_selected="線集 " name="edit_floater" tool_tip="遞択したXMLファむルによっお定矩されたXUIフロヌタヌを線集したす。倖郚゚ディタヌを開きたすロヌカラむズされたバヌゞョンが存圚しない堎合は、enバヌゞョンを開きたす。"/>
+ <button label="保存" label_selected="保存" name="save_floater" tool_tip="遞択したXMLファむルで定矩されたXUIフロヌタを保存したす。"/>
+ <button label="党お保存" label_selected="党お保存" name="save_all_floaters" tool_tip="遞択した蚀語で定矩されたすべおのXUIフロヌタを保存したす。"/>
<button label="≫" label_selected="≪" name="toggle_overlap_panel" tool_tip="重なっおいる芁玠の匷調衚瀺ず衚瀺パネルを切り替えたす。芁玠を右クリックしお、この機胜甚に遞択したす。遞択した芁玠は、赀い四角圢でマヌクされたす。"/>
<text name="select_language_label_2">
二次蚀語
@@ -22,7 +22,7 @@
<combo_box name="language_select_combo_2">
<combo_box.item label="en" name="item1" value="en"/>
</combo_box>
- <button label="衚瀺" name="display_floater_2" tool_tip="遞択したファむルで定矩されたフロヌタを衚瀺したす。"/>
+ <button label="衚瀺" name="display_floater_2" tool_tip="遞択したXMLファむルで定矩されたXUIフロヌタを衚瀺したす。"/>
<button enabled="false" label="非衚瀺" name="close_displayed_floater_2" tool_tip="珟圚衚瀺されおいるフロヌタヌが存圚する堎合は、それを閉じたす。"/>
<button label="スキヌマを゚クスポヌト" name="export_schema"/>
<check_box label="四角圢を衚瀺" name="show_rectangles"/>
@@ -35,8 +35,8 @@
<text name="editor_path_label">
゚ディタのパス
</text>
- <line_editor name="executable_path_field" tool_tip="フロヌタヌファむルを線集するための゚ディタヌ実行可胜ファむルぞのフルパス。匕甚笊は必芁ありたせん"/>
- <button follows="left|bottom" label="ブラりズ " label_selected="ブラりズ " name="browse_for_executable" tool_tip="フロヌタヌファむルを線集するための゚ディタヌ実行可胜ファむルを参照したす。"/>
+ <line_editor name="executable_path_field" tool_tip="フロヌタヌXMLファむルを線集するための゚ディタヌ実行可胜ファむルぞのフルパス。匕甚笊は必芁ありたせん"/>
+ <button follows="left|bottom" label="ブラりズ " label_selected="ブラりズ " name="browse_for_executable" tool_tip="フロヌタヌXMLファむルを線集するための゚ディタヌ実行可胜ファむルを参照したす。"/>
<text name="executable_args_label">
゚ディタの匕数
</text>
@@ -46,7 +46,7 @@
<text name="diff_file_label">
差分ファむル
</text>
- <line_editor name="vlt_diff_path_field" tool_tip="Viewer Localization Toolkitによっお生成されたのD0、D1蚀語差分ファむルぞのフルパス"/>
+ <line_editor name="vlt_diff_path_field" tool_tip="Viewer Localization Toolkitによっお生成されたXMLのD0、D1蚀語差分ファむルぞのフルパス"/>
<button label="ブラりズ " label_selected="ブラりズ " name="browse_for_vlt_diffs" tool_tip="VLTで生成されたD0、D1差分ファむルを参照しお、倉曎されたファむルず芁玠を匷調衚瀺したす。"/>
<button label="差分をハむラむト" label_selected="ハむラむトを解陀" name="toggle_vlt_diff_highlight" tool_tip="倉曎された蚀語デヌタを含むファむルず芁玠の匷調衚瀺を切り替えたす。"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_url_entry.xml b/indra/newview/skins/default/xui/ja/floater_url_entry.xml
index 3ff50854a5..534e0156c5 100644
--- a/indra/newview/skins/default/xui/ja/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/ja/floater_url_entry.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="url_entry">
<text name="media_label">
- メディア
+ メディアURL
</text>
<combo_box name="media_entry"/>
<button label="" name="ok_btn"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml
index be59547bf3..fd8e75da87 100644
--- a/indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="whitelist_entry" title="ホワむトリストの入力">
<text name="media_label">
- かパタヌンを入力しお、蚱可するドメむンをリストに远加したす。
+ URLかURLパタヌンを入力しお、蚱可するドメむンをリストに远加したす。
</text>
- <line_editor name="whitelist_entry" tool_tip="かパタヌンをホワむトリストに入力したす。"/>
+ <line_editor name="whitelist_entry" tool_tip="URLかURLパタヌンをホワむトリストに入力したす。"/>
<button label="" name="ok_btn"/>
<button label="キャンセル" name="cancel_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_other.xml b/indra/newview/skins/default/xui/ja/menu_attachment_other.xml
index 284449d59d..87f469f91d 100644
--- a/indra/newview/skins/default/xui/ja/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/ja/menu_attachment_other.xml
@@ -2,7 +2,7 @@
<context_menu name="Avatar Pie">
<menu_item_call label="プロフィヌルを芋る" name="Profile..."/>
<menu_item_call label="フレンドに远加" name="Add Friend"/>
- <menu_item_call label="" name="Send IM..."/>
+ <menu_item_call label="IM" name="Send IM..."/>
<menu_item_call label="コヌル" name="Call"/>
<menu_item_call label="グルヌプに招埅 " name="Invite..."/>
<menu_item_separator/>
@@ -14,7 +14,7 @@
<menu_item_call label="フリヌズ" name="Freeze..."/>
<menu_item_call label="远攟" name="Eject..."/>
<menu_item_call label="テクスチャのデバッグ" name="Debug..."/>
- <menu_item_call label="ずしおダンプ" name="Dump XML"/>
+ <menu_item_call label="XMLずしおダンプ" name="Dump XML"/>
<menu_item_call label="ズヌムむン" name="Zoom In"/>
<menu_item_call label="支払う" name="Pay..."/>
<menu_item_separator/>
diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_other.xml b/indra/newview/skins/default/xui/ja/menu_avatar_other.xml
index a7989b35c8..0a022d16a1 100644
--- a/indra/newview/skins/default/xui/ja/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/ja/menu_avatar_other.xml
@@ -2,7 +2,7 @@
<context_menu name="Avatar Pie">
<menu_item_call label="プロフィヌルを芋る" name="Profile..."/>
<menu_item_call label="フレンドに远加" name="Add Friend"/>
- <menu_item_call label="" name="Send IM..."/>
+ <menu_item_call label="IM" name="Send IM..."/>
<menu_item_call label="コヌル" name="Call"/>
<menu_item_call label="グルヌプぞ招埅" name="Invite..."/>
<menu_item_separator/>
@@ -14,7 +14,7 @@
<menu_item_call label="フリヌズ" name="Freeze..."/>
<menu_item_call label="远攟" name="Eject..."/>
<menu_item_call label="テクスチャのデバッグ" name="Debug..."/>
- <menu_item_call label="ずしおダンプ" name="Dump XML"/>
+ <menu_item_call label="XMLずしおダンプ" name="Dump XML"/>
<menu_item_call label="ズヌムむン" name="Zoom In"/>
<menu_item_call label="支払う" name="Pay..."/>
<menu_item_separator/>
diff --git a/indra/newview/skins/default/xui/ja/menu_conversation.xml b/indra/newview/skins/default/xui/ja/menu_conversation.xml
index 047f5d57cf..163feb5b56 100644
--- a/indra/newview/skins/default/xui/ja/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/ja/menu_conversation.xml
@@ -5,7 +5,7 @@
<menu_item_call label="ボむスチャットを切断する" name="disconnect_from_voice"/>
<menu_item_call label="遞択した項目を閉じる" name="close_selected_conversations"/>
<menu_item_call label="プロフィヌルを衚瀺" name="view_profile"/>
- <menu_item_call label="" name="im"/>
+ <menu_item_call label="IM" name="im"/>
<menu_item_call label="テレポヌトのオファヌ" name="offer_teleport"/>
<menu_item_call label="ボむスコヌル" name="voice_call"/>
<menu_item_call label="チャットの履歎 " name="chat_history"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml
index 78c46d13b4..438b0c304b 100644
--- a/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Conversation Context Menu">
- <menu_item_call label=" " name="IM"/>
+ <menu_item_call label="IM..." name="IM"/>
<menu_item_call label="ボむスコヌル " name="Call"/>
<menu_item_call label="チャットの履歎を開く " name="Chat history"/>
<menu_item_call label="プロフィヌルを衚瀺" name="View Profile"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml
index bcda112d2f..2012eb88cc 100644
--- a/indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml
+++ b/indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml
@@ -3,5 +3,5 @@
<menu_item_check label="名前で䞊べ替え" name="sort_by_name"/>
<menu_item_check label="日付で䞊べ替え" name="sort_by_date"/>
<menu_item_check label="䞊䜍のフレンドを䞊べ替え" name="sort_by_friends"/>
- <menu_item_call label="近隣チャットの履歎を衚瀺 " name="view_nearby_chat_history"/>
+ <menu_item_call label="チャット履歎を衚瀺 " name="view_nearby_chat_history"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_gesture_gear.xml b/indra/newview/skins/default/xui/ja/menu_gesture_gear.xml
index e1f24cdb39..3a8fd36ceb 100644
--- a/indra/newview/skins/default/xui/ja/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_gesture_gear.xml
@@ -4,7 +4,7 @@
<menu_item_call label="名前倉曎" name="rename"/>
<menu_item_call label="コピヌ" name="copy_gesture"/>
<menu_item_call label="ペヌスト" name="paste"/>
- <menu_item_call label="をコピヌ" name="copy_uuid"/>
+ <menu_item_call label="UUIDをコピヌ" name="copy_uuid"/>
<menu_item_call label="珟圚のアりトフィットに保存" name="save_to_outfit"/>
<menu_item_call label="線集" name="edit_gesture"/>
<menu_item_call label="調べる" name="inspect"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_inventory.xml b/indra/newview/skins/default/xui/ja/menu_inventory.xml
index c7cba4845d..d602823fe4 100644
--- a/indra/newview/skins/default/xui/ja/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inventory.xml
@@ -82,7 +82,7 @@
<menu_item_call label="オリゞナルを開く" name="Open Original"/>
<menu_item_call label="プロパティ" name="Properties"/>
<menu_item_call label="名前を倉曎" name="Rename"/>
- <menu_item_call label="アセットのをコピヌ" name="Copy Asset UUID"/>
+ <menu_item_call label="アセットのUUIDをコピヌ" name="Copy Asset UUID"/>
<menu_item_call label="メむンパネルで衚瀺" name="Show in Main Panel"/>
<menu_item_call label="カット" name="Cut"/>
<menu_item_call label="コピヌ" name="Copy"/>
@@ -113,7 +113,7 @@
<menu_item_separator name="Wearable And Object Separator"/>
<menu_item_call label="装着" name="Wearable And Object Wear"/>
<menu label="装着先" name="Attach To"/>
- <menu label="HUD 装着先" name="Attach To HUD"/>
+ <menu label="HUDの装着先" name="Attach To HUD"/>
<menu_item_call label="è§Šã‚‹" name="Attachment Touch"/>
<menu_item_call label="線集" name="Wearable Edit"/>
<menu_item_call label="远加" name="Wearable Add"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_participant_list.xml b/indra/newview/skins/default/xui/ja/menu_participant_list.xml
index ebce5f7e6b..5756e3f8b5 100644
--- a/indra/newview/skins/default/xui/ja/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/ja/menu_participant_list.xml
@@ -4,7 +4,7 @@
<menu_item_check label="最近の発蚀者で䞊べ替え" name="SortByRecentSpeakers"/>
<menu_item_call label="プロフィヌルの衚瀺" name="View Profile"/>
<menu_item_call label="フレンド登録" name="Add Friend"/>
- <menu_item_call label="" name="IM"/>
+ <menu_item_call label="IM" name="IM"/>
<menu_item_call label="コヌル" name="Call"/>
<menu_item_call label="共有" name="Share"/>
<menu_item_call label="支払う" name="Pay"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby.xml
index bbe842a37e..13c940abf4 100644
--- a/indra/newview/skins/default/xui/ja/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_nearby.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
<menu_item_call label="プロフィヌルを衚瀺" name="view_profile"/>
- <menu_item_call label="" name="im"/>
+ <menu_item_call label="IM" name="im"/>
<menu_item_call label="テレポヌトを送る" name="offer_teleport"/>
<menu_item_call label="ボむスコヌル" name="voice_call"/>
<menu_item_call label="チャットの履歎を衚瀺 " name="chat_history"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml
index 4e3dbd3279..e8b8f0f694 100644
--- a/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml
@@ -2,7 +2,7 @@
<context_menu name="Multi-Selected People Context Menu">
<menu_item_call label="フレンド登録" name="add_friends"/>
<menu_item_call label="フレンドを削陀" name="remove_friends"/>
- <menu_item_call label="" name="im"/>
+ <menu_item_call label="IM" name="im"/>
<menu_item_call label="コヌル" name="call"/>
<menu_item_call label="共有" name="share"/>
<menu_item_call label="支払い" name="pay"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_profile_other.xml b/indra/newview/skins/default/xui/ja/menu_profile_other.xml
index 0247a60803..9803735afc 100644
--- a/indra/newview/skins/default/xui/ja/menu_profile_other.xml
+++ b/indra/newview/skins/default/xui/ja/menu_profile_other.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Avatar Profile Menu">
- <menu_item_call label="" name="im"/>
+ <menu_item_call label="IM" name="im"/>
<menu_item_call label="テレポヌトのオファヌ" name="offer_teleport"/>
<menu_item_call label="テレポヌトのリク゚スト" name="request_teleport"/>
<menu_item_call label="ボむスコヌル" name="voice_call"/>
@@ -19,5 +19,5 @@
<menu_item_separator name="separator_copy_options"/>
<menu_item_call label="衚瀺名をコピヌ" name="copy_display_name"/>
<menu_item_call label="゚ヌゞェント名をコピヌ" name="copy_name"/>
- <menu_item_call label="゚ヌゞェントをコピヌ" name="copy_id"/>
+ <menu_item_call label="゚ヌゞェントIDをコピヌ" name="copy_id"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_profile_self.xml b/indra/newview/skins/default/xui/ja/menu_profile_self.xml
index 7c9570378e..f39593e417 100644
--- a/indra/newview/skins/default/xui/ja/menu_profile_self.xml
+++ b/indra/newview/skins/default/xui/ja/menu_profile_self.xml
@@ -8,5 +8,5 @@
<menu_item_separator name="separator_copy_options"/>
<menu_item_call label="衚瀺名をコピヌ" name="copy_display_name"/>
<menu_item_call label="゚ヌゞェント名をコピヌ" name="copy_name"/>
- <menu_item_call label="゚ヌゞェントをコピヌ" name="copy_id"/>
+ <menu_item_call label="゚ヌゞェントIDをコピヌ" name="copy_id"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_settings_gear.xml b/indra/newview/skins/default/xui/ja/menu_settings_gear.xml
index a8ff0d3721..3f5d30073b 100644
--- a/indra/newview/skins/default/xui/ja/menu_settings_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_settings_gear.xml
@@ -6,5 +6,5 @@
<menu_item_call label="リヌゞョン地域に適甚" name="Settings Apply Region"/>
<menu_item_call label="コピヌ" name="copy_settings"/>
<menu_item_call label="ペヌスト" name="paste_settings"/>
- <menu_item_call label="をコピヌ" name="copy_uuid"/>
+ <menu_item_call label="UUIDをコピヌ" name="copy_uuid"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_slurl.xml b/indra/newview/skins/default/xui/ja/menu_slurl.xml
index 820cc3cd53..e68128e429 100644
--- a/indra/newview/skins/default/xui/ja/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/ja/menu_slurl.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="Popup">
- <menu_item_call label="に぀いお" name="about_url"/>
- <menu_item_call label="にテレポヌトする" name="teleport_to_url"/>
+ <menu_item_call label="URLに぀いお" name="about_url"/>
+ <menu_item_call label="URLにテレポヌトする" name="teleport_to_url"/>
<menu_item_call label="マップ" name="show_on_map"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_url_agent.xml b/indra/newview/skins/default/xui/ja/menu_url_agent.xml
index 9ce9a070f2..d06f4896b2 100644
--- a/indra/newview/skins/default/xui/ja/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_agent.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
<menu_item_call label="プロフィヌルを衚瀺" name="show_agent"/>
- <menu_item_call label="を送信 " name="send_im"/>
+ <menu_item_call label="IMを送信 " name="send_im"/>
<menu_item_call label="フレンドを远加 " name="add_friend"/>
<menu_item_call label="フレンドを削陀 " name="remove_friend"/>
<menu_item_call label="嫌がらせの報告" name="report_abuse"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_url_http.xml b/indra/newview/skins/default/xui/ja/menu_url_http.xml
index ae97e8bd8d..c3da8a8686 100644
--- a/indra/newview/skins/default/xui/ja/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_http.xml
@@ -3,5 +3,5 @@
<menu_item_call label="Web ペヌゞを開く" name="url_open"/>
<menu_item_call label="内蔵ブラりザで開く" name="url_open_internal"/>
<menu_item_call label="倖郚ブラりザで開く" name="url_open_external"/>
- <menu_item_call label="をクリップボヌドにコピヌ" name="url_copy"/>
+ <menu_item_call label="URLをクリップボヌドにコピヌ" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml
index f6b10bb121..41df8fdbb1 100644
--- a/indra/newview/skins/default/xui/ja/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml
@@ -17,7 +17,7 @@
<menu_item_call label="アカりントのダッシュボヌド " name="Manage My Account"/>
<menu_item_call label="[Membership]" name="Membership"/>
<menu_item_separator/>
- <menu_item_call label="初期蚭定 " name="Preferences"/>
+ <menu_item_call label="環境蚭定 " name="Preferences"/>
<menu_item_call label="ツヌルバヌのボタン " name="Toolbars"/>
<menu_item_call label="党おのコントロヌルを隠す" name="Hide UI" shortcut="control|shift|U"/>
<menu_item_check label="HUDを衚瀺" name="Show HUD Attachments" shortcut="alt|shift|H"/>
@@ -47,7 +47,7 @@
<menu_item_separator/>
<menu_item_call label="すべおの服装" name="All Clothes"/>
</menu>
- <menu label="" name="Avatar Detach HUD"/>
+ <menu label="HUD" name="Avatar Detach HUD"/>
<menu label="取り倖す" name="Avatar Detach"/>
<menu_item_call label="党おを取り倖す" name="Detach All"/>
</menu>
@@ -70,7 +70,7 @@
</menu>
<menu label="コミュニケヌション" name="Communicate">
<menu_item_check label="䌚話 " name="Conversations"/>
- <menu_item_check label="近隣のチャット " name="Nearby Chat"/>
+ <menu_item_check label="呚蟺チャット " name="Nearby Chat"/>
<menu_item_check label="ボむスチャット" name="Speak"/>
<menu_item_check name="Conversation Log..." label="䌚話ログ "/>
<menu_item_separator/>
@@ -95,7 +95,7 @@
<menu_item_call label="珟圚地をホヌムに蚭定" name="Set Home to Here"/>
<menu_item_separator/>
<menu_item_call label="スナップショット" name="Take Snapshot"/>
- <menu_item_call label="床スナップショット" name="Capture 360"/>
+ <menu_item_call label="360床スナップショット" name="Capture 360"/>
<menu_item_separator/>
<menu_item_call label="堎所のプロフィヌル" name="Place Profile"/>
<menu_item_call label="土地情報" name="About Land"/>
@@ -112,14 +112,14 @@
<menu_item_check label="座暙" name="Coordinates"/>
<menu_item_check label="区画のプロパティ" name="Parcel Properties"/>
<menu_item_separator/>
- <menu_item_check label="拡匵メニュヌ" name="Show Advanced Menu"/>
+ <menu_item_check label="アドバンスメニュヌ" name="Show Advanced Menu"/>
</menu>
<menu_item_check label="グラフィック性胜の最適化 " name="Performance"/>
<menu_item_separator/>
<menu label="環境" name="Environment">
- <menu_item_check label="倜明け" name="Sunrise"/>
+ <menu_item_check label="日の出" name="Sunrise"/>
<menu_item_check label="正午" name="Noon"/>
- <menu_item_check label="倕方" name="Sunset"/>
+ <menu_item_check label="日没" name="Sunset"/>
<menu_item_check label="深倜" name="Midnight"/>
<menu_item_check label="共有された環境を䜿甚" name="Use Shared Environment"/>
<menu_item_separator/>
@@ -188,7 +188,7 @@
<menu_item_check label="遞択ビヌムを衚瀺する" name="Show Selection Beam"/>
<menu_item_separator/>
<menu_item_check label="グリッド吞着" name="Snap to Grid"/>
- <menu_item_call label="オブゞェクトの軞をグリッドに吞着" name="Snap Object XY to Grid"/>
+ <menu_item_call label="オブゞェクトのXY軞をグリッドに吞着" name="Snap Object XY to Grid"/>
<menu_item_call label="遞択をグリッドに䜿甚する" name="Use Selection for Grid"/>
<menu_item_separator/>
<menu_item_call label="グリッドオプション " name="Grid Options"/>
@@ -221,9 +221,9 @@
<menu_item_call label="衝突・プッシュ打撃" name="Bumps, Pushes &amp;amp; Hits"/>
<menu_item_call label="[APP_NAME]に぀いお" name="About Second Life"/>
</menu>
- <menu label="拡匵" name="Advanced">
+ <menu label="アドバンス" name="Advanced">
<menu_item_call label="テクスチャをリベヌクする" name="Rebake Texture"/>
- <menu_item_call label="サむズをデフォルトにする" name="Set UI Size to Default"/>
+ <menu_item_call label="UIサむズをデフォルトにする" name="Set UI Size to Default"/>
<menu_item_call label="りィンドりサむズ蚭定 " name="Set Window Size..."/>
<menu_item_separator/>
<menu_item_check label="オブゞェクトの遞択距離の制限" name="Limit Select Distance"/>
@@ -233,7 +233,7 @@
<menu_item_check label="スナップショットをディスクに保存" name="QuietSnapshotsToDisk"/>
<menu_item_separator/>
<menu label="パフォヌマンスツヌル" name="Performance Tools">
- <menu_item_call label="遅延メヌタヌ" name="Lag Meter"/>
+ <menu_item_call label="ラグメヌタヌ" name="Lag Meter"/>
<menu_item_check label="統蚈バヌ" name="Statistics Bar"/>
<menu_item_call label="シヌン負荷の統蚈情報" name="Scene Load Statistics"/>
<menu_item_check label="アバタヌの耇雑床を衚瀺" name="Avatar Draw Info"/>
@@ -262,7 +262,7 @@
<menu_item_check label="衝突" name="Rendering Type Bump"/>
</menu>
<menu label="レンダリング機胜" name="Rendering Features">
- <menu_item_check label="" name="ToggleUI"/>
+ <menu_item_check label="UI" name="ToggleUI"/>
<menu_item_check label="遞択枈" name="Selected"/>
<menu_item_check label="ハむラむト" name="Highlighted"/>
<menu_item_check label="動的テクスチャ" name="Dynamic Textures"/>
@@ -313,7 +313,7 @@
<menu_item_separator/>
<menu_item_check label="カメラ" name="Camera"/>
<menu_item_check label="颚" name="Wind"/>
- <menu_item_check label="" name="FOV"/>
+ <menu_item_check label="FOV" name="FOV"/>
<menu_item_check label="バッゞ" name="Badge"/>
</menu>
<menu label="情報を衚瀺" name="Display Info">
@@ -352,7 +352,7 @@
</menu>
<menu label="メタデヌタの描画" name="Render Metadata">
<menu_item_check label="バりンディングボックス" name="Bounding Boxes"/>
- <menu_item_check label="普通" name="Normals"/>
+ <menu_item_check label="法線" name="Normals"/>
<menu_item_check label="八分朚" name="Octree"/>
<menu_item_check label="シャドり円錐" name="Shadow Frusta"/>
<menu_item_check label="実像" name="Physics Shapes"/>
@@ -363,7 +363,7 @@
<menu_item_check label="テクスチャ優先床" name="Texture Priority"/>
<menu_item_check label="テクスチャの範囲" name="Texture Area"/>
<menu_item_check label="偎面" name="Face Area"/>
- <menu_item_check label="情報" name="LOD Info"/>
+ <menu_item_check label="LOD情報" name="LOD Info"/>
<menu_item_check label="䞉角圢の数" name="Triangle Count"/>
<menu_item_check label="制䜜・キュヌ" name="Build Queue"/>
<menu_item_check label="光" name="Lights"/>
@@ -372,7 +372,7 @@
<menu_item_check label="ゞョむント" name="Joints"/>
<menu_item_check label="レむキャスト" name="Raycast"/>
<menu_item_check label="颚のベクトル" name="Wind Vectors"/>
- <menu_item_check label="圫刻" name="Sculpt"/>
+ <menu_item_check label="スカルプト" name="Sculpt"/>
<menu label="テクスチャの密床" name="Texture Density">
<menu_item_check label="無し" name="None"/>
<menu_item_check label="原行" name="Current"/>
@@ -389,10 +389,10 @@
<menu_item_check label="オブゞェクト間のオクルヌゞョン" name="Object-Object Occlusion"/>
<menu_item_separator/>
<menu_item_check label="高床な光源モデル" name="Advanced Lighting Model"/>
- <menu_item_check label=" 倪陜・月・プロゞェクタからの圱" name="Shadows from Sun/Moon/Projectors"/>
- <menu_item_check label=" SSAOず圱のスムヌゞング" name="SSAO and Shadow Smoothing"/>
+ <menu_item_check label=" 倪陜・月・プロゞェクタからの圱" name="Shadows from Sun/Moon/Projectors"/>
+ <menu_item_check label=" SSAOず圱のスムヌゞング" name="SSAO and Shadow Smoothing"/>
<menu_item_separator/>
- <menu_item_check label="次回起動時にをデバッグ" name="Debug GL"/>
+ <menu_item_check label="次回起動時にGLのデバッグを開始" name="Debug GL"/>
<menu_item_check label="パむプラむンをデバッグ" name="Debug Pipeline"/>
<menu_item_check label="自動アルファマスク遅延" name="Automatic Alpha Masks (deferred)"/>
<menu_item_check label="自動アルファマスク遅延なし" name="Automatic Alpha Masks (non-deferred)"/>
@@ -439,7 +439,7 @@
<menu_item_call label="リヌゞョンオブゞェクトのキャッシュをダンプ" name="Dump Region Object Cache"/>
<menu_item_call label="関心リストフルアップデヌト" name="Interest List: Full Update"/>
</menu>
- <menu label="" name="UI">
+ <menu label="UI" name="UI">
<menu_item_call label="メディアブラりザ" name="Media Browser"/>
<menu_item_call label="むンベントリの出力" name="Dump Inventory"/>
<menu_item_call label="タむマヌをダンプ" name="Dump Timers"/>
@@ -455,15 +455,15 @@
<menu_item_check label="デバッグキヌ" name="Debug Keys"/>
<menu_item_check label="WindowProcのデバッグ" name="Debug WindowProc"/>
</menu>
- <menu label="" name="XUI">
+ <menu label="XUI" name="XUI">
<menu_item_call label="色の蚭定をリロヌド" name="Reload Color Settings"/>
<menu_item_call label="フォントテストを衚瀺" name="Show Font Test"/>
- <menu_item_check label="名を衚瀺" name="Show XUI Names"/>
- <menu_item_call label="テストを送信する" name="Send Test IMs"/>
+ <menu_item_check label="XUI名を衚瀺" name="Show XUI Names"/>
+ <menu_item_call label="テストIMを送信する" name="Send Test IMs"/>
<menu_item_call label="名前キャッシュをフラッシュ" name="Flush Names Caches"/>
</menu>
- <menu label="アバタヌ" name="Character">
- <menu label="ベヌクドテクスチャを取埗する" name="Grab Baked Texture">
+ <menu label="キャラクタヌ" name="Character">
+ <menu label="ベむク枈みテクスチャを取埗する" name="Grab Baked Texture">
<menu_item_call label="瞳" name="Grab Iris"/>
<menu_item_call label="é ­" name="Grab Head"/>
<menu_item_call label="䞊半身" name="Grab Upper Body"/>
@@ -488,7 +488,7 @@
<menu_item_check label="芋おいるものを衚瀺する" name="Show Look At"/>
<menu_item_check label="クリックした堎所を衚瀺する" name="Show Point At"/>
<menu_item_check label="結合郚のアップデヌトのデバッグ" name="Debug Joint Updates"/>
- <menu_item_check label="を無効にする" name="Disable LOD"/>
+ <menu_item_check label="LODを無効にする" name="Disable LOD"/>
<menu_item_check label="キャラクタヌVisのデバッグ" name="Debug Character Vis"/>
<menu_item_check label="スケルトンの衝突刀定を衚瀺する" name="Show Collision Skeleton"/>
<menu_item_check label="ボヌンを衚瀺" name="Show Bones"/>
@@ -499,7 +499,7 @@
<menu_item_call label="ロヌカルテクスチャをダンプ" name="Dump Local Textures"/>
</menu>
<menu_item_separator/>
- <menu_item_check label="テスクチャ" name="HTTP Textures"/>
+ <menu_item_check label="HTTPテスクチャ" name="HTTP Textures"/>
<menu_item_call label="圧瞮画像" name="Compress Images"/>
<menu_item_call label="圧瞮ファむルテスト" name="Compress File Test"/>
<menu_item_call label="Visual Leak Detectorを有効にする" name="Enable Visual Leak Detector"/>
@@ -517,14 +517,14 @@
<menu_item_call label="管理者ステヌタス解陀" name="Leave Admin Options"/>
<menu_item_check label="管理者メニュヌを衚瀺する" name="View Admin Options"/>
</menu>
- <menu label="管理" name="Admin">
+ <menu label="管理者" name="Admin">
<menu label="オブゞェクト" name="AdminObject">
<menu_item_call label="コピヌを取る" name="Admin Take Copy"/>
<menu_item_call label="自分を所有者にする" name="Force Owner To Me"/>
<menu_item_call label="所有者暩限の実行" name="Force Owner Permissive"/>
<menu_item_call label="削陀" name="Delete"/>
<menu_item_call label="ロック" name="Lock"/>
- <menu_item_call label="アセットのを取埗" name="Get Assets IDs"/>
+ <menu_item_call label="アセットのIDを取埗" name="Get Assets IDs"/>
</menu>
<menu label="区画" name="Parcel">
<menu_item_call label="自分を所有者にする" name="Owner To Me"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
index 213a554bbd..2c13d50226 100644
--- a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
@@ -6,8 +6,8 @@
<menu_item_call label="è§Šã‚‹" name="touch"/>
<menu_item_call label="脱ぐ" name="take_off_or_detach"/>
<menu_item_call label="取り倖す" name="detach"/>
- <context_menu label="装着" name="wearable_attach_to"/>
- <context_menu label="に装着" name="wearable_attach_to_hud"/>
+ <context_menu label="装着" name="wearable_attach_to"/>
+ <context_menu label="HUDに装着" name="wearable_attach_to_hud"/>
<menu_item_call label="取り倖す" name="take_off"/>
<menu_item_call label="線集" name="edit"/>
<menu_item_call label="アむテムのプロフィヌル" name="object_profile"/>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 123e95df04..9ec7a0de98 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -451,7 +451,7 @@ L$が䞍足しおいるので、このグルヌプに参加するこずができ
</notification>
<notification name="CreateGroupCost">このグルヌプ䜜成にかかる費甚L$ [COST]
䞀人ではグルヌプにならないので、氞久に削陀されおしたいたす。
-時間以内にメンバヌを勧誘し、入䌚しおもらっおください。
+48時間以内にメンバヌを勧誘し、入䌚しおもらっおください。
<tag>
group
</tag>
@@ -1260,7 +1260,7 @@ L$が䞍足しおいるので、このグルヌプに参加するこずができ
fail
</tag>
</notification>
- <notification name="SoundFileInvalidTooLong">オヌディオファむルが長すぎたす。最倧秒
+ <notification name="SoundFileInvalidTooLong">オヌディオファむルが長すぎたす。最倧30秒
[FILE]
<tag>
fail
@@ -1411,7 +1411,7 @@ L$が䞍足しおいるので、このグルヌプに参加するこずができ
fail
</tag>
</notification>
- <notification name="invalid_tport">テレポヌトの詊行は分間に回たでず制限されおいたす。分埅っおからもう䞀床テレポヌトしおみおください。問題が解決しない堎合は、ログむンし盎しおください。
+ <notification name="invalid_tport">テレポヌトの詊行は1分間に6回たでず制限されおいたす。1分埅っおからもう䞀床テレポヌトしおみおください。問題が解決しない堎合は、ログむンし盎しおください。
<tag>
fail
</tag>
@@ -1735,7 +1735,7 @@ L$が䞍足しおいるので、このグルヌプに参加するこずができ
</tag>
</notification>
<notification name="YouHaveBeenLoggedOut">したった、[SECOND_LIFE]からログアりトされおしたいたした。[MESSAGE]
- <usetemplate name="okcancelbuttons" notext="終了" yestext="でチャット"/>
+ <usetemplate name="okcancelbuttons" notext="終了" yestext="IM &amp; チャットを芋る"/>
</notification>
<notification name="InventoryUnusable">むンベントリの読み蟌み䞭に問題が発生したした。たず、ログアりトしお再床ログむンし盎しおみおください。
このメッセヌゞが再床衚瀺される堎合は、サポヌトに連絡しお問題を解決しおください。
@@ -2126,7 +2126,7 @@ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
HUDComplexityWarning
</context>
</unique>
- <usetemplate ignoretext="が耇雑すぎる堎合の譊告" name="notifyignore"/>
+ <usetemplate ignoretext="HUDが耇雑すぎる堎合の譊告" name="notifyignore"/>
</notification>
<notification name="FirstRun">[APP_NAME]のむンストヌルが完了したした。
[SECOND_LIFE]を䜿ったこずがない堎合は、ログむンする前にアカりントの䜜成を行っおください。
@@ -2162,7 +2162,7 @@ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
</form>
</notification>
<notification name="WelcomeChooseSex">たもなく、あなたのアバタヌが衚瀺されたす。矢印キヌを䜿甚しお歩きたす。
-ヘルプが必芁なずきや、[SECOND_LIFE]に぀いお知りたいずきは、キヌを抌しおください。
+ヘルプが必芁なずきや、[SECOND_LIFE]に぀いお知りたいずきは、F1キヌを抌しおください。
男性あるいは女性のアバタヌを遞択しおください。この蚭定は埌で倉曎できたす。
<tag>
confirm
@@ -2189,8 +2189,8 @@ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
発行元[ISSUER_NAME_STRING]
有効日[VALID_FROM]
次の曎新日[VALID_TO]
-フィンガヌプリント[SHA1_DIGEST]
-フィンガヌプリント[MD5_DIGEST]
+MD5フィンガヌプリント[SHA1_DIGEST]
+SHA1フィンガヌプリント[MD5_DIGEST]
キヌ䜿甚法[KEYUSAGE]
拡匵キヌ䜿甚法[EXTENDEDKEYUSAGE]
サブゞェクトキヌ認識別子[SUBJECTKEYIDENTIFIER]
@@ -2201,15 +2201,15 @@ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
</notification>
<notification name="TrustCertificateError">このサヌバヌの認蚌機関は䞍明です。
認蚌情報
- サブゞェクト名[SUBJECT_NAME_STRING]
- 発行元[ISSUER_NAME_STRING]
- 有効日[VALID_FROM]
- 次の曎新日[VALID_TO]
- フィンガヌプリント[SHA1_DIGEST]
- フィンガヌプリント[MD5_DIGEST]
- キヌ䜿甚法[KEYUSAGE]
- 拡匵キヌ䜿甚法[EXTENDEDKEYUSAGE]
- サブゞェクトキヌ認識別子[SUBJECTKEYIDENTIFIER]
+サブゞェクト名[SUBJECT_NAME_STRING]
+発行元[ISSUER_NAME_STRING]
+有効日[VALID_FROM]
+次の曎新日[VALID_TO]
+MD5フィンガヌプリント[SHA1_DIGEST]
+SHA1フィンガヌプリント[MD5_DIGEST]
+キヌ䜿甚法[KEYUSAGE]
+拡匵キヌ䜿甚法[EXTENDEDKEYUSAGE]
+サブゞェクトキヌ認識別子[SUBJECTKEYIDENTIFIER]
この認蚌局を信頌したすか
<tag>
@@ -2232,7 +2232,7 @@ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
[NAME]は、オブゞェクトを線集する暩限を取り消されたした。
</notification>
<notification name="FlushMapVisibilityCaches">このリヌゞョンのマップのキャッシュを消去したす。デバッグ目的のみに䟿利な操䜜です。
-䜜成䞭は分経過するず、党員のマップが再床ログむン埌に曎新されたす
+䜜成䞭は5分経過するず、党員のマップが再床ログむン埌に曎新されたす
<tag>
fail
</tag>
@@ -2281,7 +2281,7 @@ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
テクスチャは、24ビットの512✕512以䞋の画像を遞択し、「適甚」ボタンを再床クリックしおください。
</notification>
<notification name="RawUploadStarted">
- アップロヌドを開始したした。接続速床によっおは、最倧分皋床かかりたす。
+ アップロヌドを開始したした。接続速床によっおは、最倧2分皋床かかりたす。
</notification>
<notification name="ConfirmBakeTerrain">珟圚の地圢を構築しようずしおいたす。この操䜜を行うず珟圚の地圢が、土地の隆起ず沈降の制限範囲の基準ずなり、「埩元」ツヌルのデフォルトになりたす。操䜜を続行したすか
<tag>
@@ -2606,7 +2606,7 @@ OKをクリックしお、ダりンロヌドずむンストヌルを開始した
</tag>
<form name="form">
<input name="message">
- あなたはフリヌズされおいたす。動くこずもチャットするこずもできたせん。管理者がであなたに連絡したす。
+ あなたはフリヌズされおいたす。動くこずもチャットするこずもできたせん。管理者がIMであなたに連絡したす。
</input>
<button name="" text=""/>
<button name="Cancel" text="キャンセル"/>
@@ -3150,19 +3150,19 @@ https://community.secondlife.com/knowledgebase/%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83
fail
</tag>
</notification>
- <notification name="UnableToLoadNotecardAsset">珟圚ノヌトカヌドのアセットを読み蟌むこずができたせん。
+ <notification name="UnableToLoadNotecardAsset">珟圚ノヌトカヌドのアセットIDを読み蟌むこずができたせん。
<tag>
fail
</tag>
<usetemplate name="okbutton" yestext=""/>
</notification>
- <notification name="NotAllowedToViewNotecard">芁求したアセットに関するノヌトカヌドを閲芧するには、暩限が䞍十分です。
+ <notification name="NotAllowedToViewNotecard">芁求したアセットIDに関するノヌトカヌドを閲芧するには、暩限が䞍十分です。
<tag>
fail
</tag>
<usetemplate name="okbutton" yestext=""/>
</notification>
- <notification name="MissingNotecardAssetID">ノヌトカヌド甚のアセットがデヌタベヌスに登録されおいたせん。
+ <notification name="MissingNotecardAssetID">ノヌトカヌド甚のアセットIDがデヌタベヌスに登録されおいたせん。
<tag>
fail
</tag>
@@ -3189,7 +3189,7 @@ https://community.secondlife.com/knowledgebase/%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83
</tag>
<usetemplate canceltext="キャンセル" name="yesnocancelbuttons" notext="いいえ" yestext="はい"/>
</notification>
- <notification label="再起動を確認" name="ConfirmRestart">このリヌゞョンを分埌に再起動しようずしおいたす。このたた続けおもよろしいですか
+ <notification label="再起動を確認" name="ConfirmRestart">このリヌゞョンを2分埌に再起動しようずしおいたす。このたた続けおもよろしいですか
<tag>
confirm
</tag>
@@ -3489,7 +3489,7 @@ https://community.secondlife.com/knowledgebase/%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83
⑎嫌がらせの報告の手順。居䜏者が、[SECOND_LIFE]暩限システムを悪甚しおいるず思われる堎合たずえば、CopyBotたたは同様のコピヌツヌルを䜿甚しお、知的財産暩を䟵害しおいるず思われる堎合は、䞍正䜿甚報告を提出するこずができたす。䞍正行為チヌムは、[SECOND_LIFE][http://secondlife.com/corporate/tos.php 利甚芏玄]や、[http://jp.secondlife.com/corporate/cs.php コミュニティ・スタンダヌド]に違反する行為を調査し、に違反する行為に察する適切な凊眰を䞋したす。ただし、担圓チヌムは[SECOND_LIFE]の䞖界からコンテンツを削陀しお欲しいずいうリク゚ストには応じたせん。
-⑵DMCA たたはコンテンツ削陀プロセス。[SECOND_LIFE]からコンテンツの削陀をリク゚ストするには、[https://www.lindenlab.com/legal/intellectual-property-infringement-notification-policy ポリシヌ]に芏定されおいる有効な暩利䟵害通知を提出する必芁がありたす。
+⑵DMCA たたはコンテンツ削陀プロセス。[SECOND_LIFE]からコンテンツの削陀をリク゚ストするには、[https://www.lindenlab.com/legal/intellectual-property-infringement-notification-policy DMCAポリシヌ]に芏定されおいる有効な暩利䟵害通知を提出する必芁がありたす。
このたた嫌がらせの報告を続けたい堎合は、このりィンドりを閉じお報告の送信を完了しおください。特定のカテゎリ「コピヌ Bot 及び暩限の悪甚」を遞択する必芁がある堎合がありたす。
@@ -3578,7 +3578,7 @@ Linden Lab
</tag>
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="はい"/>
</notification>
- <notification name="ConfirmClearMediaUrlList">保存されたのリストを消去したす。このたた、リストを消去しおもよろしいですか
+ <notification name="ConfirmClearMediaUrlList">保存されたURLのリストを消去したす。このたた、リストを消去しおもよろしいですか
<tag>
confirm
</tag>
@@ -3669,10 +3669,10 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
<notification name="AutoWearNewClothing">䜜成する服装を自動的に装着したすか
<usetemplate ignoretext="「容姿」を線集䞭に、䜜成する服装を装着するずき" name="okcancelignore" notext="いいえ" yestext="はい"/>
</notification>
- <notification name="NotAgeVerified">蚪問しようずしおいる堎所は、歳以䞊の䜏人に制限されおいたす。
+ <notification name="NotAgeVerified">蚪問しようずしおいる堎所は、18歳以䞊の䜏人に制限されおいたす。
<usetemplate ignoretext="幎霢制限付きの゚リアを蚪問する幎霢に達しおいたせん。" name="okignore" yestext=""/>
</notification>
- <notification name="NotAgeVerified_Notify">この堎所ぞの入堎は、歳以䞊に制限されおいたす。
+ <notification name="NotAgeVerified_Notify">この堎所ぞの入堎は、18歳以䞊に制限されおいたす。
<tag>
fail
</tag>
@@ -3708,7 +3708,7 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
<notification name="ReplacedMissingWearable">
欠萜しおいる服装や身䜓郚䜍をデフォルトに眮き換えたす。
</notification>
- <notification name="GroupNotice">件名[SUBJECT] メッセヌゞ[MESSAGE]
+ <notification name="GroupNotice">件名[SUBJECT] メッセヌゞ[MESSAGE]
<tag>
group
</tag>
@@ -3726,7 +3726,7 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
</notification>
<notification name="UploadingAuctionSnapshot">
むンワヌルドずWebサむトのスナップショットをアップロヌド䞭です 
-所芁時間玄分
+所芁時間玄5分
</notification>
<notification name="UploadPayment">アップロヌドにL$ [AMOUNT]支払いたした。
<tag>
@@ -3774,7 +3774,7 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
</tag>
</notification>
<notification name="IMAcrossParentEstates">
- 芪䞍動産間では、を送信できたせん。
+ 芪䞍動産間では、IMを送信できたせん。
</notification>
<notification name="TransferInventoryAcrossParentEstates">
芪䞍動産間でむンベントリを移動するこずはできたせん。
@@ -3855,7 +3855,7 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
[NAME]は、むンベントリの提䟛を断りたした。
</notification>
<notification name="ObjectMessage">
- [NAME][MESSAGE]
+ [NAME]: [MESSAGE]
</notification>
<notification name="CallingCardAccepted">
コヌリングカヌドが受理されたした。
@@ -3870,7 +3870,7 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
この操䜜は、ランドマヌクをダブルクリックするか、右クリックしお「テレポヌト」を遞択しお実行するこずもできたす。
</notification>
<notification name="TeleportToPerson">
- 誰かずのプラむベヌトな䌚話を開くには、盞手のアバタヌをクリックしお、メニュヌから「」を遞択したす。
+ 誰かずのプラむベヌトな䌚話を開くには、盞手のアバタヌをクリックしお、メニュヌから「IM」を遞択したす。
</notification>
<notification name="CantSelectLandFromMultipleRegions">サヌバヌの境界を越えお土地を遞択するこずできたせん。
もっず小さな土地を遞択しおください。
@@ -4000,14 +4000,14 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
<unique/>
<usetemplate name="okbutton" yestext="リヌゞョンの再構築"/>
</notification>
- <notification name="DynamicPathfindingDisabled">このリヌゞョン地域においお、動的経路探玢が有効になっおいたせん。経路探玢呌び出しを䜿甚するスクリプトの入ったオブゞェクトは、このリヌゞョンで期埅どおりに動䜜しない可胜性がありたす。
+ <notification name="DynamicPathfindingDisabled">このリヌゞョン地域においお、動的経路探玢が有効になっおいたせん。経路探玢LSL呌び出しを䜿甚するスクリプトの入ったオブゞェクトは、このリヌゞョンで期埅どおりに動䜜しない可胜性がありたす。
<unique/>
</notification>
<notification name="PathfindingCannotRebakeNavmesh">゚ラヌが発生したした。ネットワヌクたたはサヌバヌに問題があるか、制䜜する暩限がない可胜性がありたす。この問題は、䞀床ログアりトしおから、ログむンし盎すず解決される堎合がありたす。
<unique/>
<usetemplate name="okbutton" yestext=""/>
</notification>
- <notification name="SeeAvatars">この区画にいるアバタヌやこの区画内で行われる文字チャットは、他の区画から芋えたせん。あなたには、この区画倖にいる䜏人が芋えず、倖の䜏人にはあなたの姿が芋えたせん。チャンネルでの通垞の文字チャットもブロックされたす。
+ <notification name="SeeAvatars">この区画にいるアバタヌやこの区画内で行われる文字チャットは、他の区画から芋えたせん。あなたには、この区画倖にいる䜏人が芋えず、倖の䜏人にはあなたの姿が芋えたせん。チャンネル0での通垞の文字チャットもブロックされたす。
<unique/>
</notification>
<notification name="ScriptsStopped">
@@ -4048,12 +4048,12 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
fail
</tag>
</notification>
- <notification name="MustGetAgeRegion">このリヌゞョン地域に入るには、歳以䞊である必芁がありたす。
+ <notification name="MustGetAgeRegion">このリヌゞョン地域に入るには、18歳以䞊である必芁がありたす。
<tag>
fail
</tag>
</notification>
- <notification name="MustGetAgeParcel">この区画に入るには、歳以䞊である必芁がありたす。
+ <notification name="MustGetAgeParcel">この区画に入るには、18歳以䞊である必芁がありたす。
<tag>
fail
</tag>
@@ -4296,7 +4296,7 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
</tag>
</notification>
<notification name="OfferCallingCard">[NAME]が、コヌリングカヌドを枡そうずしおいたす。
-あなたのむンベントリにブックマヌクが远加され、この䜏人に玠早くを送るこずができたす。
+あなたのむンベントリにブックマヌクが远加され、この䜏人に玠早くIMを送るこずができたす。
<tag>
friendship
</tag>
@@ -4317,7 +4317,7 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
[MESSAGE]
-送信元のオブゞェクト&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt; 所有者[NAME_SLURL]
+送信元のオブゞェクト&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt; 所有者[NAME_SLURL]
<tag>
confirm
</tag>
@@ -4457,7 +4457,7 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
</notification>
<notification name="BuyLindenDollarSuccess">お支払ありがずうございたす。
-あなたのL$残高は、凊理が完了するずアップデヌトされたす。凊理に分以䞊かかった堎合、お取り匕きがキャンセルされるこずがありたす。その堎合は、賌入金額はあなたの US$残高に远加されたす。 [https://secondlife.com/my/account/?lang=ja-JP マむアカりント]の取匕履歎ペヌゞで、支払状況を確認できたす。
+あなたのL$残高は、凊理が完了するずアップデヌトされたす。凊理に20分以䞊かかった堎合、お取り匕きがキャンセルされるこずがありたす。その堎合は、賌入金額はあなたの US$残高に远加されたす。 [https://secondlife.com/my/account/?lang=ja-JP マむアカりント]の取匕履歎ペヌゞで、支払状況を確認できたす。
<tag>
funds
</tag>
@@ -4745,11 +4745,11 @@ Webペヌゞにリンクするず、他人がこの堎所に簡単にアクセã‚
<button name="respondbutton" text="返答"/>
</form>
</notification>
- <notification name="ConfirmCloseAll">すべおのを閉じたすか
+ <notification name="ConfirmCloseAll">すべおのIMを閉じたすか
<tag>
confirm
</tag>
- <usetemplate ignoretext="すべおのを閉じる前の確認" name="okcancelignore" notext="キャンセル" yestext=""/>
+ <usetemplate ignoretext="すべおのIMを閉じる前の確認" name="okcancelignore" notext="キャンセル" yestext=""/>
</notification>
<notification name="AttachmentSaved">
装着物が保存されたした。
@@ -5075,7 +5075,7 @@ UDP3478, 3479, 5060, 5062, 6250, 12000-32000
メモリプヌル残量が少なくなっおいたす。クラッシュを避けるため[APP_NAME]の機胜の䞀郚は無効になりたした。他のアプリケヌションを終了し、状況が継続たたは再発する堎合にはSecond Lifeを再起動しおください。
</notification>
<notification name="ForceQuitDueToLowMemory">
- メモリ䞍足のため秒以内に[APP_NAME]は終了したす。
+ メモリ䞍足のため30秒以内に[APP_NAME]は終了したす。
</notification>
<notification name="SOCKS_NOT_PERMITTED">ルヌルセットによっお蚱可されおいないため、SOCKS 5プロキシ"[HOST]:[PORT]"が接続を拒絶したした。
<tag>
@@ -5275,7 +5275,7 @@ UDP3478, 3479, 5060, 5062, 6250, 12000-32000
<tag>
confirm
</tag>
- <usetemplate ignoretext="を非衚瀺前の確認" name="okcancelignore" notext="キャンセル" yestext=""/>
+ <usetemplate ignoretext="UIを非衚瀺前の確認" name="okcancelignore" notext="キャンセル" yestext=""/>
</notification>
<notification name="PathfindingLinksets_WarnOnPhantom">遞択された䞀郚のリンクセットはファントムフラグが切り替えられたす。
@@ -6220,7 +6220,7 @@ UDP3478, 3479, 5060, 5062, 6250, 12000-32000
fail
</tag>
</notification>
- <notification name="TenObjectsDisabledPlzRefresh">遞択された最初の個のオブゞェクトのみが無効にされたした。必芁に応じお、リフレッシュしお遞択内容を远加しおください。
+ <notification name="TenObjectsDisabledPlzRefresh">遞択された最初の10個のオブゞェクトのみが無効にされたした。必芁に応じお、リフレッシュしお遞択内容を远加しおください。
<tag>
fail
</tag>
@@ -6638,9 +6638,9 @@ UDP3478, 3479, 5060, 5062, 6250, 12000-32000
fail
</tag>
</notification>
- <notification name="CompressionTestResults">サむズ[SIZE]㎅のファむル[FILE]をgzipのレベルで圧瞮したテスト結果
-圧瞮[PACK_TIME]秒 [PSIZE]㎅
-解凍[UNPACK_TIME]秒 [USIZE]㎅
+ <notification name="CompressionTestResults">サむズ[SIZE]㎅のファむル[FILE]をgzipのレベル6で圧瞮したテスト結果
+圧瞮[PACK_TIME]秒 [PSIZE]㎅
+解凍[UNPACK_TIME]秒 [USIZE]㎅
<tag>
fail
</tag>
@@ -6674,7 +6674,7 @@ UDP3478, 3479, 5060, 5062, 6250, 12000-32000
</tag>
<usetemplate name="okbutton" yestext=""/>
</notification>
- <notification name="RiggedMeshAttachedToHUD">ポむント「[POINT]」にアタッチされたオブゞェクト「[NAME]」にはリグメッシュが含たれおいたす。
+ <notification name="RiggedMeshAttachedToHUD">HUDポむント「[POINT]」にアタッチされたオブゞェクト「[NAME]」にはリグメッシュが含たれおいたす。
リグメッシュオブゞェクトは、アバタヌに取り付けるように蚭蚈されおいたす。あなたにはこのオブゞェクトが衚瀺されたすが、他の人には衚瀺されたせん。
@@ -6682,9 +6682,9 @@ UDP3478, 3479, 5060, 5062, 6250, 12000-32000
<tag>
confirm
</tag>
- <usetemplate ignoretext="リグメッシュがポむントにアタッチされおいる堎合に譊告したす。" name="okignore" yestext=""/>
+ <usetemplate ignoretext="リグメッシュがHUDポむントにアタッチされおいる堎合に譊告したす。" name="okignore" yestext=""/>
</notification>
- <notification name="EnableAutoFPSWarning" type="alertmodal">自動を有効にしようずしおいたす。保存されおいないグラフィック蚭定はすべお倱われたす。
+ <notification name="EnableAutoFPSWarning" type="alertmodal">自動FPSを有効にしようずしおいたす。保存されおいないグラフィック蚭定はすべお倱われたす。
たずそれらを保存したすか
<tag>
diff --git a/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml
index b920a0a8f7..848e3d2f33 100644
--- a/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml
@@ -24,7 +24,7 @@
<icon name="hovered_icon"/>
<icon name="selected_icon"/>
<text name="avatar_name" value="読み蟌んでいたす"/>
- <text name="last_interaction" value="秒"/>
+ <text name="last_interaction" value="0秒"/>
<icon name="permission_edit_theirs_icon" tool_tip="このフレンドのオブゞェクトを線集するこずができたす。"/>
<icon name="permission_edit_mine_icon" tool_tip="このフレンドは、あなたのオブゞェクトを線集・削陀・取埗するこずができたす。"/>
<icon tool_tip="このフレンドはマップ䞊であなたの䜍眮を衚瀺できたす。" name="permission_map_icon"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml
index 156f475fc6..56b6e88c7b 100644
--- a/indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="clothing_list_button_bar_panel">
- <button label="远加" name="add_btn"/>
+ <button label="远加 +" name="add_btn"/>
<button name="clothing_shop_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_universal.xml b/indra/newview/skins/default/xui/ja/panel_edit_universal.xml
index fd5fe80848..6d6ee5622f 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_universal.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_universal.xml
@@ -10,9 +10,9 @@
<texture_picker label="目のタトゥ" name="Eyes Tattoo" tool_tip="クリックしお画像を遞択する"/>
<texture_picker label="巊腕のタトゥ" name="Left Arm Tattoo" tool_tip="クリックしお画像を遞択する"/>
<texture_picker label="巊脚のタトゥ" name="Left Leg Tattoo" tool_tip="クリックしお画像を遞択する"/>
- <texture_picker label="予備のタトゥ" name="Aux1 Tattoo" tool_tip="クリックしお画像を遞択する"/>
- <texture_picker label="予備のタトゥ" name="Aux2 Tattoo" tool_tip="クリックしお画像を遞択する"/>
- <texture_picker label="予備のタトゥ" name="Aux3 Tattoo" tool_tip="クリックしお画像を遞択する"/>
+ <texture_picker label="予備1のタトゥ" name="Aux1 Tattoo" tool_tip="クリックしお画像を遞択する"/>
+ <texture_picker label="予備2のタトゥ" name="Aux2 Tattoo" tool_tip="クリックしお画像を遞択する"/>
+ <texture_picker label="予備3のタトゥ" name="Aux3 Tattoo" tool_tip="クリックしお画像を遞択する"/>
<color_swatch label="色明暗" name="Color/Tint" tool_tip="クリックしおカラヌピッカヌを開きたす"/>
</panel>
</scroll_container>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_bulk_ban.xml b/indra/newview/skins/default/xui/ja/panel_group_bulk_ban.xml
index 962d69c67c..27d9b088cb 100644
--- a/indra/newview/skins/default/xui/ja/panel_group_bulk_ban.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_bulk_ban.xml
@@ -4,7 +4,7 @@
読み蟌んでいたす 
</panel.string>
<panel.string name="ban_selection_too_large">
- グルヌプのバンが送信されおいたせん遞択した䜏人が倚すぎたす。グルヌプぞの立入犁止の数はリク゚スト圓たり人に制限されおいたす。
+ グルヌプのバンが送信されおいたせん遞択した䜏人が倚すぎたす。グルヌプぞの立入犁止の数は1リク゚スト圓たり100人に制限されおいたす。
</panel.string>
<panel.string name="ban_not_permitted">
グルヌプのバンが送信されおいたせん「立入犁止リストの管理」の胜力がありたせん。
diff --git a/indra/newview/skins/default/xui/ja/panel_group_creation_sidetray.xml b/indra/newview/skins/default/xui/ja/panel_group_creation_sidetray.xml
index 42e3b0050e..5e5fbfff9f 100644
--- a/indra/newview/skins/default/xui/ja/panel_group_creation_sidetray.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_creation_sidetray.xml
@@ -53,7 +53,7 @@
</layout_panel>
</layout_stack>
<text name="info_deletion">
- 泚時間メンバヌが人未満のグルヌプは、自動的に解散されたす。
+ 泚48時間メンバヌが2人未満のグルヌプは、自動的に解散されたす。
</text>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_invite.xml b/indra/newview/skins/default/xui/ja/panel_group_invite.xml
index 85f0cba760..1177d5930d 100644
--- a/indra/newview/skins/default/xui/ja/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_invite.xml
@@ -11,7 +11,7 @@
</panel.string>
<panel.string name="invite_selection_too_large">
グルヌプぞの招埅が送信されおいたせん遞択された䜏人が倚すぎたす。
-グルヌプぞの招埅は回のリク゚ストあたり人に制限されおいたす。
+グルヌプぞの招埅は1回のリク゚ストあたり100人に制限されおいたす。
</panel.string>
<text name="help_text">
グルヌプには䞀床に耇数の䜏人を招埅するこずができたす。「リストから䜏人を遞択」をクリックしおください。
diff --git a/indra/newview/skins/default/xui/ja/panel_group_notices.xml b/indra/newview/skins/default/xui/ja/panel_group_notices.xml
index ebde7f9944..8045c26724 100644
--- a/indra/newview/skins/default/xui/ja/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_notices.xml
@@ -9,8 +9,8 @@
過去の通知はありたせん
</panel.string>
<text name="lbl2">
- 通知は日間保存されたす。
-日の制限数は通です。
+ 通知は14日間保存されたす。
+1日の制限数は200通です。
</text>
<scroll_list name="notice_list">
<scroll_list.columns label="" name="icon"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_roles.xml b/indra/newview/skins/default/xui/ja/panel_group_roles.xml
index bd16e3e986..1a063a3592 100644
--- a/indra/newview/skins/default/xui/ja/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_roles.xml
@@ -30,7 +30,7 @@ Ctrlキヌを抌しながら、メンバヌ名をクリックするこずで耇æ
<panel.string name="help_text">
圹割には、タむトルず蚱可された胜力が割り圓おられおいたす。
メンバヌは぀以䞊の圹割を持぀こずができたす。
-グルヌプで䜿える圹割は個たでで、「党員Everyone」ず「所有者Owner」がそれに含たれおいたす。
+グルヌプで䜿える圹割は10個たでで、「党員Everyone」ず「所有者Owner」がそれに含たれおいたす。
</panel.string>
<panel.string name="cant_delete_role">
「党員Everyone」ず「所有者Owner」の圹割は削陀するこずができたせん。
diff --git a/indra/newview/skins/default/xui/ja/panel_landmark_info.xml b/indra/newview/skins/default/xui/ja/panel_landmark_info.xml
index c95320e53a..4055e23d9f 100644
--- a/indra/newview/skins/default/xui/ja/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/ja/panel_landmark_info.xml
@@ -16,7 +16,7 @@
この䜍眮の情報は、アクセス制限のためご利甚いただけたせん。蚱可に぀いおは区画所有者にお問い合わせください。
</string>
<string name="acquired_date">
- [year,datetime,local]幎[mth,datetime,local]月[day,datetime,local]日[wkday,datetime,local] [hour,datetime,local][min,datetime,local][second,datetime,local]
+ [year,datetime,local]幎[mth,datetime,local]月[day,datetime,local]日[wkday,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local]
</string>
<string name="icon_PG" value="Parcel_PG_Dark"/>
<string name="icon_M" value="Parcel_M_Dark"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
index 5b5116a05d..c75fd8b1ca 100644
--- a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
@@ -19,7 +19,7 @@
<item label="名前" name="Name" value="search_by_name"/>
<item label="制䜜者" name="Creator" value="search_by_creator"/>
<item label="説明" name="Description" value="search_by_description"/>
- <item label="" name="UUID" value="search_by_UUID"/>
+ <item label="UUID" name="UUID" value="search_by_UUID"/>
</combo_box>
<menu_button tool_tip="怜玢衚瀺オプションを衚瀺" name="options_visibility_btn"/>
<filter_editor label="怜玢甚語を入力する" name="inventory search editor"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_media_settings_general.xml b/indra/newview/skins/default/xui/ja/panel_media_settings_general.xml
index 5d984cb58c..39d9863a0a 100644
--- a/indra/newview/skins/default/xui/ja/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_media_settings_general.xml
@@ -28,7 +28,7 @@
サむズ
</text>
<text name="X_label">
- 
+ X
</text>
<spinner label="" name="height_pixels"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
index 08edb447cb..7c7ce83a01 100644
--- a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="nearby_chat">
- <line_editor label="ここをクリックしおチャットを開始したす。" name="chat_box" tool_tip="Enterキヌで発蚀し、CtrlEnterキヌでシャりトしたす。"/>
+ <line_editor label="ここをクリックしおチャットを開始したす。" name="chat_box" tool_tip="Enterキヌで発蚀し、Ctrl+Enterキヌで叫びたす。"/>
<button name="show_nearby_chat" tool_tip="近隣チャットログを衚瀺非衚瀺"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
index 1093624cda..9c3b51adb9 100644
--- a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
@@ -19,8 +19,8 @@
<button label="すべお停止" name="all_nearby_media_disable_btn" tool_tip="近隣のメディアをすべおオフにしたす"/>
<button label="すべお開始" name="all_nearby_media_enable_btn" tool_tip="近隣のメディアをすべおオンにしたす"/>
<button name="open_prefs_btn" tool_tip="メディアの蚭定を開きたす"/>
- <button label="詳现 ≫" label_selected="≪ 簡易" name="more_btn" tool_tip="拡匵コントロヌル"/>
- <button label="詳现 ≫" label_selected="≪ 簡易" name="less_btn" tool_tip="拡匵コントロヌル"/>
+ <button label="詳现 &gt;&gt;" label_selected="&lt;&lt; 簡易" name="more_btn" tool_tip="拡匵コントロヌル"/>
+ <button label="詳现 &gt;&gt;" label_selected="&lt;&lt; 簡易" name="less_btn" tool_tip="拡匵コントロヌル"/>
</panel>
<panel name="nearby_media_panel">
<text name="nearby_media_title">
diff --git a/indra/newview/skins/default/xui/ja/panel_notification_list_item.xml b/indra/newview/skins/default/xui/ja/panel_notification_list_item.xml
index 00733bf79d..f1fa54d14e 100644
--- a/indra/newview/skins/default/xui/ja/panel_notification_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_notification_list_item.xml
@@ -40,7 +40,7 @@
<text name="sender_or_fee_box">
送信者䜏民 じゅうみん
</text>
- <text name="notification_time" value="2014幎12月24日 2330"/>
+ <text name="notification_time" value="2014幎12月24日 23:30"/>
</panel>
</panel>
</layout_panel>
@@ -76,7 +76,7 @@
<text name="sender_or_fee_box_exp">
送信者䜏民 じゅうみん
</text>
- <text name="notification_time_exp" value="2014幎12月24日 2330"/>
+ <text name="notification_time_exp" value="2014幎12月24日 23:30"/>
</panel>
<panel name="notification_text_panel_exp">
<chat_editor name="notification_text_exp">
diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml
index 516ee3c7d2..fbdaa319a2 100644
--- a/indra/newview/skins/default/xui/ja/panel_people.xml
+++ b/indra/newview/skins/default/xui/ja/panel_people.xml
@@ -19,7 +19,7 @@
<string name="AltMiniMapToolTipMsg" value="[地域]ダブルクリックでテレポヌト。Shift‐ドラッグで氎平・垂盎移動"/>
<string name="GroupCountWithInfo" value="あなたは珟圚、[COUNT]グルヌプに属しおいたす。あず[REMAINING]グルヌプに参加するこずができたす。[secondlife:/// 䞊限を増やす]"/>
<tab_container name="tabs">
- <panel label="近隣" name="nearby_panel">
+ <panel label="近く" name="nearby_panel">
<panel label="bottom_panel" name="nearby_buttons_panel">
<filter_editor label="人物をフィルタ" name="nearby_filter_input"/>
<button name="gear_btn" tool_tip="遞択した人物に察するアクション"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/ja/panel_performance_autoadjustments.xml
index 3a0eeae6d5..fdbfca64ce 100644
--- a/indra/newview/skins/default/xui/ja/panel_performance_autoadjustments.xml
+++ b/indra/newview/skins/default/xui/ja/panel_performance_autoadjustments.xml
@@ -24,12 +24,12 @@
<combo_box.item label="アバタヌずワヌルド" name="av_and_scene" value="1"/>
<combo_box.item label="ワヌルドのみ" name="scene_only" value="2"/>
</combo_box>
- <button label="今すぐ自動調敎" name="start_autotune" tool_tip="ビュヌアヌは、目暙を満たすように蚭定が調敎されるたで停止したす。"/>
+ <button label="今すぐ自動調敎" name="start_autotune" tool_tip="ビュヌアヌは、目暙FPSを満たすように蚭定が調敎されるたで停止したす。"/>
<button label="キャンセル" name="stop_autotune" tool_tip="自動調敎を䞭断したす。"/>
<text name="wip_desc">
調敎䞭です 
</text>
- <check_box label="継続的に調敎する" name="AutoTuneContinuous" tool_tip="ビュヌアヌは、このフロヌタヌが閉じおいおも停止するたで、目暙を満たすように蚭定を継続的に調敎したす。">
+ <check_box label="継続的に調敎する" name="AutoTuneContinuous" tool_tip="ビュヌアヌは、このフロヌタヌが閉じおいおも停止するたで、目暙FPSを満たすように蚭定を継続的に調敎したす。">
</check_box>
<radio_group name="autotune_lock_type">
<radio_item label="このログむンセッションのみ" name="one_session_lock" value="0"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_performance_huds.xml b/indra/newview/skins/default/xui/ja/panel_performance_huds.xml
index 51d9e73540..2d53d74d0d 100644
--- a/indra/newview/skins/default/xui/ja/panel_performance_huds.xml
+++ b/indra/newview/skins/default/xui/ja/panel_performance_huds.xml
@@ -5,13 +5,13 @@
戻る
</text>
<text name="huds_title">
- アクティブな
+ アクティブなHUD
</text>
<text name="huds_desc1">
- 䜿甚しおいないを取り倖すずメモリが節玄され、Second Lifeの凊理が高速化されたす。
+ 䜿甚しおいないHUDを取り倖すずメモリが節玄され、Second Lifeの凊理が高速化されたす。
</text>
<text name="huds_desc2">
- 泚意の最小化ボタンを䜿甚しおも、を取り倖したこずにはなりたせん。
+ 泚意HUDの最小化ボタンを䜿甚しおも、HUDを取り倖したこずにはなりたせん。
</text>
<name_list name="hud_list">
<name_list.columns label="" name="complex_visual"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_performance_preferences.xml b/indra/newview/skins/default/xui/ja/panel_performance_preferences.xml
index 40e7800adc..2e165b11b6 100644
--- a/indra/newview/skins/default/xui/ja/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/ja/panel_performance_preferences.xml
@@ -7,7 +7,7 @@
<text name="settings_title">
グラフィック蚭定
</text>
- <button label="拡匵蚭定を開く" name="advanced_btn"/>
+ <button label="詳现蚭定を開く" name="advanced_btn"/>
<button label="掚奚蚭定にリセット" name="defaults_btn"/>
<view_border name="border0"/>
<text name="quality_lbl">
@@ -40,7 +40,7 @@
</text>
<slider name="draw_distance"/>
<text name="draw_distance_m">
- 
+ m
</text>
<text name="farther_lbl">
遠景
@@ -58,7 +58,7 @@
<check_box label="倧気呚蟺シェヌダヌ" name="atmospheric_shaders"/>
<check_box label="高床な光源モデル" name="advanced_lighting_model"/>
<text name="RenderShadowDetailText">
- 圱
+ 圱
</text>
<combo_box name="ShadowDetail">
<combo_box.item label="なし" name="0" value="0"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_place_profile.xml b/indra/newview/skins/default/xui/ja/panel_place_profile.xml
index 21843e4420..5bd1611a2e 100644
--- a/indra/newview/skins/default/xui/ja/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/ja/panel_place_profile.xml
@@ -39,7 +39,7 @@
この堎所の情報は、アクセス制限のためご利甚いただけたせん。蚱可に぀いおは区画所有者にお問い合わせください。
</string>
<string name="acquired_date">
- [year,datetime,local]幎[mth,datetime,local]月[day,datetime,local]日[wkday,datetime,local] [hour,datetime,local][min,datetime,local][second,datetime,local]
+ [year,datetime,local]幎[mth,datetime,local]月[day,datetime,local]日[wkday,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local]
</string>
<button name="back_btn" tool_tip="戻る"/>
<text name="title" value="堎所のプロフィヌル"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml b/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml
index 6373eadabc..f74059e7f1 100644
--- a/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml
@@ -2,9 +2,9 @@
<panel name="panel_postcard_settings">
<combo_box label="解像床" name="postcard_size_combo">
<combo_box.item label="珟圚のりィンドり" name="CurrentWindow"/>
- <combo_box.item label="✕" name="640x480"/>
- <combo_box.item label="✕" name="800x600"/>
- <combo_box.item label="✕" name="1024x768"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
<combo_box.item label="カスタム" name="Custom"/>
</combo_box>
<spinner label="暪幅✕高さ" name="postcard_snapshot_width"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
index 40998f8035..72da378efb 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="拡匵" name="advanced">
+<panel label="アドバンス" name="advanced">
<panel.string name="aspect_ratio_text">
- [NUM][DEN]
+ [NUM]:[DEN]
</panel.string>
<text name="Cache:">
キャッシュ
@@ -17,19 +17,19 @@
<button label="参照" label_selected="参照" name="set_cache"/>
<button label="デフォルトの堎所" label_selected="デフォルトの堎所" name="default_cache_location"/>
<text name="UI Size:">
- のサむズ
+ UIのサむズ
</text>
<text name="HUD Size:">
- のスケヌル
+ HUDのスケヌル
</text>
- <check_box label="スクリプトの゚ラヌを衚瀺" name="show_script_errors"/>
+ <check_box label="スクリプトの゚ラヌを衚瀺:" name="show_script_errors"/>
<radio_group name="show_location">
<radio_item label="近隣チャット" name="0"/>
<radio_item label="別々のりィンドり" name="1"/>
</radio_group>
<check_box label="耇数のビュヌアを蚱可" name="allow_multiple_viewer_check"/>
<check_box label="ログむン時にグリッド遞択を衚瀺" name="show_grid_selection_check"/>
- <check_box label="拡匵メニュヌを衚瀺" name="show_advanced_menu_check"/>
+ <check_box label="アドバンスメニュヌを衚瀺" name="show_advanced_menu_check"/>
<check_box label="開発メニュヌを衚瀺" name="show_develop_menu_check"/>
<button label="蚘録枈みのナヌザ名" name="remembered_usernames"/>
<button label="デフォルトの䜜成暩限" name="default_creation_permissions"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
index dd11296729..8246c1e07c 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
@@ -4,12 +4,12 @@
<panel name="general_chat_settings">
<check_box initial_value="true" label="チャット䞭にタむピング動䜜のアニメヌションを再生" name="play_typing_animation"/>
<check_box label="オフラむン時に受け取ったはメヌルで受信する" name="send_im_to_email"/>
- <check_box label="フレンドずグルヌプ以倖からのコヌルずは受信しない" name="voice_call_friends_only_check"/>
+ <check_box label="フレンドずグルヌプ以倖からのコヌルずIMは受信しない" name="voice_call_friends_only_check"/>
<text name="email_settings">
- [https://accounts.secondlife.com/change_email?lang=ja オフラむン時ののメヌル送信先の蚭定]
+ [https://accounts.secondlife.com/change_email?lang=ja オフラむン時のIMのメヌル送信先の蚭定]
</text>
<text name="font_size">
- 文字の倧きさ
+ フォントサむズ
</text>
<combo_box name="chat_font_size">
<item label="小" name="Small" value="0"/>
@@ -20,7 +20,7 @@
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
- フレンド
+ フレンドからのIM
</text>
<combo_box name="FriendIMOptions">
<item label="開いおいる䌚話りィンドり" name="OpenConversationsWindow" value="openconversations"/>
@@ -30,7 +30,7 @@
</combo_box>
<check_box label="サりンドを再生" name="play_sound_friend_im"/>
<text name="non_friend_ims">
- フレンドのいない
+ フレンド以倖からのIM
</text>
<combo_box name="NonFriendIMOptions">
<item label="開いおいる䌚話りィンドり" name="OpenConversationsWindow" value="openconversations"/>
@@ -40,7 +40,7 @@
</combo_box>
<check_box label="サりンドを再生" name="play_sound_non_friend_im"/>
<text name="conference_ims">
- 䌚話
+ 䌚議IM
</text>
<combo_box name="ConferenceIMOptions">
<item label="開いおいる䌚話りィンドり" name="OpenConversationsWindow" value="openconversations"/>
@@ -70,7 +70,7 @@
</combo_box>
<check_box label="サりンドを再生" name="play_sound_nearby_chat_im"/>
<text name="object_ims">
- オブゞェクトによる
+ オブゞェクトによるIM
</text>
<combo_box name="ObjectIMOptions">
<item label="開いおいる䌚話りィンドり" name="OpenConversationsWindow" value="openconversations"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_colors.xml b/indra/newview/skins/default/xui/ja/panel_preferences_colors.xml
index b740f85806..d57f8d12f5 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_colors.xml
@@ -29,13 +29,13 @@
所有者
</text>
<text name="text_box9">
- 
+ URL
</text>
<text name="bubble_chat">
名前の衚瀺の背景色吹き出しチャットにも適甚
</text>
<color_swatch name="background" tool_tip="名前の衚瀺色を遞択"/>
- <slider label="䞍透明床" name="bubble_chat_opacity" tool_tip="名前の衚瀺の䞍透明床を遞択"/>
+ <slider label="䞍透明床:" name="bubble_chat_opacity" tool_tip="名前の衚瀺の䞍透明床を遞択"/>
<text name="floater_opacity">
フロヌタヌの透過床
</text>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
index 9309dda5af..eff831a7ac 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
@@ -45,7 +45,7 @@
<check_box label="ナヌザヌ名" name="show_slids" tool_tip="bobsmith123 などナヌザヌ名を衚瀺"/>
<check_box label="グルヌプタむトル" name="show_all_title_checkbox1" tool_tip="オフィサヌたたはメンバヌなど、グルヌプタむトルを衚瀺"/>
<check_box label="フレンドをハむラむト衚瀺" name="show_friends" tool_tip="フレンドの名前をハむラむト衚瀺"/>
- <check_box label="衚瀺名を衚瀺" name="display_names_check" tool_tip="これを遞択するず、チャット、などで衚瀺名が衚瀺されたす。"/>
+ <check_box label="衚瀺名を衚瀺" name="display_names_check" tool_tip="これを遞択するず、チャット、IMなどで衚瀺名が衚瀺されたす。"/>
<text name="inworld_typing_rg_label">
特定キヌを抌したずきの動䜜
</text>
@@ -57,10 +57,10 @@
「離垭」ずするたでの時間
</text>
<combo_box label="「離垭」ずするたでの時間" name="afk">
- <combo_box.item label="分" name="item0"/>
- <combo_box.item label="分" name="item1"/>
- <combo_box.item label="分" name="item2"/>
- <combo_box.item label="分" name="item3"/>
+ <combo_box.item label="2分" name="item0"/>
+ <combo_box.item label="5分" name="item1"/>
+ <combo_box.item label="10分" name="item2"/>
+ <combo_box.item label="30分" name="item3"/>
<combo_box.item label="離垭蚭定なし" name="item4"/>
</combo_box>
<text name="text_box3">
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
index 79a4689526..a70b30c57f 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
@@ -37,7 +37,7 @@
<slider name="QualityPerformanceSelection"/>
<slider control_name="RenderFarClip" label="描画距離" name="DrawDistance"/>
<text name="DrawDistanceMeterText2">
- 
+ m
</text>
<check_box initial_value="true" label="倧気呚蟺シェヌダヌ" name="WindLightUseAtmosShaders"/>
<check_box initial_value="true" label="高床な光源モデル" name="UseLightShaders"/>
@@ -56,5 +56,5 @@
<button label="プリセットを削陀 " name="PrefDeleteButton"/>
<button label="プリセットを削陀 " name="PrefDeleteButton"/>
<button label="掚奚蚭定にリセット" name="Defaults"/>
- <button label="拡匵蚭定 " name="AdvancedSettings"/>
+ <button label="詳现蚭定 " name="AdvancedSettings"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_sound.xml b/indra/newview/skins/default/xui/ja/panel_preferences_sound.xml
index 3956e07bf8..85be779053 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_sound.xml
@@ -4,10 +4,10 @@
䞭倮のボタン
</panel.string>
<panel.string name="button4_mouse">
- ボタン
+ マりスボタン4
</panel.string>
<panel.string name="button5_mouse">
- ボタン
+ マりスボタン5
</panel.string>
<slider label="党䜓のボリュヌム" name="System Volume"/>
<button name="mute_audio"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_presets_pulldown.xml b/indra/newview/skins/default/xui/ja/panel_presets_pulldown.xml
index b4504dd39a..128669260a 100644
--- a/indra/newview/skins/default/xui/ja/panel_presets_pulldown.xml
+++ b/indra/newview/skins/default/xui/ja/panel_presets_pulldown.xml
@@ -5,6 +5,6 @@
</text>
<scroll_list name="preset_list"/>
<view_border name="horiz_separator"/>
- <button name="open_prefs_btn" label="グラフィック初期蚭定" tool_tip="グラフィック蚭定を呌び出したす。"/>
- <button name="open_autofps_btn" label="自動蚭定" tool_tip="自動調敎蚭定を呌び出したす。"/>
+ <button name="open_prefs_btn" label="グラフィック蚭定" tool_tip="グラフィック蚭定を呌び出したす。"/>
+ <button name="open_autofps_btn" label="自動FPS蚭定" tool_tip="自動調敎蚭定を呌び出したす。"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml
index 6c33bda5cd..038a7aa49f 100644
--- a/indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml
@@ -64,7 +64,7 @@
<button name="close_btn" tool_tip="ズヌムバック"/>
</layout_panel>
<layout_panel name="new_window">
- <button name="new_window_btn" tool_tip="をブラりザで開く"/>
+ <button name="new_window_btn" tool_tip="URLをブラりザで開く"/>
</layout_panel>
</layout_stack>
<icon name="media_secure_lock_flag" tool_tip="安党なブラりゞング"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
index 71e223b90b..1c9111606e 100644
--- a/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
+++ b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_profile" label="プロフィヌル">
- <string name="date_format" value="での誕生日[year,datetime,utc]幎[mth,datetime,utc]月[day,datetime,utc]日"/>
+ <string name="date_format" value="SLでの誕生日[year,datetime,utc]幎[mth,datetime,utc]月[day,datetime,utc]日"/>
<string name="age_format" value="[AGE]経過"/>
<string name="partner_text" value="パヌトナヌ[LINK]"/>
<string name="CaptionTextAcctInfo">
diff --git a/indra/newview/skins/default/xui/ja/panel_region_covenant.xml b/indra/newview/skins/default/xui/ja/panel_region_covenant.xml
index 9b2239e0bb..16349b45d4 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_covenant.xml
@@ -45,7 +45,7 @@
皮類
</text>
<text name="region_landtype_text">
- メむンランド入怍地
+ メむンランド / ホヌムステッド
</text>
<text name="region_maturity_lbl">
区分
diff --git a/indra/newview/skins/default/xui/ja/panel_region_environment.xml b/indra/newview/skins/default/xui/ja/panel_region_environment.xml
index 48aa2a0adb..969c8f699c 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_environment.xml
@@ -7,7 +7,7 @@
リヌゞョン地域の蚭定を䜿甚
</string>
<string name="str_altitude_desription">
- 空 [INDEX][ALTITUDE]
+ 空 [INDEX][ALTITUDE]m
</string>
<string name="str_no_parcel">
区画が遞択されおいたせん。環境の蚭定は無効になっおいたす。
@@ -48,7 +48,7 @@
</layout_panel>
<layout_panel name="pnl_environment_length">
<text name="lbl_apparent_time">
- [AP] [HH][MM][PRC]
+ [AP] [HH]:[MM] ([PRC]%)
</text>
</layout_panel>
<layout_panel name="pnl_environment_buttons"/>
@@ -57,7 +57,7 @@
<layout_panel name="pnl_environment_altitudes">
<panel name="pnl_alt1">
<text name="txt_alt1">
- 空[INDEX] [ALTITUDE]
+ 空[INDEX] [ALTITUDE]m
</text>
<line_editor name="edt_invname_alt1">
䞍明
@@ -66,7 +66,7 @@
</panel>
<panel name="pnl_alt2">
<text name="txt_alt2">
- 空[INDEX] [ALTITUDE]
+ 空[INDEX] [ALTITUDE]m
</text>
<line_editor name="edt_invname_alt2">
䞍明
@@ -75,7 +75,7 @@
</panel>
<panel name="pnl_alt3">
<text name="txt_alt3">
- 空[INDEX] [ALTITUDE]
+ 空[INDEX] [ALTITUDE]m
</text>
<line_editor name="edt_invname_alt3">
䞍明
diff --git a/indra/newview/skins/default/xui/ja/panel_region_estate.xml b/indra/newview/skins/default/xui/ja/panel_region_estate.xml
index df790376ec..429b55cb32 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_estate.xml
@@ -19,7 +19,7 @@
<radio_item label="アクセスタブに蚘茉された䜏人ずグルヌプのみ蚱可する" name="estate_restricted_access"/>
<radio_item label="誰でも蚪問可" name="estate_public_access"/>
</radio_group>
- <check_box label="歳以䞊である必芁がありたす" name="limit_age_verified" tool_tip="この䞍動産䞍動産にアクセスするには、18 才以䞊でなければなりたせん。詳现に぀いおは、[SUPPORT_SITE]をご芧ください。"/>
+ <check_box label="18歳以䞊である必芁がありたす" name="limit_age_verified" tool_tip="この䞍動産䞍動産にアクセスするには、18 才以䞊でなければなりたせん。詳现に぀いおは、[SUPPORT_SITE]をご芧ください。"/>
<check_box label="支払情報が登録されおいる必芁がありたす" name="limit_payment" tool_tip="支払情報が登録されおいないず、この䞍動産にアクセスするこずはできたせん。詳现に぀いおは、[SUPPORT_SITE]をご芧ください。"/>
<check_box label="区画所有者" name="parcel_access_override"/>
<check_box label="ボむスチャットを蚱可" name="voice_chat_check"/>
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 11e8d0d169..398f8d6718 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
@@ -13,16 +13,16 @@
地圢テクスチャ
</text>
<text name="height_text_lbl">
- 䜎
+ 1䜎
</text>
<text name="height_text_lbl2">
- 
+ 2
</text>
<text name="height_text_lbl3">
- 
+ 3
</text>
<text name="height_text_lbl4">
- 高
+ 4高
</text>
<text name="height_text_lbl5">
地圢の隆起範囲
@@ -31,7 +31,7 @@
数倀は䞊のテクスチャのブレンド範囲を瀺したす。
</text>
<text name="height_text_lbl11">
- 蚈枬単䜍はメヌトルで、「䜎」の倀は、番のテクスチャの高さの「最倧倀」です。「高」の倀は、番のテクスチャの高さの「最䜎倀」です。
+ 蚈枬単䜍はメヌトルで、「䜎」の倀は、1番のテクスチャの高さの「最倧倀」です。「高」の倀は、4番のテクスチャの高さの「最䜎倀」です。
</text>
<text name="height_text_lbl6">
北西
diff --git a/indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml
index c717b71194..68eb8b4f9d 100644
--- a/indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml
@@ -8,7 +8,7 @@
</text>
<scroll_list name="scripts_list">
<scroll_list.columns label="サむズ ㎅" name="size"/>
- <scroll_list.columns label="" name="urls"/>
+ <scroll_list.columns label="URL" name="urls"/>
<scroll_list.columns label="オブゞェクト名" name="name"/>
<scroll_list.columns label="堎所" name="location"/>
</scroll_list>
diff --git a/indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml
index 71dedb55a6..30c3fdc9b5 100644
--- a/indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml
@@ -10,7 +10,7 @@
</text>
<scroll_list name="scripts_list">
<scroll_list.columns label="サむズ ㎅" name="size"/>
- <scroll_list.columns label="" name="urls"/>
+ <scroll_list.columns label="URL" name="urls"/>
<scroll_list.columns label="オブゞェクト名" name="name"/>
<scroll_list.columns label="オブゞェクトの所有者" name="owner"/>
<scroll_list.columns label="区画" name="parcel"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml
index 9cb0b8f116..27a55aa653 100644
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml
@@ -10,7 +10,7 @@
送信䞭 
</string>
<text name="title">
- メヌル
+ Eメヌル
</text>
<tab_container name="postcard_tabs">
<panel label="メッセヌゞ" name="panel_postcard_message"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
index 9feae80624..2497b15548 100644
--- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
@@ -7,10 +7,10 @@
垯域幅
</panel.string>
<panel.string name="time">
- [ampm, datetime, slt] [hour12, datetime, slt][min, datetime, slt] [timezone,datetime, slt]
+ [ampm, datetime, slt] [hour12, datetime, slt]:[min, datetime, slt] [timezone,datetime, slt]
</panel.string>
<panel.string name="timeTooltip">
- [year, datetime, slt]幎[month, datetime, slt]月[day, datetime, slt]日[weekday, datetime, slt]
+ [year, datetime, slt]幎[month, datetime, slt][day, datetime, slt]日[weekday, datetime, slt]
</panel.string>
<panel.string name="buycurrencylabel">
L$ [AMT]
@@ -24,7 +24,7 @@
<button label="ショップ" name="goShop" tool_tip="Second Lifeのマヌケットプレむスを開きたす。" width="70"/>
</panel>
<text name="TimeText" tool_tip="珟圚時刻倪平掋">
- 午前 2400 PST
+ 午前 24:00 PST
</text>
<icon image_name="Cam_FreeCam_Off" name="presets_icon_camera" tool_tip="カメラ"/>
<icon image_name="Presets_Icon" name="presets_icon_graphic" tool_tip="グラフィックのプリセット"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_tools_texture.xml b/indra/newview/skins/default/xui/ja/panel_tools_texture.xml
index 49efc529e4..968635e55b 100644
--- a/indra/newview/skins/default/xui/ja/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/ja/panel_tools_texture.xml
@@ -17,7 +17,7 @@
</combo_box>
<radio_group name="radio_material_type">
<radio_item label="テクスチャ (拡散)" name="Texture (diffuse)" value="0"/>
- <radio_item label="凹凞 (暙準)" name="Bumpiness (normal)" value="1"/>
+ <radio_item label="凹凞 (法線)" name="Bumpiness (normal)" value="1"/>
<radio_item label="茝き (反射)" name="Shininess (specular)" value="2"/>
</radio_group>
<check_box initial_value="false" label="繰り返しをロックする" name="checkbox_sync_settings" tool_tip="すべおのマップの繰り返しを調敎する"/>
@@ -79,7 +79,7 @@
</text>
<color_swatch label="" name="shinycolorswatch" tool_tip="クリックしおカラヌピッカヌを開きたす"/>
<text name="media_info">
- 遞択したメディアのがもしあれば、ここに入りたす。
+ 遞択したメディアのURLがもしあれば、ここに入りたす。
</text>
<button label="遞択 " name="add_media" tool_tip="メディアを远加したす"/>
<button label="削陀" name="delete_media" tool_tip="このメディアテクスチャを削陀したす"/>
diff --git a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
index fe9998b4ce..520ef848a0 100644
--- a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
@@ -19,7 +19,7 @@
所有者ができるこず
</panel.string>
<panel.string name="acquiredDate">
- [year,datetime,local]幎[mth,datetime,local]月[day,datetime,local]日[wkday,datetime,local] [hour,datetime,local][min,datetime,local][second,datetime,local]
+ [year,datetime,local]幎[mth,datetime,local]月[day,datetime,local]日[wkday,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local]
</panel.string>
<panel.string name="origin_inventory">
むンベントリ
diff --git a/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml
index 8ff543bf92..1240a2e670 100644
--- a/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml
@@ -48,7 +48,7 @@
<text name="Name:">
名前
</text>
- <line_editor name="Object Name" tool_tip="䜿甚できる名前の文字数は最倧文字たでです。長いプリム名は短瞮されたす。名前に䜿甚できる文字はASCII-7 非拡匵に含たれる印字可胜な文字のみです瞊線「|」は䟋倖。"/>
+ <line_editor name="Object Name" tool_tip="䜿甚できる名前の文字数は最倧63文字たでです。長いプリム名は短瞮されたす。名前に䜿甚できる文字はASCII-7 非拡匵に含たれる印字可胜な文字のみです瞊線「|」は䟋倖。"/>
<text name="Description:">
説明
</text>
@@ -68,7 +68,7 @@
<text name="label click action">
クリックで
</text>
- <combo_box name="clickaction" tool_tip="マりスで回巊クリックするず、オブゞェクトに察しおアクションを起こせるようになりたす。各クリックアクションには、䜕ができるかを瀺す特別なカヌ゜ルがありたす。クリックアクションによっおは、動䜜芁件が必芁なものもありたす。䟋えば、「觊る」や「支払い」にはスクリプトが必芁になりたす。">
+ <combo_box name="clickaction" tool_tip="マりスで1回巊クリックするず、オブゞェクトに察しおアクションを起こせるようになりたす。各クリックアクションには、䜕ができるかを瀺す特別なカヌ゜ルがありたす。クリックアクションによっおは、動䜜芁件が必芁なものもありたす。䟋えば、「觊る」や「支払い」にはスクリプトが必芁になりたす。">
<combo_box.item label="觊るデフォルト" name="Touch/grab(default)"/>
<combo_box.item label="オブゞェクトに座る" name="Sitonobject"/>
<combo_box.item label="オブゞェクトを買う" name="Buyobject"/>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 033de9a684..99909d80d1 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -31,7 +31,7 @@
グラフィックを初期化できたせんでした。グラフィックドラむバを曎新しおください。
</string>
<string name="AboutHeader">
- [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3][ADDRESS_SIZE]bit
+ [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3][ADDRESS_SIZE]bit
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
</string>
<string name="BuildConfig">
@@ -46,9 +46,9 @@ SLURL&lt;nolink&gt;[SLURL]&lt;/nolink&gt;
[SERVER_RELEASE_NOTES_URL]
</string>
<string name="AboutSystem">
- [CPU]
+ CPU[CPU]
メモリ[MEMORY_MB]㎆
-のバヌゞョン[OS_VERSION]
+OSのバヌゞョン[OS_VERSION]
グラフィックカヌド補造元[GRAPHICS_CARD_VENDOR]
グラフィックカヌド:[GRAPHICS_CARD]
</string>
@@ -61,15 +61,15 @@ SLURL&lt;nolink&gt;[SLURL]&lt;/nolink&gt;
<string name="AboutSettings">
りィンドりサむズ:[WINDOW_WIDTH]x[WINDOW_HEIGHT]
フォントサむズ調敎[FONT_SIZE_ADJUSTMENT]pt
-スケヌリング[UI_SCALE]
-描画距離[DRAW_DISTANCE]
-垯域幅[NET_BANDWITH]kbit秒
-係数[LOD_FACTOR]
+UIスケヌリング[UI_SCALE]
+描画距離[DRAW_DISTANCE]m
+垯域幅[NET_BANDWITH]kbit/s
+LOD係数[LOD_FACTOR]
描画の質[RENDER_QUALITY]
テクスチャメモリ[TEXTURE_MEMORY]㎆
</string>
<string name="AboutOSXHiDPI">
- 高衚瀺モヌド[HIDPI]
+ 高DPI衚瀺モヌド[HIDPI]
</string>
<string name="AboutLibs">
J2Cデコヌダバヌゞョン[J2C_VERSION]
@@ -82,10 +82,10 @@ LibVLCバヌゞョン[LIBVLC_VERSION]
パケット損倱[PACKETS_LOST,number,0][PACKETS_IN,number,0][PACKETS_PCT,number,1]
</string>
<string name="AboutTime">
- [year, datetime, slt]幎[month, datetime, slt]月[day, datetime, slt]日 [hour, datetime, slt][min,datetime, slt][second,datetime,slt]
+ [year, datetime, slt]幎[month, datetime, slt]月[day, datetime, slt]日 [hour, datetime, slt]:[min,datetime, slt]:[second,datetime,slt]
</string>
<string name="ErrorFetchingServerReleaseNotesURL">
- サヌバヌのリリヌスノヌトの取埗時に゚ラヌが発生したした。
+ サヌバヌのリリヌスノヌトのURL取埗時に゚ラヌが発生したした。
</string>
<string name="BuildConfiguration">
ビルド構成
@@ -357,7 +357,7 @@ support@secondlife.com にお問い合わせください。
癜黒
</string>
<string name="Colors1970">
- 幎代のカラヌ
+ 1970幎代のカラヌ
</string>
<string name="Intense">
匷調
@@ -540,7 +540,7 @@ support@secondlife.com にお問い合わせください。
<string name="TooltipSLAPP">
クリックしお secondlife:// コマンドを出したす。
</string>
- <string name="CurrentURL" value="珟圚の[CurrentURL]"/>
+ <string name="CurrentURL" value="珟圚のURL[CurrentURL]"/>
<string name="TooltipEmail">
クリックしお電子メヌルを䜜成したす。
</string>
@@ -557,7 +557,7 @@ support@secondlife.com にお問い合わせください。
ミュヌト解陀
</string>
<string name="SLappAgentIM">
- 
+ IM
</string>
<string name="SLappAgentPay">
支払い
@@ -821,28 +821,28 @@ support@secondlife.com にお問い合わせください。
泣く
</string>
<string name="anim_dance1">
- ダンス
+ ダンス1
</string>
<string name="anim_dance2">
- ダンス
+ ダンス2
</string>
<string name="anim_dance3">
- ダンス
+ ダンス3
</string>
<string name="anim_dance4">
- ダンス
+ ダンス4
</string>
<string name="anim_dance5">
- ダンス
+ ダンス5
</string>
<string name="anim_dance6">
- ダンス
+ ダンス6
</string>
<string name="anim_dance7">
- ダンス
+ ダンス7
</string>
<string name="anim_dance8">
- ダンス
+ ダンス8
</string>
<string name="anim_express_disdain">
䟮蔑
@@ -1010,7 +1010,7 @@ support@secondlife.com にお問い合わせください。
オフラむン
</string>
<string name="worldmap_item_tooltip_format">
- [AREA]㎡ L$ [PRICE][SQMPRICE] L$㎡
+ [AREA]㎡ L$ [PRICE][SQMPRICE] L$㎡
</string>
<string name="worldmap_results_none_found">
䜕も芋぀かりたせんでした。
@@ -1034,7 +1034,7 @@ support@secondlife.com にお問い合わせください。
のささやき
</string>
<string name="shout">
- のシャりト
+ の叫び
</string>
<string name="ringing">
むンワヌルドボむスチャットに接続䞭 
@@ -1142,16 +1142,16 @@ support@secondlife.com にお問い合わせください。
䞍明
</string>
<string name="Estate / Full Region">
- 䞍動産フルリヌゞョン
+ 䞍動産 / フルリヌゞョン
</string>
<string name="Estate / Homestead">
- 䞍動産入怍地
+ 䞍動産 / ホヌムステッド
</string>
<string name="Mainland / Homestead">
- メむンランド入怍地
+ メむンランド / ホヌムステッド
</string>
<string name="Mainland / Full Region">
- メむンランドフルリヌゞョン
+ メむンランド / フルリヌゞョン
</string>
<string name="all_files">
党おのファむル
@@ -3225,7 +3225,7 @@ For AI Character: Get the closest navigable point to the point provided.
料金はサブスクリプションのレベルにより異なりたす。レベルが高いほど、料金が䞋がりたす。[https://accounts.secondlife.com/change_membership/?lang=ja-JP 詳现]
</string>
<string name="Open landmarks">
- オヌプン ランドマヌク
+ ランドマヌク䞀芧を開く
</string>
<string name="Unconstrained">
アンコンストレむンド制玄なし
@@ -3602,7 +3602,7 @@ For AI Character: Get the closest navigable point to the point provided.
あなたは、呚囲の誰からも芋えおいない可胜性がありたす。
</string>
<string name="hud_description_total">
- 利甚䞭の
+ 利甚䞭のHUD
</string>
<string name="hud_name_with_joint">
[OBJ_NAME][JNT_NAME]に装着䞭
@@ -3695,7 +3695,7 @@ For AI Character: Get the closest navigable point to the point provided.
幎霢未確認
</string>
<string name="Center 2">
- 䞭倮
+ 䞭倮2
</string>
<string name="Top Right">
右䞊
@@ -3874,19 +3874,19 @@ For AI Character: Get the closest navigable point to the point provided.
区画䞀芧[PARCELS]個
</string>
<string name="ScriptLimitsMemoryUsed">
- 䜿甚されたメモリ[MAX]㎅䞭[COUNT]㎅ [AVAILABLE]㎅利甚可
+ 䜿甚されたメモリ[MAX]㎅䞭[COUNT]㎅ [AVAILABLE]㎅利甚可
</string>
<string name="ScriptLimitsMemoryUsedSimple">
䜿甚されたメモリ[COUNT]㎅
</string>
<string name="ScriptLimitsParcelScriptURLs">
- 区画のスクリプト
+ 区画のスクリプトURL
</string>
<string name="ScriptLimitsURLsUsed">
- 䜿甚された[MAX]ä»¶äž­[COUNT]件 [AVAILABLE]件利甚可
+ 䜿甚されたURL[MAX]ä»¶äž­[COUNT]ä»¶ [AVAILABLE]件利甚可
</string>
<string name="ScriptLimitsURLsUsedSimple">
- 䜿甚された[COUNT]ä»¶
+ 䜿甚されたURL[COUNT]ä»¶
</string>
<string name="ScriptLimitsRequestError">
情報のリク゚スト䞭に゚ラヌが発生したした
@@ -3997,28 +3997,28 @@ For AI Character: Get the closest navigable point to the point provided.
右胞筋
</string>
<string name="ATTACH_HUD_CENTER_2">
- 䞭倮 2
+ HUD䞭倮 2
</string>
<string name="ATTACH_HUD_TOP_RIGHT">
- 右䞊
+ HUD右䞊
</string>
<string name="ATTACH_HUD_TOP_CENTER">
- 䞊・䞭倮
+ HUD䞊・䞭倮
</string>
<string name="ATTACH_HUD_TOP_LEFT">
- 巊䞊
+ HUD巊䞊
</string>
<string name="ATTACH_HUD_CENTER_1">
- 䞭倮 1
+ HUD䞭倮 1
</string>
<string name="ATTACH_HUD_BOTTOM_LEFT">
- 巊䞋
+ HUD巊䞋
</string>
<string name="ATTACH_HUD_BOTTOM">
- 䞋
+ HUD䞋
</string>
<string name="ATTACH_HUD_BOTTOM_RIGHT">
- 右䞋
+ HUD右䞋
</string>
<string name="ATTACH_NECK">
驖
@@ -4078,10 +4078,10 @@ For AI Character: Get the closest navigable point to the point provided.
[COUNT]件芋぀かりたした
</string>
<string name="PanelDirTimeStr">
- [ampm,datetime,utc] [hour12,datetime,utc][min,datetime,utc]
+ [ampm,datetime,utc] [hour12,datetime,utc]:[min,datetime,utc]
</string>
<string name="PanelDirEventsDateText">
- [mthnum,datetime,slt][day,datetime,slt]
+ [mthnum,datetime,slt]/[day,datetime,slt]
</string>
<string name="PanelContentsTooltip">
オブゞェクトの䞭身
@@ -4545,10 +4545,10 @@ www.secondlife.com から最新バヌゞョンをダりンロヌドしおくだã
ピクセル圢匏が蚭定できたせん。
</string>
<string name="MBGLContextErr">
- レンダヌコンテキストが䜜れたせん
+ GLレンダヌコンテキストが䜜れたせん
</string>
<string name="MBGLContextActErr">
- レンダヌコンテキストを有効化できたせん。
+ GLレンダヌコンテキストを有効化できたせん。
</string>
<string name="MBVideoDrvErr">
お䜿いのコンピュヌタヌのビデオカヌドのドラむバが正垞にむンストヌルされおいないか、叀いたたはサポヌト察象倖のため、[APP_NAME]を実行するこずができたせんでした。
@@ -6157,7 +6157,7 @@ www.secondlife.com から最新バヌゞョンをダりンロヌドしおくだã
むンベントリからここにアむテムをドラッグしたす。
</string>
<string name="no_session_message">
- セッションが存圚したせん
+ IMセッションが存圚したせん
</string>
<string name="only_user_message">
このセッションにいるナヌザヌはあなただけです。
@@ -6582,28 +6582,28 @@ www.secondlife.com から最新バヌゞョンをダりンロヌドしおくだã
䞀時退垭䞭
</string>
<string name="dance1">
- ダンス
+ ダンス1
</string>
<string name="dance2">
- ダンス
+ ダンス2
</string>
<string name="dance3">
- ダンス
+ ダンス3
</string>
<string name="dance4">
- ダンス
+ ダンス4
</string>
<string name="dance5">
- ダンス
+ ダンス5
</string>
<string name="dance6">
- ダンス
+ ダンス6
</string>
<string name="dance7">
- ダンス
+ ダンス7
</string>
<string name="dance8">
- ダンス
+ ダンス8
</string>
<string name="AvatarBirthDateFormat">
[year,datetime,slt]幎[mthnum,datetime,slt]月[day,datetime,slt]日
@@ -6623,7 +6623,7 @@ www.secondlife.com から最新バヌゞョンをダりンロヌドしおくだã
<string name="outfit_photo_verify_dimensions_error">
画像の寞法を確認できたせん。画像サむズがピッカヌに衚瀺されるたでお埅ちください。
</string>
- <string name="sentences_separator" value=" "/>
+ <string name="sentences_separator" value=" "/>
<string name="words_separator" value="、"/>
<string name="server_is_down">
倧倉申し蚳ございたせんが、予期しない問題が発生したした。サヌビスに関する既知の問題に぀いおは、 https://status.secondlifegrid.net/?lang=ja-JP をご芧ください。
@@ -6636,7 +6636,7 @@ www.secondlife.com から最新バヌゞョンをダりンロヌドしおくだã
日:月:火:æ°Ž:朚:金:土
</string>
<string name="dateTimeMonthNames">
- 月:月:月:月:月:月:月:月:月:月:月:月
+ 1月:2月:3月:4月:5月:6月:7月:8月:9月:10月:11月:12月
</string>
<string name="dateTimeMonthShortNames">
㋀:㋁:㋂:㋃:㋄:㋅:㋆:㋇:㋈:㋉:㋊:㋋
@@ -7108,7 +7108,7 @@ www.secondlife.com から最新バヌゞョンをダりンロヌドしおくだã
パヌティクルを非衚瀺
</string>
<string name="Command_360_Capture_Label">
- 床ショット
+ 360床スナップショット
</string>
<string name="Command_AboutLand_Label">
土地情報
@@ -7198,7 +7198,7 @@ www.secondlife.com から最新バヌゞョンをダりンロヌドしおくだã
ボむス蚭定
</string>
<string name="Command_360_Capture_Tooltip">
- 床の正距円筒図法のスナップショット画像を撮圱したす。
+ 360床の正距円筒図法のスナップショット画像を撮圱したす。
</string>
<string name="Command_AboutLand_Tooltip">
蚪問先に関する情報を衚瀺したす。
@@ -7483,7 +7483,7 @@ www.secondlife.com から最新バヌゞョンをダりンロヌドしおくだã
物理圢状に䞍正な確認デヌタがありたす。物理モデルを修正しおください。
</string>
<string name="Mav_Details_MAV_BLOCK_MISSING">
- デヌタがありたせん。高が存圚し、有効であるこずを確認しおください。蚭定されおいない堎合は、物理モデルを蚭定したす。
+ デヌタがありたせん。高LODが存圚し、有効であるこずを確認しおください。蚭定されおいない堎合は、物理モデルを蚭定したす。
</string>
<string name="Mav_Details_MAV_UNKNOWN_VERSION">
物理圢状のバヌゞョンが正しくありたせん。物理モデルに正しいバヌゞョンを蚭定しおください。
@@ -7494,7 +7494,7 @@ www.secondlife.com のりェブサむトに接続できるかご確認くださã
接続できおも、この゚ラヌが継続的に起こる堎合は、サポヌトセクションから問題を報告しおください。
</string>
<string name="ssl_peer_certificate">
- ログむンサヌバヌが経由で確認できたせんでした。
+ ログむンサヌバヌがSSL経由で確認できたせんでした。
この゚ラヌが継続的に起こる堎合は、Secondlife.com のサポヌトセクションから問題を報告しおください。
</string>
<string name="ssl_connect_error">
diff --git a/indra/newview/skins/default/xui/ja/teleport_strings.xml b/indra/newview/skins/default/xui/ja/teleport_strings.xml
index c1be98bef9..cdfdb1628b 100644
--- a/indra/newview/skins/default/xui/ja/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/ja/teleport_strings.xml
@@ -47,7 +47,7 @@
むンベントリシステムは珟圚利甚できたせん。
</message>
<message name="MustGetAgeRegion">
- このリヌゞョン地域に入るには、歳以䞊である必芁がありたす。
+ このリヌゞョン地域に入るには、18歳以䞊である必芁がありたす。
</message>
<message name="RegionTPSpecialUsageBlocked">
リヌゞョンに入るこずができたせん。
diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp
index d5bf189d82..60172b3960 100644
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -32,6 +32,7 @@
#include "lltrans.h"
#include "lluistring.h"
#include "../llviewertexture.h"
+#include "../llviewercontrol.h"
#include "../llworldmapmessage.h"
// Class to test
#include "../llworldmap.h"
@@ -71,6 +72,11 @@ void LLUIString::updateResult() const { }
void LLUIString::setArg(const std::string& , const std::string& ) { }
void LLUIString::assign(const std::string& ) { }
+LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) {}
+LLControlGroup::~LLControlGroup() {}
+bool LLControlGroup::getBOOL(std::string_view) { return true; }
+LLControlGroup gSavedSettings("test_settings");
+
// End Stubbing
// -------------------------------------------------------------------------------------------
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index d16f427530..0ce89df914 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -247,6 +247,16 @@ class ViewerManifest(LLManifest):
}
return "%(channel_vendor_base)s%(channel_variant_underscores)s_%(version_underscores)s_%(arch)s" % substitution_strings
+ def installer_base_name_mac(self):
+ global CHANNEL_VENDOR_BASE
+ # a standard map of strings for replacing in the templates
+ substitution_strings = {
+ 'channel_vendor_base' : '_'.join(CHANNEL_VENDOR_BASE.split()),
+ 'channel_variant_underscores':self.channel_variant_app_suffix(),
+ 'version_underscores' : '_'.join(self.args['version'])
+ }
+ return "%(channel_vendor_base)s%(channel_variant_underscores)s_%(version_underscores)s_universal" % substitution_strings
+
def app_name(self):
global CHANNEL_VENDOR_BASE
channel_type=self.channel_type()
@@ -1070,7 +1080,7 @@ class Darwin_x86_64_Manifest(ViewerManifest):
def package_finish(self):
- imagename = self.installer_base_name()
+ imagename = self.installer_base_name_mac()
self.set_github_output('imagename', imagename)
finalname = imagename + ".dmg"
self.package_file = finalname
diff --git a/scripts/code_tools/fix_whitespace.py b/scripts/code_tools/fix_whitespace.py
index 7a88265479..d5f7ce1cce 100644
--- a/scripts/code_tools/fix_whitespace.py
+++ b/scripts/code_tools/fix_whitespace.py
@@ -70,7 +70,7 @@ def process_directory(directory, extensions, tab_stop):
def main():
parser = argparse.ArgumentParser(description='Convert tabs to spaces in files, considering tab stops.')
- parser.add_argument('-e', '--extensions', type=str, default='c,cpp,h,hpp,inl,py,glsl,cmake', help='Comma-separated list of file extensions to process (default: "c,cpp,h,hpp,inl,py,glsl,cmake")')
+ parser.add_argument('-e', '--extensions', type=str, default='c,cpp,m,mm,h,hpp,inl,py,glsl,cmake', help='Comma-separated list of file extensions to process (default: "c,cpp,h,hpp,inl,py,glsl,cmake")')
parser.add_argument('-t', '--tabstop', type=int, default=4, help='Tab stop size (default: 4)')
parser.add_argument('-d', '--directory', type=str, required=True, help='Directory to process')